Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

MacでGCCを"正しく"環境構築しよう!

前書き

MacでのGCCの環境構築をどの記事よりも丁寧に解説した記事です。

同様の記事は沢山あるものの記述が曖昧な場合や間違っている場合があります。そこで、構築で使うコマンドを提示に留まらず理由や意味も丁寧に説明し、エラーが出ても自力で対処できることを意識して解説を書きました

また、この記事の続編のMacでのGCCのコンパイルエラーの対処法を詳細に解説するではインストール後のコンパイルエラーを解消するための方法を解説しているのでぜひ参考にしてください。

本題

まず、GCCの環境構築は以下の四つの段階に大別できます。デバッグの際にはどの段階でエラーが出ているかを把握するようにしましょう。

[0] 環境の確認
[1] CommandLineToolsのインストール
[2] Homebrewの導入
[3] GCCのインストール&GCCへの切り替え

[0]環境の確認

OSのバージョンは% sw_vers1により確認することができます。参考として自分の環境での出力を以下に載せます。

自分のバージョンと比べて極端に古いまたは新しいバージョンの場合、下記の環境構築で多少の違い2があるのでご注意ください。

% sw_vers
ProductName:    macOS
ProductVersion: 11.1
BuildVersion:   20C69

[1]CommandLineToolsのインストール

(0)インストールの前提

以降ではXcodeに付属していないCommandLineToolsを使うので、ディベロッパーツールとしてXcodeに付属するCommandLineToolsを使っている場合はXcodeに付属していないCommandLineToolsに切り替える必要があります。

まず、現在使っているディペロッパーディレクトリを% xcode-select -pで出力します。このとき/Library/Developer/CommandLineToolsが出力されれば問題ないですが、例えば/Applications/Xcode.app/Contents/Developerが出力されるような場合は% xcode-select -s /Library/Developer/CommandLineToolsとして使うCommandLineToolsのディペロッパーディレクトリへと切り替えてください。

(1)インストールの手順と確認

CommandLineToolsは% xcode-select --installでインストールできます。このコマンドを実行するといくつかポップアップが出てくるので指示通りに進めます。すると、CommandLineToolsは先程変更したディベロッパーディレクトリ(/Library/Developer/CommandLineTools)にインストールされます。

また、正しくCommandLineToolsをインストールできた場合は以下のコマンドで実行可能なCommandLineToolsのバージョンを表示できます。

% pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version

(2)インストール時の注意

先程のコマンドによりbeta版ではない最新バージョンのCommandLineToolsがインストールされます。しかし、% xcode-select --installを実行してもエラーが出る場合や別のバージョンを指定してインストールをしたい場合は以下で紹介する方法でインストールを行ってください。

インストールをすでにした場合は% sudo rm -r /Library/Developer/CommandLineToolsによりCommandLineToolsのアンインストールをまずは行ってください。

インストールには公式のMore Downloads for Apple Developersを利用します。このサイトには色々なバージョンのCommandLineToolsのdmgファイルがあるので、適当なディレクトリにdmgファイルダウンロードして解凍し指示通りにインストールを進めれば良いです。

また、OSやSDKのバージョンを確認したい場合は、Xcodeの英語版wikipediaの表を見てください。

(3)使用するコマンドの説明

上記のxcode-select及びpkgutilの二つのBSDコマンドの説明を付記します。また、BSDとはBerkeley Software Distributionの略語でMacOSはこのOSから派生しています。

xcode-select

  • xcrunxcodebuildなどが使うディベロッパーツールのあるディレクトリを操作できるBSDコマンドである。
  • これにより複数のXcodeのバージョンを同居させて開発することも可能になる。
  • 詳しくはman3で確認する。

pkgutil

  • MacOSXにおけるpkgファイルによるインストールを管理するBSDコマンドである。
  • 詳しくはman3で確認する。
  • ちなみに、CommandLineToolsはdmgファイル(ディスクイメージ)でダウンロードされ、解凍されると中のpkgファイルが展開されてインストールが始まる。

