OSX の gcc を変更した話

## [0. 概要]
最近いろんなパソコン(OSX)にgcc-5を入れる機会が多かったので備忘録としてその方法を書いておきます。
gcc/g++の導入に関しては、macportsの方がhomebrewよりかなり簡単にできます(主観)。また、コンパイラの使い分けや切り替えに関しても、macportsはかなり便利です。
例えばOpenMPを使う場合、GCCのバージョン4.2から正式にサポートされるようになったらしいのですが、OSX標準のものだとできないので、gcc-4.9あたりを入れておけばいいと思います！

## [1. macportsのインストール]

> 以下のリンクを参考にしてください
> Xcodeを入れてMacPortのdmgをダウンロード、インストールするだけです！
>http://qiita.com/us10096698/items/54195e60b7afb60105ef

##[2. gcc/g++のバージョンを確認します]

> 私の環境では以前homebrewで入れたgcc-4.9であると表示されました。

```bash
$ gcc --v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc49/4.9.3/libexec/gcc/x86_64-apple-darwin15.4.0/4.9.3/lto-wrapper
Target: x86_64-apple-darwin15.4.0
Configured with: ../configure --build=x86_64-apple-darwin15.4.0 --prefix=/usr/local/Cellar/gcc49/4.9.3 --libdir=/usr/local/Cellar/gcc49/4.9.3/lib/gcc/4.9 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-4.9 --with-gmp=/usr/local/opt/gmp4 --with-mpfr=/usr/local/opt/mpfr2 --with-mpc=/usr/local/opt/libmpc08 --with-cloog=/usr/local/opt/cloog018 --with-isl=/usr/local/opt/isl011 --with-system-zlib --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --with-build-config=bootstrap-debug --disable-werror --with-pkgversion='Homebrew gcc49 4.9.3' --with-bugurl=https://github.com/Homebrew/homebrew-versions/issues --enable-plugin --disable-nls --enable-multilib
Thread model: posix
gcc version 4.9.3 (Homebrew gcc49 4.9.3) 
```

> OSXでデフォルトのコンパイラを使っている場合は以下のようになるかもしれません

```bash
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
```

##[3. gcc/g++のmacportsでインストールできるバージョンの選択肢を確認します]

```bash
$ port search gcc
apple-gcc40 @5494 (lang)
    Apple's version of gcc 4.0

apple-gcc42 @5666.3_15 (lang)
    Apple's version of gcc 4.2

---------------省略---------------

gcc5 @5.3.0_1 (lang)
    The GNU compiler collection

---------------省略---------------

gcc49 @4.9.3 (lang)
    The GNU compiler collection
```

##[4. 指定したバージョンをインストール]

> 今回はgcc-5をインストールしたいので以下のようにmacportsでインストール

```bash
$ sudo port install gcc5
```

##[5. 実行ファイル(gcc/g++)本体のpathを調べる]

```bash
$ port contents gcc5 | grep /bin/
  /opt/local/bin/aot-compile-mp-5
  /opt/local/bin/c++-mp-5
  /opt/local/bin/cpp-mp-5
  /opt/local/bin/g++-mp-5
  
  ---------------省略---------------

  /opt/local/bin/gcc-mp-5

  ---------------省略---------------

  /opt/local/bin/x86_64-apple-darwin15-gcj-mp-5
  /opt/local/bin/x86_64-apple-darwin15-gfortran-mp-5
```

今回使いたい実行ファイルはgcc-mp-5とg++-mp-5なので、pathを控えておきます。

##[6. gcc/g++とリンクをする]

> リンクをしておかないと、gcc hoge.c としてもXcodeのコンパイラが呼ばれるので、リンクを通します。その際にリンクを通す先(エイリアスの作成先)は以下のコマンドで得られた場所です。
私の環境ではこのような感じでした。

```bash
$ which g++
/usr/local/bin/g++
```

> 最後にここに、先ほど控えておいたgcc-5/g++-5のリンクを通します。私の場合以下のようになりました。

```bash
$ sudo ln -sf /opt/local/bin/gcc-mp-5  /usr/local/bin/gcc
$ sudo ln -sf /opt/local/bin/g++-mp-5  /usr/local/bin/g++
$ sudo ln -sf /opt/local/bin/g++-mp-5  /usr/local/bin/cc
$ sudo ln -sf /opt/local/bin/g++-mp-5  /usr/local/bin/c++
```

##[7. 確認]

> インストールしたgcc-5がリンクされているか確認します。
> リンクされていれば以下のようになるはずです。

