web-dev-qa-db-ja.com

CMakeを使ったGCCとClang / LLVMの切り替え

私はCMakeを使ってビルドされたプロジェクトをたくさん持っていて、それらをコンパイルするためにGCCとClang/LLVMのどちらを使うかを簡単に切り替えられるようにしたいです。 Clangを使うには次のように設定する必要があると私は信じています(間違えたら訂正してください)。

    SET (CMAKE_C_COMPILER             "/usr/bin/clang")
    SET (CMAKE_C_FLAGS                "-Wall -std=c99")
    SET (CMAKE_C_FLAGS_DEBUG          "-g")
    SET (CMAKE_C_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
    SET (CMAKE_C_FLAGS_RELEASE        "-O4 -DNDEBUG")
    SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")

    SET (CMAKE_CXX_COMPILER             "/usr/bin/clang++")
    SET (CMAKE_CXX_FLAGS                "-Wall")
    SET (CMAKE_CXX_FLAGS_DEBUG          "-g")
    SET (CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
    SET (CMAKE_CXX_FLAGS_RELEASE        "-O4 -DNDEBUG")
    SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")

    SET (CMAKE_AR      "/usr/bin/llvm-ar")
    SET (CMAKE_LINKER  "/usr/bin/llvm-ld")
    SET (CMAKE_NM      "/usr/bin/llvm-nm")
    SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
    SET (CMAKE_RANLIB  "/usr/bin/llvm-ranlib")

これらとデフォルトのGCC変数を切り替えるための簡単な方法はありますか?できればプロジェクト固有のものではなくシステム全体の変更として(つまり、プロジェクトのCMakeLists.txtに追加するだけではありません)

また、gccの代わりにclangを使ってコンパイルするとき、システムデフォルトではなくllvm-*プログラムを使う必要がありますか?違いは何ですか?

241
Rezzie

CMakeは、使用するCおよびC++コンパイラを検出すると、環境変数CCおよびCXXを尊重します。

$ export CC=/usr/bin/clang
$ export CXX=/usr/bin/clang++
$ cmake ..
-- The C compiler identification is Clang
-- The CXX compiler identification is Clang

コンパイラ固有のフラグはシステム全体のCMakeファイルに入れて CMAKE_USER_MAKE_RULES_OVERRIDE 変数を指すことで上書きできます。以下の内容でファイル~/ClangOverrides.txtを作成します。

SET (CMAKE_C_FLAGS_INIT                "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG_INIT          "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE_INIT        "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")

SET (CMAKE_CXX_FLAGS_INIT                "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG_INIT          "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT        "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")

接尾辞_INITはCMakeに与えられた値で対応する*_FLAGS変数を初期化させます。その後、次の方法でcmakeを起動します。

$ cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=~/ClangOverrides.txt ..

最後にLLVM binutilsの使用を強制するために、内部変数_CMAKE_TOOLCHAIN_PREFIXを設定します。この変数はCMakeFindBinUtilsモジュールによって尊重されます。

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

これらすべてをまとめると、環境変数CCおよびCXXを設定してから、前述の変数オーバーライドを指定してcmakeを呼び出すシェルラッパーを作成できます。

308
sakra

Ubuntuでのシステム全体のC++変更

Sudo apt-get install clang
Sudo update-alternatives --config c++

このようなものを表示します。

  Selection    Path              Priority   Status
------------------------------------------------------------
* 0            /usr/bin/g++       20        auto mode
  1            /usr/bin/clang++   10        manual mode
  2            /usr/bin/g++       20        manual mode

それからclang ++を選択してください。

115
Coder

あなたはオプションのコマンドを使用することができます:

option(USE_CLANG "build application with clang" OFF) # OFF is the default

そしてclang-compilerの設定をif()で囲みます。

if(USE_CLANG)
    SET (...)
    ....
endif(USE_CLANG)

このようにして、gui-configurationツールではcmakeオプションとして表示されます。

システム全体に適用するには、もちろん環境変数をデフォルト値として使用するか、Ferruccioの答えをそのまま使用することができます。

21
Tobias Schlegel

Ubuntuでのシステム全体のCの変更:

Sudo update-alternatives --config cc

Ubuntuでのシステム全体のC++変更

Sudo update-alternatives --config c++

上記のそれぞれについて、選択番号(1)を押してからEnterを押してClangを選択します。

  Selection    Path            Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc     20        auto mode
  1            /usr/bin/clang   10        manual mode
  2            /usr/bin/gcc     20        manual mode
Press enter to keep the current choice[*], or type selection number:
16

あなたは間違いなくさまざまな異なるllvm-arなどのプログラムを使用する必要はありません。

SET (CMAKE_AR      "/usr/bin/llvm-ar")
SET (CMAKE_LINKER  "/usr/bin/llvm-ld")
SET (CMAKE_NM      "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB  "/usr/bin/llvm-ranlib")

これらはllvmの内部フォーマットで動作するように作られているので、アプリケーションの構築には役に立ちません。

注意として、-O4はあなたが望まないかもしれないあなたのプログラムでLTOを呼び出すでしょう(それはコンパイル時間を非常に増加させるでしょう)そしてclangはc99モードにデフォルトであるのでフラグも必ずしも必要ではありません。

9
echristo

この目的のためにcmakeのツールチェーンファイルメカニズムを使うことができます。 ここ 。対応する定義を含む各コンパイラ用のツールチェーンファイルを作成します。設定時に、あなたは実行します。

 cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/clang-toolchain.cmake ..

また、ツールチェーンファイルからのproject()呼び出し中に、すべてのコンパイラ情報が設定されます。ドキュメンテーションではクロスコンパイルの文脈でのみ言及されていますが、同じシステム上の異なるコンパイラに対しても同様に機能します。

7
j_fu

cmakeの助けによると:

-C <initial-cache>
     Pre-load a script to populate the cache.

     When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project.  This option may be used to specify a  file  from
     which to load cache entries before the first pass through the project's cmake listfiles.  The loaded entries take priority over the project's default values.  The given file should be a CMake
     script containing SET commands that use the CACHE option, not a cache-format file.

gcc_compiler.txtclang_compiler.txtのようなファイルを作成して、CMakeの構文にすべての相対的な設定を含めることができます。

Clangの例(clang_compiler.txt):

 set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)

それからそれを実行します

GCC:

cmake -C gcc_compiler.txt XXXXXXXX

クラン:

cmake -C clang_compiler.txt XXXXXXXX
4
Enze Chi

環境変数にアクセスするには、$ENV{environment-variable}に構文CMakeLists.txtを使用できます。一連の環境変数を適切に初期化し、それらの変数への参照をCMakeLists.txtファイルに含めるスクリプトを作成できます。

3
Ferruccio

cmakeによって選択されたデフォルトのコンパイラがgccで、clangをインストールした場合は、clangを使用してプロジェクトを簡単にコンパイルできます。

$ mkdir build && cd build
$ CXX=clang++ CC=clang cmake ..
$ make -j2
2
xl4times