2018年9月17日月曜日

Fedora28でGCC7.3をビルドする

Fedora28ではGCCのバージョンは8.1だが、CUDA-9.2はGCC8ではできない。
(CUDAはもともとFedora27までのサポートなので、Fedora28は対象外。)

https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#system-requirements

CUDAのヘッダーファイルの定義を変えてもよいのだが、CUDAがビルドできるGCC7をソースビルドして用意することにした。
今回は、GCC7をビルドして、CUDAのサンプルをビルド&実行するところまで
方針としては、
  • もともと入っているGCC8と共存する
  • CUDAをビルドするときのみ(CUDAホストコンパイラ)にGCC7を指定する
  • GCC8と7は切り替えることができる


ビルドするにあたって、以下を参考にさせていただいた(ありがとうございます)。


環境

  • Fedora 28 x86_64
  • gcc バージョン 8.1.1 20180712 (Red Hat 8.1.1-5) (GCC)

GCCのビルド

ビルドに必要なパッケージをインストール。

$ sudo dnf install texinfo texi2html flex

CUDA9.2がサポートしているGCC 7.3のソースコードのダウンロードと展開。

$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-7.3.0/gcc-7.3.0.tar.gz
$ tar xvf gcc-7.3.0.tar.gz
$ cd gcc-7.3.0

ビルド。
必要なコンパイラはC, C++のみを指定。
インストールパス(prefix)に適当なパス(斜体部分)を指定。
(ここではhomeディレクトリ配下)
x86_64のみでi386のターゲットはビルドしない。

$ ./contrib/download_prerequisites
$ mkdir build
$ cd build
$ ../configure --enable-bootstrap --enable-languages=c,c++ --prefix=/home/username/gcc/7.3 --enable-shared --enable-threads=posix --enable-checking=release --disable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-gnu-indirect-function --build=x86_64-redhat-linux
$make
$make install


specsファイルの作成

コンパイルしたGCC7でビルドした際に、適切な動的リンクライブラリ(libstdc++.so)がリンクされるようにSPECEファイルを修正する。
これは、CUDAホストコンパイラだけを指定する場合は問題ないと思うが、GCC7でビルドする場合もあるので行う。
specsファイルを出力。

$ /home/username/gcc/7.3/bin/gcc -dumpspecs > specs

出力したspecsファイルの以下を修正する。
変更前
*link_libgcc:
%D

変更後
*link_libgcc:
%{!static:%{!static-libgcc:-rpath /home/username/gcc/7.3/lib64/}} %D

修正したspecsファイルをコピー

$ cp specs /home/username/gcc/7.3/lib/gcc/x86_64-redhat-linux/7/


Environment Modulesの設定

GCC7, 8をEnvironment Modulesで切り替えられるようにする。
/etc/modulefiles 配下に、gcc7xのファイルを作成する。

#%Module 1.0
#
#  gcc-7.X module for use with 'environment-modules' package:
#

conflict        gcc8x
prepend-path    PATH                    /home/username/gcc/7.3/bin/

切り替えの確認

GCC7に切り替え

$ module add gcc7x
$ gcc -v
/home/username/gcc/7.3/lib/gcc/x86_64-redhat-linux/7/specs から spec を読み込んでいます
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/username/gcc/7.3/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper
ターゲット: x86_64-redhat-linux
configure 設定: ../configure --enable-bootstrap --enable-languages=c,c++ --prefix=/home/nobuo/gcc/7.3 --enable-shared --enable-threads=posix --enable-checking=release --disable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-gnu-indirect-function --build=x86_64-redhat-linux
スレッドモデル: posix
gcc バージョン 7.3.0 (GCC) 


もとに戻す

$ module unload gcc7x
$ gcc -v
組み込み spec を使用しています。
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
ターゲット: x86_64-redhat-linux
configure 設定: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
スレッドモデル: posix
gcc バージョン 8.1.1 20180712 (Red Hat 8.1.1-5) (GCC) 

CUDAサンプルのビルド&実行

CUDA9.2のサンプルをビルドする。
まずはサンプルをコピー。

$ sh /usr/local/cuda/bin/cuda-install-samples-9.2.sh ./

GCC7に切り替え

$ module add gcc7x

あとは、ビルドだけ。
ただし、サンプルの中の 3_Imaging/cudaDecodeGL だけは、ビルドできないので除外。
(findgllib.mk でOpenGLのライブラリの検索がFedora用がなく無理だった)

OpenCVでCUDAをビルドする場合

OpenCVでCUDAを有効としたい場合は、GCC7に切り替えず、CUDA_HOST_COMPILERにGCC7のg++のパスを指定すれば良い。