[1]前書き
この記事はMacでGCCを"正しく"環境構築しよう!の続編なので、先に読んでからこちらの記事を読むことをお勧めします。手順通りに進めていただければGCCを使えるはずです1。
この記事では、HomebrewでインストールしたGCCでコンパイルしようとすると、fatal error: '〇〇.h' file not foundとエラーが出る場合の対応策について紹介します。
また、GCC以外の場面でfatal error: '〇〇.h' file not foundのエラーが出た場合も紹介した方法を応用することで問題を解決することができるような解説を以下では心がけています。
[2]前提
まず、GCCが使える状態になっていることを以下のコマンドで確認します。バージョンの違いはありますが、一番下の行がHomebrew GCCになっていればHomebrewのGCCが使える状態になっています。異なる場合はMacでGCCを"正しく"環境構築しよう!を先に読んでください。
% g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/10.2.0/libexec/gcc/x86_64-apple-darwin20/10.2.0/lto-wrapper
Target: x86_64-apple-darwin20
Configured with: ../configure --build=x86_64-apple-darwin20 --prefix=/usr/local/Cellar/gcc/10.2.0 --libdir=/usr/local/Cellar/gcc/10.2.0/lib/gcc/10 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-10 --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 10.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk SED=/usr/bin/sed
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (Homebrew GCC 10.2.0)
[3]サーチパスの確認と〇〇.hの検索
file not foundへの対処を見れば基本的には解決するので、この章を読むのは必須ではありません。但し、解決しない場合に自力で解決するのにこの章は役立つと期待しています。
(1)原因の確認
fatal error: '〇〇.h' file not foundは〇〇.h(ヘッダファイル)が見つからないことが原因です。まずはヘッダファイルのインクルード元を見つけるためにサーチパスを確認しましょう。
サーチパスは適当なC++のファイル(hoge.cc)を用意して-vオプション付きでコンパイル(% g++ -v hoge.cc2)した時の出力の中にあります3。また、自分の出力結果の該当部分のみを参考に載せておきます4。
つまり、以下のサーチしているディレクトリに〇〇.hがない場合にfatal error: '〇〇.h' file not foundというエラーが発生します。
% g++ -v hoge.cc
# その他の出力
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/usr/local/include"
ignoring nonexistent directory "/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/../../../../../../x86_64-apple-darwin20/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/Library/Frameworks"
# include "..." search starts here:
# include <...> search starts here:
/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/../../../../../../include/c++/10.2.0
/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/../../../../../../include/c++/10.2.0/x86_64-apple-darwin20
/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/../../../../../../include/c++/10.2.0/backward
/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/include
/usr/local/Cellar/gcc/10.2.0/lib/gcc/10/gcc/x86_64-apple-darwin20/10.2.0/include-fixed
/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/System/Library/Frameworks
End of search list.
# その他の出力
ちなみに、Macに元々あるclang++のサーチパスは以下のようになりました。
% clang++ -v hoge.cc
# その他の出力
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
# include "..." search starts here:
# include <...> search starts here:
/usr/local/include
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1
/Library/Developer/CommandLineTools/usr/lib/clang/12.0.0/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
/Library/Developer/CommandLineTools/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
# その他の出力
(2)サーチパスの詳細
サーチパスはシステム側で決められています5。自分の環境を含む複数の環境で確かめた限りでは、HomebrewでインストールしたGCC(/usr/local/Cellar/gcc/10.2.0/)の配下とCommandLineToolsの一部としてインストールされるMacOSXのSDK6(/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/)の配下のヘッダファイルを含むディレクトリを指します7。
(3)〇〇.hの検索
サーチパスを把握し出力をメモしたらlocateコマンドを用いて〇〇.hを探します。
同様の検索用のコマンドのfindコマンドもありますが、ここでは高速なlocateコマンドの利用を推奨します。Macでのlocateコマンドの使い方は環境構築で最も役に立ったlocateコマンドを紹介するを参考にしてください。
例えば、fatal error: 'wchar.h' file not foundとなる場合、自分の環境でwchar.hを探すと以下のようになります。
% locate /wchar.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/wchar.h
/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/usr/include/wchar.h
/Library/Developer/CommandLineTools/usr/include/c++/v1/wchar.h
/usr/local/Cellar/gcc/10.2.0/include/c++/10.2.0/tr1/wchar.h
[4]file not foundへの対処
まず、MacでGCCを"正しく"環境構築しよう!の内容を完遂すれば、HomebrewでインストールしたGCCの配下のヘッダファイルは普通はインクルードできます。従って、MacOSのSDKの配下のヘッダファイルがインクルードできていないと考えられます。
具体的には以下の手順で実行を行い、その都度エラーが消えるかを確認してください。
(1)CommandLineTollsの確認
まず、CommandLineToolsに問題がないかを確認しましょう。具体的な手順は「MacでGCCを"正しく"環境構築しよう!」の[1]に書いてあります。
(2)SDKの確認
次は、インストールすべきSDKが異なる場合があるので確認しましょう。% g++ -vを実行し、出力の中の--with-sysrootオプションの指すディレクトリを確認してください。自分であれば/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdkとなっています。
実は、--with-sysrootオプションで指定されたMacOSのSDKの配下からヘッダファイルがインクルードされます8。従って、SDKのバージョンの合うCommandLineToolsをインストールしてください。SDKのバージョンの合うCommandLineToolsのインストール方法については「MacでGCCを"正しく"環境構築しよう!」の[1]の(2)を参考にしてください。
(3)-sysrootオプションでの指定
(2)まででうまくいかない場合や最新のSDKを使いたい場合は用いるSDKをコンパイル時のオプションで指定します。インストール済みのSDKを% ls /Library/Developer/CommandLineTools/SDKsで調べ、使いたいSDKを-sysrootオプションで指定すれば良いです9。
オプションとして-sysrootオプションのみを使うと、以下のようなコマンドになると思います。
% g++ -syroot=/Library/Developer/CommandLineTools/SDKs/〇〇.sdk hoge.cc
以上を正確に行ってもうまくいかない場合は他の問題が発生してるので、自分で対処方法を考えるか検索してください10。
[5]C++のサンプルファイル(hoge.cc)
何回か出てくるhoge.ccを載せておきます。〇〇.hをインクルードして終了するだけのソースファイルです。〇〇.hは適当に置き換えてください。
# include<〇〇.h>
int main(){
return 0;
}
-
この記事でかなり網羅してあると思うので、うまくいかない場合は一つ一つの手順を完遂できているかということに着目してデバッグしてください。 ↩
-
これ以降、
% コマンド名で実行するコマンドを示します。シェルによっては%が$ですが、適宜読み替えてください。 ↩ -
GCCのドキュメントのサーチパスに書いてあります。 ↩
-
ignoring nonexistent directoryは存在しないディレクトリにもサーチパスが通っていることを表します。 ↩ -
調査してもわからなかったので、設定ファイルの場所がわかる方は教えていただきたいです。 ↩
-
MaxOSXをターゲットプラットフォームとしたC++アプリケーションの開発に必要な一連のファイルが含まれています。詳しくは[SDK マネージャ]を参考にすると良いです。 ↩
-
バージョンなどが環境により少し異なる可能性があることに注意してください。また、GCCもSDKも複数ある場合は気をつけてください。 ↩
-
設定ファイルを書き換えて--with-sysrootのデフォルトを直接書き換えようと思ったのですが、わかりませんでした。teratailで質問しているので、有識者の方はこちらのコメント欄またはteratailで教えていただけるとありがたいです。 ↩
-
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdkというバージョン名のついていないSDKがある場合、% ls -l /Library/Developer/CommandLineTools/SDKs/MacOSX.sdkで確認してわかるようにシンボリックリンクになります。リンク先が正しければこちらを指定しても問題ありません。 ↩ -
コメントをいただけると反応できるかもしれません。 ↩