Help us understand the problem. What is going on with this article?

macOS Catalina(10.15) の Xcode11 だと /usr/include が無い

はじめに

実は、主に Mojave(10.14) で利用していた Xcode10 の頃から /usr/include は非推奨でした。
まず、Xcode10 を導入すると /usr/include が消えます。手動で復活させてもマイナー更新でいつの間にか消えたりしました。

Xcode10 リリースノート

Xcode10 から /usr/include が無い件は、そのリリースノートに説明があります。

 The command line tools will search the SDK for system headers by default.
 However, some software may fail to build correctly against the SDK and
require macOS headers to be installed in the base system under /usr/include.
 If you are the maintainer of such software, we encourage you to update
your project to work with the SDK or file a bug report for issues that are
preventing you from doing so. 

つまり、/usr/include でなく、SDK の中にあるヘッダを使えという事です。
ビルド出来ないソフトウェアは、バグレポートを出すなりメンテナなら自分で対応するなりして欲しいと。

ただ、Xcode10 の時点では /usr/include を復活させるパッケージを提供していました。

 As a workaround, an extra package is provided which will
install the headers to the base system.
 In a future release, this package will no longer be provided.

これはワークアラウンドであって、今後のリリース(=Xcode11以降)では提供しないパッケージだと明言しています。

SDK header path

% xcrun --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

この下に /usr/include が存在します。

% ls `xcrun --show-sdk-path`
Entitlements.plist  SDKSettings.json    System
Library         SDKSettings.plist   usr
% ls `xcrun --show-sdk-path`/usr
bin include lib libexec share

なお、実体は 〜/SDKs/MacOSX10.15.sdk/〜 で、〜/SDKs/MacOSX.sdk/ はそこへのシンボリックリンクです。xcrun が MacOSX.sdk を示してるので、何か特別な理由がなければ MacOSX10.15.sdk を直接参照しない方が良さそうな気がします。(あやふや

影響

Xcode コマンドラインツールのコンパイラである cc は当然この SDK の path を見ていますし、brew でインストールした gcc もこの path に対応しているようです。

% /usr/local/bin/gcc-9 -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/gcc-9
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.2.0_1/libexec/gcc/x86_64-apple-darwin19/9.2.0/lto-wrapper
Target: x86_64-apple-darwin19
Configured with: ../configure --build=x86_64-apple-darwin19 --prefix=/usr/local/Cellar/gcc/9.2.0_1 --libdir=/usr/local/Cellar/gcc/9.2.0_1/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 9.2.0_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
Thread model: posix
gcc version 9.2.0 (Homebrew GCC 9.2.0_1)

実際に困るケースとしては、ビルドシステムとしての autoconf や cmake のルール記述で /usr/include を決め打ちしている場合や、pkg-config 用の .pc ファイルで同様に決め打ちしている場合、正常にビルド出来なくなるでしょう。

実例 (ImageMagick)

現時点、brew でライブラリを揃えた環境に於いて、ImageMagick を configure, make しようとするとエラーが出て失敗します。

% make
<略>
  CC       MagickCore/libMagickCore_7_Q16HDRI_la-magick.lo
MagickCore/magick.c:100:12: fatal error: 'libxml/parser.h' file not found
#  include <libxml/parser.h>
           ^~~~~~~~~~~~~~~~~
1 error generated.
make[1]: *** [MagickCore/libMagickCore_7_Q16HDRI_la-magick.lo] Error 1
make: *** [all] Error 2

これは brew が示す SDK 側の libxml2 の情報が間違えているからだと思われます。

% find /usr/local -name "libxml*.pc"
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.8/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.9/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.10/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.11/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.13/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.12/libxml-2.0.pc
/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.15/libxml-2.0.pc
/usr/local/Cellar/libxml2/2.9.9_2/lib/pkgconfig/libxml-2.0.pc
% cat /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.15/libxml-2.0.pc
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
modules=1

Name: libXML
Version: 2.9.4
Description: libXML library version2.
Requires:
Libs: -L${libdir} -lxml2
Libs.private: -lz -lpthread -licucore -lm
Cflags: -I${includedir}/libxml2

解決策1

/usr/bin/xml2-config は正しいパスを返すので、以下のように対処できます。

% env CFLAGS="$(xml2-config --cflags)" \
      XML_CFLAGS="$(xml2-config --cflags)" \
      XML_LIBS="$(xml2-config --libs)" \
  ./configure
% make

数年前まで ImageMagick も configure 時に xml2-config を使っていたのですが、いつの間にか pkg-config 使うようになってますね。まぁ pkg-config は色々なパッケージを解決できるので、これに寄せるのは美しいですし、今回のは brew 側の事故みたいなものです。

解決作2

brew でインストールした libxml2 を使う場合はこうです。

% env PKG_CONFIG_PATH="/usr/local/opt/libxml2/lib/pkgconfig" \
  ./configure
% make

感謝

追記 (2019/10/17)

--sysroot オプション、SDKROOT 環境変数と、それらに関連する解説がありましたので紹介します。

% export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"

なお、--sdk macosx を省略すると表示するパス名は違いますが、シンボリックリンクで同じ場所になります。

% xcrun --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
% xcrun --sdk macosx --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
% ls -l /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
total 0
drwxr-xr-x  4 root  wheel  128 10  8 09:38 DriverKit19.0.sdk
drwxr-xr-x  8 root  wheel  256 10  8 09:39 MacOSX.sdk
lrwxr-xr-x  1 root  wheel   10  9 24 01:46 MacOSX10.15.sdk -> MacOSX.sdk

--sdk は文字通り、SDK の指定に使うようで、例えば driverkit だとこうなります。

% xcrun --sdk driverkit --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/DriverKit19.0.sdk
yoya
画像処理の事ばかり考えてます。ImageMagick ウォッチングが趣味です。
http://pwiki.awm.jp/~yoya/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away