やりたいこと
- M1 Macbook Proに元々入っているg++で時効されるapple clangではlamda式などのc++11機能が使えなかった、homebrew経由でgccを入れ直したい
結論
- 前提として、以下のオプションをつければ g++ でもc++11の機能が使用できた
$ g++ -std=c++11 main.cpp
- [未検証]gccをbrewで入れた時に実行できないのは、/usr/includeが消えているところが怪しい?
- Xcodeから設定をいじれば/usr/includeは復活できるとのことだが、生環境に公式非推奨っぽい変更をすることに抵抗があったのでやらない。
- 結局上記の根本解決で対策したが、一応知識として供養
やったこと・試したこと
参考にさせていただきました記事の著者の皆様、誠にありがとうございます。
= ひとまずgccを入れる
$ brew install gcc
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ brew info gcc
gcc: stable 11.2.0 (bottled), HEAD
GNU compiler collection
https://gcc.gnu.org/
/opt/homebrew/Cellar/gcc/11.2.0_1 (1,412 files, 339.6MB) *
Poured from bottle on 2022-02-21 at 00:16:05
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb
License: GPL-3.0-or-later with GCC-exception-3.1
==> Dependencies
Required: gmp ✔, isl ✔, libmpc ✔, mpfr ✔, zstd ✔
==> Options
--HEAD
Install HEAD version
==> Analytics
install: 104,284 (30 days), 356,750 (90 days), 1,369,195 (365 days)
install-on-request: 44,813 (30 days), 160,114 (90 days), 621,601 (365 days)
build-error: 318 (30 days)
- ここで、gccがいくつか種類があることがわかる
$ gcc
gcc gcc-11 gcc-ar-11 gcc-nm-11 gcc-ranlib-11
$ for i in gcc gcc-11 gcc-ar-11 gcc-nm-11 gcc-ranlib-11 ; do which $i; done
/usr/bin/gcc
/opt/homebrew/bin/gcc-11
/opt/homebrew/bin/gcc-ar-11
/opt/homebrew/bin/gcc-nm-11
/opt/homebrew/bin/gcc-ranlib-11
- gccはbinに入っているapple clangバージョンを指定しているが、homebrewで入ったバージョンは、gcc-11で呼び出せることがわかる。
一回これで実行を通してみる
# include <iostream>
int main()
{
std::cout << "Hello" << std::endl;
}
$ gcc-11 main.cpp
Undefined symbols for architecture arm64:
"__ZNSolsEPFRSoS_E", referenced from:
_main in ccXYUJIE.o
"__ZNSt8ios_base4InitC1Ev", referenced from:
__Z41__static_initialization_and_destruction_0ii in ccXYUJIE.o
"__ZNSt8ios_base4InitD1Ev", referenced from:
__Z41__static_initialization_and_destruction_0ii in ccXYUJIE.o
"__ZSt4cout", referenced from:
_main in ccXYUJIE.o
"__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_", referenced from:
_main in ccXYUJIE.o
"__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc", referenced from:
_main in ccXYUJIE.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
-
ここで、homebrewにmanlibとかar, nmのバージョンが入っているのが気になる。
-
以下の記事のように、 manlib, arがmacのビルド環境を邪魔すると書いてあることもあるしエラー分も近いので、ここが怪しい気がする。
https://qiita.com/nagomiso/items/dc6021beb72d09f2128f -
上記記事では、ar manlib を/usr/bin/以下から読み出すことにするとカイエkつすると書いてあるが、手元環境では以下のようにすでにar manlibは/usr/bin以下から呼び出されている。
$ which ar
/usr/bin/ar
$ which ranlib
/usr/bin/ranlib
- ここをみると、/usr/includeが消えていることが原因とのこと?
/usr/includeとは?
https://life-is-command.com/man-usr-include/
C++の基本的なライブラリのヘッダーがはいっている(とされている)場所らしい
ここと
https://developer.apple.com/documentation/xcode-release-notes/xcode-10-release-notes#3035624
ここによれば、 /usr/include
はXcode-10から使わないことになったらしく、また基本的には上記の変更に合わせることが推奨されている。
上記の方法で治るかは試したないのでわからないが、あまり環境を弄りたくないため、そもそもapple clangでc++11ができないという前提が崩せないか調査
- 結果、普通apple clangつかったままコメントを入れればg++機能使えるっぽい。 なんの時間だったのだ。。。