25
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[macOS Monterey] ClangからGCCへの切り替え

Last updated at Posted at 2022-02-21

競プロを始めようと思って

手持ちのMacbookに環境構築を進めていました。
C++のコンパイラ周りで困ったことがあったのでメモ。

環境

  • Macbook Pro (13-inch, M1, 2020)
  • macOS Monterey 12.2
  • gcc 11.2.0 (Homebrew GCC 11.2.0_3)
  • Apple clang version 12.0.5 (clang-1205.0.22.9)

tl;dr

  • ClangからGCCに切り替えた
  • #include<bits/stdc++.h>を含むcppファイルをコンパイルしたらerror: assert.h: No such file or directoryの怒られが発生
  • export SDKROOT="$(xcrun --sdk macosx --show-sdk-path) ← 結論

長くなったので結論までの流れをコンパクトにまとめました(えらい)
ちなみにですがClangでも普段なんら困ることはないみたいなので,面倒なのが嫌な人はここまでにしましょう。

GCCのインストールとClangからの切り替え

別にこだわりはなかったんですが,競プロで等でよく見かけるヘッダ(bits/stdc++.h)を提供しているのがGCCだったりしたのでMac標準(?)のClangではなくてGCCを利用することにしました。
インストールはbrew install gcc。(Intel MacとM1 MacではHomebrewを使ったパッケージのインストール先が異なるので注意)

次に,まだこの段階ではClangが呼び出されてしまうgccg++それぞれのコマンドでGCCが呼び出されるように切り替えます。
brewコマンドでインストールされたGCCは/opt/homebrew/Cellar/に入っているのですが,インストールが済んだ時点で自動的に/opt/homebrew/bin/からシンボリックリンクが張られているのでls -l .. | grep ..コマンドで確認。

Terminal
$ ls -l /opt/homebrew/bin | grep gcc
... gcc-11 -> ../Cellar/gcc/11.2.0_3/bin/gcc-11
$ ls -l /opt/homebrew/bin | grep g++
... g++-11 -> ../Cellar/gcc/11.2.0_3/bin/g++-11

上のgcc-11/g++-11がそうです(実際にはgcc/g++を含む他の結果も表示されます)。
(↑ 11という数字はインストールされた時点でのバージョンによるので適宜読み替えてください)
つまり,この時点で (opt/homebrew/binにパスが通っていれば) gcc-11g++-11のコマンドでGCCを呼び出せるわけです。

毎度バージョンを入力するのも面倒なので,ln -fsコマンドでバージョンを省略した名前のシンボリックリンクを張っておきます(-fsはシンボリックリンクを作成して,同名のリンクファイルが既にある場合に削除してねというお願いをするオプションです)。

Terminal
$ ln -fs /opt/homebrew/bin/gcc-11 /opt/homebrew/bin/gcc  
$ ln -fs /opt/homebrew/bin/g++-11 /opt/homebrew/bin/g++     

ここでwhichコマンドを使って各コマンドからどのファイルが呼び出されているか確認します。

Terminal
$ which gcc
/opt/homebrew/bin/gcc
$ which g++
/opt/homebrew/bin/g++

このように先ほど指定したシンボリックリンクのファイルが呼び出されていればOKです。
まだ/usr/bin/gcc/usr/bin/g++が表示されている場合,

  • /opt/homebrew/bin/よりも/usr/bin/の方がパスの優先度が高い
  • そもそもopt/homebrew/bin/にパスが通っていない

コマンド実行時OSのシェルは,パスが通っている(登録されている)ディレクトリを優先度の高い順に探します。
以下のコマンドで/opt/homebrew/bin/にパスを通します。
(~/.zshrcがない場合はtouch ~/.zshrcをしてから), echo "export PATH=/opt/homebrew/bin:$PATH" >> ~/.zshrc
これを実行して,source ~/.zshrcで設定を再度読み込めばOKです。

使ってみる

意気揚々と#include<bits/stdc++.h>したcppファイルをコンパイルしたら,以下の怒られが発生してしまいました。

Terminal
$ g++ main.cpp
In file included from /opt/homebrew/Cellar/gcc/11.2.0_3/include/c++/11/aarch64-apple-darwin21/bits/stdc++.h:33,
                 from a.cpp:2:
/opt/homebrew/Cellar/gcc/11.2.0_3/include/c++/11/cassert:44:10: fatal error: assert.h: No such file or directory
   44 | #include <assert.h>
      |          ^~~~~~~~~~
compilation terminated.

この問題,色々調べて勉強になったのですが,こちらの記事が詳しくて分かりやすかったので参考にさせていただきました。感謝。
Xcodeのアップデートに伴ってヘッダーファイル等の参照すべきフォルダが変わっているということのようです。

The Command Line Tools package installs the macOS system headers inside the macOS SDK.
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.

macOS SDKにシステムヘッダとか入ってるからそっちを参照するようにしてくれと。
元々は/usr/includeというフォルダがあったけど無くなってしまったらしいです。

で,これは環境変数SDKROOTを設定することで解決することができるようです。

Terminal
$ g++ main.cpp
In file included from /opt/homebrew/Cellar/gcc/11.2.0_3/include/c++/11/aarch64-apple-darwin21/bits/stdc++.h:33,
                 from a.cpp:2:
/opt/homebrew/Cellar/gcc/11.2.0_3/include/c++/11/cassert:44:10: fatal error: assert.h: No such file or directory
   44 | #include <assert.h>
      |          ^~~~~~~~~~
compilation terminated.
$ export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"
$ g++ main.cpp
$ ls
a.out main.cpp

SDKROOTの設定の後はヘッダファイルの参照エラーが解消し,無事コンパイルできました!
こちらの変更もecho "export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" >> ~/.zshrcしておきましょう。

感想

~~Clangで良かったんじゃねえか...~~いや非常に勉強になって楽しかったです。
(SDKROOTの環境変数設定したのちゃんと覚えておかないと後々困ることがありそうな気がする)

*Qiitaに類するサービスを含め記事の投稿が初めてなので間違いや分かりづらい点が多々あるかと思いますのでご指摘いただけるととても嬉しいです。

参考

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

25
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?