作曲・指導・C言語・Linux

金沢音楽制作

金沢音楽制作では、楽曲・楽譜の制作と、作曲や写譜などレッスンを行っています。

macOSでgccを使う

macOSでGNUのgccを実行する方法を記します。

macOSの初期状態で、gccg++を使うと、本来のgccではなくclangというコンパイラが実行されます。しかし、それでは困る場合があると思います。

ターミナルで、次のように実行していけば、本来のgccが実行できますが、この書き方は意地が悪いので、よく分からない場合は読み飛ばしてください。この記事の最後に解説を書きました(「冒頭のコマンドの解説」)。

追記(2021-05-10):gcc-11が配布されました。バージョンの指定が面倒な場合、次のようにブレース展開を使ってもいいと思います。

$ brew install gcc
$ which gcc-{1..100}
/usr/local/bin/gcc-10
$ echo alias gcc="'"$(!!)"'" >> .bashrc
$ ^gcc='gcc^g++='g++^
$ . !$
$ gcc --version
gcc-10 (Homebrew GCC 10.2.0) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

環境:macOS 10.14、bash 5.0.18

gccをインストールする

macOSに、gccをインストールしましょう。つまり、macOSには、本来の(GNU Compiler Collectionとしての)gccは入っていません。ここではbrewを使ってインストールしますが、macPortsでも考え方は同じです。

$ brew install gcc
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 6 formulae.

==> Downloading https://homebrew.bintray.com/bottles/gcc-10.2.0.mojave.bottle.ta
Already downloaded: /Users/hase/Library/Caches/Homebrew/downloads/9848634721d3936c7501b4539c138aa1e1f3fb5884f9bf8ab4aa39660f735a66--gcc-10.2.0.mojave.bottle.tar.gz
==> Pouring gcc-10.2.0.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/gcc/10.2.0: 1,465 files, 343MB

brewでアプリケーションをインストールすると、/usr/local/bin/にシンボリックリンクが置かれることでパスが通ります。

さて、実行結果の最終行を見てください。実体のインストール先(/usr/local/Cellar/gcc/10.2.0)が分かるので確認してみます。

$ ls -F /usr/local/Cellar/gcc/10.2.0/
COPYING    INSTALL_RECEIPT.json  README  include/  libexec/
ChangeLog  NEWS                  bin/    lib/      share/

lsに付けられた-Fオプションは、ファイル名の末にファイルタイプを表示します。/がディレクトリ、*が実行ファイル、@がシンボリックリンクです。

この中のbin(Binary code)ディレクトリに実行ファイルが格納されているので、またlsで確認してみます。このうち、gcc-10g++-10がよく使われるものだと思われます。というか、他のファイルがなんなのかよく分かっていないです。

$ ls -F /usr/local/Cellar/gcc/10.2.0/bin
c++-10*         gfortran-10*
cpp-10*         lto-dump-10*
g++-10*         x86_64-apple-darwin18-c++-10*
gcc-10*         x86_64-apple-darwin18-g++-10*
gcc-ar-10*      x86_64-apple-darwin18-gcc-10*
gcc-nm-10*      x86_64-apple-darwin18-gcc-10.2.0*
gcc-ranlib-10*  x86_64-apple-darwin18-gcc-ar-10*
gcov-10*        x86_64-apple-darwin18-gcc-nm-10*
gcov-dump-10*   x86_64-apple-darwin18-gcc-ranlib-10*
gcov-tool-10*   x86_64-apple-darwin18-gfortran-10*
gfortran@

シンボリックリンクも確認みましょう。このパスは、後述するasliaでも利用します(必須ではありませんが)。

$ ls -F /usr/local/bin/g*10
/usr/local/bin/g++-10@         /usr/local/bin/gcov-10@
/usr/local/bin/gcc-10@         /usr/local/bin/gcov-dump-10@
/usr/local/bin/gcc-ar-10@      /usr/local/bin/gcov-tool-10@
/usr/local/bin/gcc-nm-10@      /usr/local/bin/gfortran-10@
/usr/local/bin/gcc-ranlib-10@

さて、gccをインストールしたので、早速実行してみましょう。あれ、clangが実行されてしいました。なぜでしょうか。

$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

さっき確認したファイル名を思い出してください。インストールした実行ファイル名は、gccではなくgcc-10です。ということは、gcc-10と入力すれば、本来のgccが実行されます。しかし、これではちょっと使いにくいので、gccで実行できるようエイリアスを設定しましょう。

$ gcc-10 --version
gcc-10 (Homebrew GCC 10.2.0) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

aliasを設定する