[2]Homebrewの導入

(1)導入の手順と確認

GCCをインストールするためにパッケージ管理システムのHomebrew4を導入します。パッケージ管理システムとしてはMacportsもありますが自分は使ったことがないので説明を割愛します。

また、HomebrewはHomebrewの公式サイトのコマンドを貼り付けてください。この公式サイトに書かれているリンクから飛ぶとHomebrewのドキュメントやパッケージの依存関係などを調べることができます。

インストール後に% brew doctorを実行してYour system is ready to brew.が出力されればHomebrewは問題なくインストールできています。

また、ここまででインストールしたものなどのバージョンは% brew --configにより確認することができます。参考までに自分の環境での出力を載せておきます。

% brew --config
HOMEBREW_VERSION: 2.6.2
ORIGIN: https://github.com/Homebrew/brew
HEAD: 1a52862e6d24cd3bf87bec557a8886a1a825ee3c
Last commit: 7 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: c06f553c5f07a31e06ebebf806286141e0af7e0b
Core tap last commit: 3 days ago
Core tap branch: master
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 4
Homebrew Ruby: 2.6.3 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: quad-core 64-bit skylake
Clang: 12.0 build 1200
Git: 2.24.3 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.64.1 => /usr/bin/curl
macOS: 11.0.1-x86_64
CLT: 12.2.0.0.1.1604076827
Xcode: N/A

(2)導入時の注意

brew doctorの出力でWarningが出ることがあります。以下の2パターンが代表的ですが、他のパターンの場合は対応策を検索してください

Unbrewed ~となる場合

Homebrew経由で入れていないパッケージが/usr/localにあります。この場合はそれぞれのパッケージを適切にアンインストールするとWarningは消えます。該当するファイルやディレクトリを消すだけでもWarningは消えますが、適切にアンインストールすることをお勧めします。

You have unlinked kegs ~となる場合

Homebrewでインストールしたパッケージへのリンクが切れています。そのパッケージが必要な場合はbrew link (パッケージ名)で再度リンクし、必要ない場合はbrew uninstall (パッケージ名)でアンインストールしてください。

[3]GCCのインストール&GCCへの切り替え

(0)インストールの前提

MacのコンパイラはClangなので、GCCはインストールする必要があります。また、ここではHomebrewを利用したインストール方法を紹介します。

そして、以下ではGCCのC++でのコンパイルができるように解説しているので、Cでのコンパイルをしたい場合は適宜読み替えてください。

(1)インストールの手順と確認

% brew install gccとするだけでインストールできます。インストール後に% brew list | grep gccとしてgccが出力されていれば問題なくインストールされています。また、Homebrewでインストールしたパッケージは/usr/local/Cellarにインストールされるので、% ls /usr/local/Cellar | grep gccでも同様の出力になるはずです。

さらに、インストール時にコンパイラへのシンボリックリンクが/usr/local/binから張られるので、% ls -l /usr/local/bin | grep g++により確認できます。自分の環境では以下のようになります5

% ls -l /usr/local/bin | grep g++
 g++-10 -> ../Cellar/gcc/10.2.0/bin/g++-10
 x86_64-apple-darwin20-g++-10 -> ../Cellar/gcc/10.2.0/bin/x86_64-apple-darwin20-g++-10

通常の環境ではg++-{num}からシンボリックリンクが張られているのが上記のコマンドでわかります6。また、ここまでが間違っていなければ% /usr/local/bin/g++-{num} hoge.ccとしてコンパイルを行うことができます。

(2)コマンドの簡略化

先程の% /usr/local/bin/g++-{num} hoge.ccを毎回打つのは不便なので、以下の二つを行って簡略化します。

①コマンドの検索パスを設定する

環境変数であるPATHを設定することで先程のコマンドは% g++-{num} hoge.ccと短縮することができます。% echo $PATHでPATHを出力することができ、:で区切られた中に/usr/local/binがあればg++-{num} hoge.ccとしてコンパイルすることができます。