```bash
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin15/5.3.0/lto-wrapper
Target: x86_64-apple-darwin15
Configured with: /opt/local/var/macports/build/_opt_mports_dports_lang_gcc5/gcc5/work/gcc-5.3.0/configure --prefix=/opt/local --build=x86_64-apple-darwin15 --enable-languages=c,c++,objc,obj-c++,lto,fortran,java --libdir=/opt/local/lib/gcc5 --includedir=/opt/local/include/gcc5 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-5 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-5 --with-gxx-include-dir=/opt/local/include/gcc5/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local --enable-stage1-checking --disable-multilib --enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts gcc5 5.3.0_1'
Thread model: posix
gcc version 5.3.0 (MacPorts gcc5 5.3.0_1) 
```

```bash
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin15/5.3.0/lto-wrapper
Target: x86_64-apple-darwin15
Configured with: /opt/local/var/macports/build/_opt_mports_dports_lang_gcc5/gcc5/work/gcc-5.3.0/configure --prefix=/opt/local --build=x86_64-apple-darwin15 --enable-languages=c,c++,objc,obj-c++,lto,fortran,java --libdir=/opt/local/lib/gcc5 --includedir=/opt/local/include/gcc5 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-5 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-5 --with-gxx-include-dir=/opt/local/include/gcc5/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local --enable-stage1-checking --disable-multilib --enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts gcc5 5.3.0_1'
Thread model: posix
gcc version 5.3.0 (MacPorts gcc5 5.3.0_1) 
```

> またプログラムの実行でも確認しましょう、以下のようなプログラムをコンパイル実行しようと思います。

```cpp14_sample.cpp
#include <iostream>

//C++14
auto f(){
  return 14;// 関数f()の定義で、戻り値の型は int となる。
}	

int main(){

  // C++11
  auto num = 11;
  auto name = "hoge";

  std::cout << num << name <<std::endl;

  //C++14
  int x = f();
  std::cout << x<<std::endl;
}
```

> これをオプションつけずにコンパイルしようとすると

```bash
$ g++ cpp14_sample.cpp 
cpp14_sample.cpp:4:8: error: ISO C++ forbids declaration of 'f' with no type [-fpermissive]
 auto f(){
        ^
cpp14_sample.cpp:4:8: error: top-level declaration of 'f' specifies 'auto'
cpp14_sample.cpp:4:8: error: storage class 'auto' invalid for function 'f'
cpp14_sample.cpp: In function 'int main()':
cpp14_sample.cpp:11:8: error: 'num' does not name a type
   auto num = 11;
        ^
cpp14_sample.cpp:12:8: error: 'name' does not name a type
   auto name = "hoge";
        ^
cpp14_sample.cpp:14:16: error: 'num' was not declared in this scope
   std::cout << num << name <<std::endl;
                ^
cpp14_sample.cpp:14:23: error: 'name' was not declared in this scope
   std::cout << num << name <<std::endl;
                       ^
```

> となりますが、std=c++14オプションをつけると、正常に実行できます。

```bash
$ g++ -std=c++14 cpp14_sample.cpp 
```

> 実行すると期待通り、C++14の機能を使えているのがわかります。

```bash
$ ./a.out
11hoge
14
```

##[8. 参考]

>今回 gccという名前で直接リンクしましたが、gcc-5みたいな名前のリンクをつけて名前で使い分けることも可能です。
>また直接リンクせずとも、macportsの機能を使って

```bash
$ port select --list gcc
Available versions for gcc:
	apple-gcc42
	mp-gcc48
	mp-gcc5
	none (active)
```

> を実行し、その中から使用するgccを選択する方法もあります(こちらの方が切り替えが楽です)
> 選択は以下のように行います。

```bash
$ sudo port select --set gcc mp-gcc48
Selecting 'mp-gcc48' for 'gcc' succeeded. 'mp-gcc48' is now active.
```

> 但し以下の変更の反映が必要です

```bash
$ source ~/.bashrc 
```

>これでgcc -vを行うと以下のようになるはずです

```bash
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin15/4.8.5/lto-wrapper
Target: x86_64-apple-darwin15
Configured with: /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_gcc48/gcc48/work/gcc-4.8.5/configure --prefix=/opt/local --build=x86_64-apple-darwin15 --enable-languages=c,c++,objc,obj-c++,lto,fortran,java --libdir=/opt/local/lib/gcc48 --includedir=/opt/local/include/gcc48 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.8 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.8 --with-gxx-include-dir=/opt/local/include/gcc48/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local --disable-isl-version-check --with-cloog=/opt/local --disable-cloog-version-check --enable-stage1-checking --disable-multilib --enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts gcc48 4.8.5_0' --with-build-config=bootstrap-debug
Thread model: posix
gcc version 4.8.5 (MacPorts gcc48 4.8.5_0) 
```


以上となります。