.bashrcgccのエイリアスを設定します。前項で確認したシンボリックリンクのパスを記述しますが、実体のパスやコマンドでも問題ないので、好きに書いてください。

$ vi ~/.bashrc
alias gcc='/usr/local/bin/gcc-10'
alias g++='/usr/local/bin/g++-10'

# シンプルにこう
#alias gcc='gcc-10'
#alias g++='g++-10'

記述後、~/.bashrcを読み込んでエイリアスを有効にします。

$ . .bashrc

これで、本来のgccが使えるようになったはずです。

$ gcc --version
gcc-10 (Homebrew GCC 10.2.0) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gccのバージョンが変わった場合は、エイリアスも変更してください(数字を変えるだけでいいと思います)。

BSDはClangが標準なのか

Wikipediaの「Clang」を読むと、「FreeBSDにおいて標準のコンパイラとして採用されている。」と記されていました(アクセス日:2020-10-13)。当サイトのサーバーは、FreeBSD 11.2を使っているので、実際にgccg++ccc++の四つのコマンドのバージョンを確認してみました。結果は、gccg++はGNU、ccc++Clangでした。

$ gcc --version
gcc (FreeBSD Ports Collection) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (FreeBSD Ports Collection) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cc --version
FreeBSD clang version 6.0.0 (tags/RELEASE_600/final 326565) (based on LLVM 6.0.0)
Target: x86_64-unknown-freebsd11.2
Thread model: posix
InstalledDir: /usr/bin
$ c++ --versionFreeBSD clang version 6.0.0 (tags/RELEASE_600/final 326565) (based on LLVM 6.0.0)
Target: x86_64-unknown-freebsd11.2
Thread model: posix
InstalledDir: /usr/bin

シンボリックリンクを作る?

ネットではパスが通っているディレクトリにシンボリックリンクを作る、という記事が多い気がします。次のコードは、ネットで見かけたもので、秘伝のタレの究極形ともいえる複雑さがあります。

$ sudo ln -sf $(ls -d /usr/local/bin/* | grep "/g++-" | sort -r | head -n1) /usr/local/bin/g++

書き直すならこうかな、と思います。

$ ln -s $(which g++-10) /usr/local/bin/g++

何をやっているのかというと、g++というシンボリックリンクを、/usr/local/bin/に作ることで、g++の本来のパス(/usr/bin/g++)より後にパスが通る/usr/local/bin/g++が優先されて実行されています。しかし、これではバージョンが変わった時に修正が大変なので、エイリアスを使った方がいいです。

$ pwd
/usr/local/bin
$ ln -s g++-10 g++
$ ls -l g++*
lrwxr-xr-x 1 hase admin  8 Oct 13 08:04 g++ -> ./g++-10
lrwxr-xr-x 1 hase admin 31 Oct 12 20:51 g++-10 -> ../Cellar/gcc/10.2.0/bin/g++-10
$ readlink g++
./g++-10
$ readlink -f g++
/usr/local/Cellar/gcc/10.2.0/bin/g++-10

冒頭のコマンドの解説

冒頭で提示したコマンドを解説します。

$ brew install gcc

brewgccをインストールします。

$ which gcc-{1..100}
/usr/local/bin/gcc-10

whichコマンドでgccの場所を表示させます。このとき、gccのバージョンを確実にひろうために、{1..100}と、ブレース展開で総当りしました。

$ echo alias gcc="'"$(!!)"'" >> .bashrc

この結果をエイリアスにしたいので、echoでエイリアスを書いて.bashrcに追記します。このときの$(!!)は、コマンド置換($())で直前のコマンド(ヒストリ置換(!!))を実行したものです。展開すると、$ echo alias gcc="'"$(which gcc-{1..100})"'" >> .bashrcになります。

$ ^gcc='gcc^g++='g++^

g++にも同じ処理をしますが、また同じ手順を踏むのは面倒です。そこで、直前のコマンドを文字列置換して実行しましょう。置換対象の文字列を^(ハット)で囲み、続けて置換したい文字列を記述して、^で閉じます。そして、リターンを押すと文字列が置換されて実行されます。展開すると、$ echo alias g++="'"$(which g++-{1..100})"'" >> .bashrcです。

$ . !$

最後に.bashrcを読み込んでエイリアスを使えるようにします。souceコマンドである.の引数には、やはりヒストリ置換の!$が指定されています。!$は、直前のコマンドの最後の引数、つまり.bashrcに置換されます。

更新情報

  • 公開日:2020-10-13
  • 更新日:2021-05-10
  • 更新日:2022-04-28