通常の環境ではPATHは/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbinとなっていますが、/usr/local/binが含まれない場合と/usr/local/bin/usr/binよりも右側にある場合は以降の操作がうまくいかない可能性が高いです。これらの場合は、/usr/local/binの優先順位を最高にするために以下のコマンドを打てば良いです。

% export PATH=/usr/local/bin:$PATH

②バージョンを省略する

% g++ hoge.ccとしてバージョンの番号(num)を指定せずにコンパイルを行いたい場合、シンボリックリンクを張るかaliasに登録すれば良いです。複数のシェルなどを使い分けている場合も考慮すれば、以下のようにシンボリックリンクを張ると良いです。

% ln -s /usr/local/bin/g++-{num} /usr/local/bin/g++

これにより、シンボリックリンクが/usr/local/bin/g++から/usr/local/bin/g++-{num}へと張られるので、% ls -l /usr/local/bin | grep g++により確認できます。また、自分の環境では以下のようになります5

% ls -l /usr/local/bin | grep g++
 g++ -> /usr/local/bin/g++-10
 g++-10 -> ../Cellar/gcc/10.2.0/bin/g++-10
 x86_64-apple-darwin20-g++-10 -> ../Cellar/gcc/10.2.0/bin/x86_64-apple-darwin20-g++-10

(3)GCCでコンパイルできるかの確認

以上より、% g++ hoge.ccとしてコンパイルを行うことができるはずです。また、g++コマンドでGCCが使えるようになっているかは% g++ -vで確認できます。一番下の行がHomebrew 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) 

ちなみに、which (検索したいコマンド)とするとPATHを検索して呼ばれるコマンドへのパスが出力され、where (検索したいコマンド)とするとPATHで検索できるコマンドの任意のパスが出力されるので、以下のような出力が得られるはずです。

% which g++
/usr/local/bin/g++
% where g++
/usr/local/bin/g++
/usr/bin/g++

また、/usr/binにあるのはCommandLineToolsによりインストールされた(GCCの化けの皮を被った)Clangのコンパイラであることも% /usr/bin/g++ -vで確認できます。自分の環境では以下のようになります。

% /usr/bin/g++ -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

(4)コマンドや語句の説明

ls

  • パスで指定したディレクトリの内部のファイル及びディレクトリの一覧を出力するコマンド
  • -l引数を加えると長いフォーマットでの表示になり、シンボリックリンクが張られる場合は右側に矢印で表示される

|

  • パイプラインと呼ばれ、別のコマンドに出力を渡す働きをする。

grep

  • 指定したパターンの文字列のみを出力する。
  • % grep 〇〇とした場合は〇〇が含まれる文字列のみを出力する。

④PATH

  • コマンドを検索するための環境変数である。
  • :で区切られたパスでコマンドを検索する。
  • 区切られている中で左にあるパスの方が検索の優先順位が高い。

⑤シンボリックリンク

  • ファイルやディレクトリを参照するファイルのこと。
  • それぞれで違いはあるがソフトリンクであることを覚えておけば良い。

後書き

こちらの記事でLenovoPRO賞の特別賞をいただきました。いただいたThinkPadは大切に使わせていただきます。


  1. これ以降、% コマンド名で実行するコマンドを示します。シェルによっては%$ですが、適宜読み替えてください。 

  2. インストール先のディレクトリやインストールされるGCCのバージョンの違いなど 

  3. コマンドのオンラインマニュアルページを表示するコマンド 

  4. Homebrewの概要を把握するにはhomebrewとは何者か。仕組みについて調べてみたが役に立ちます。 

  5. 右端のリンクの部分のみを示しています。 

  6. 自分の環境では上記のようにnum=10ですが、numはそれぞれの環境で確かめて置き換えてください。 

DaikiSuyama
PythonとC++で競技プログラミングをしていました。最近は機械学習を勉強しています。 FXや株の自動売買、音楽の自動生成に興味があります。 [今]Djangoを勉強しています。
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