cmake:選擇編譯器及設置編譯器選項


1. 說明

在實際的項目平台中可能安裝有多個版本的編譯器,同時由於不同的功能可能會需要設置不同的編譯參數,這篇筆記就記錄如何選擇指定的編譯器和配置參數。

2. 選擇編譯器

2.1 初始狀態

我使用的開發平台默認安裝的gcc5.5.0,后面又安裝了clang3.8.0,在默認path下C編譯器會使用gcc 5.5.0,C++編譯器使用clang3.8.0,如下所示:

/build$ cmake ..
-- The C compiler identification is GNU 5.5.0
-- The CXX compiler identification is Clang 3.8.0
...
 

后面由於項目開發的要求我又安裝了gcc8.3.0版本,PATH也是設置為8.3.0,即在命令行下輸入"gcc -v"默認顯示8.3.0,但是在cmake會根據PATH路徑去查找支持的編譯器,還是會首先查找到原來的編譯器版本。

2.2 使用命令行

在編譯時可以通過參數直接選擇指定的編譯器的完整路徑,比如我的gcc8.3.0安裝在/usr/local/gcc/bin路徑下,在編譯時輸入:

cmake .. -DCMAKE_CXX_COMPILER=/usr/local/gcc/bin/g++

就會在編譯時選定gcc-8.3.0

2.3 在配置文件中指定

在CMakeLists.txt文件中添加:

set (CMAKE_C_COMPILER "/usr/local/gcc/bin/gcc")
set (CMAKE_CXX_COMPILER "/usr/local/gcc/bin/g++")

直接修改全局變量CMAKE_C_COMPILER和CMAKE_CXX_COMPILER為指定的編譯器路徑。

注:這兩條命令應該放在文件的開始位置(cmake_minimum_required命令之下,其他命令之上),否則可能無效。

CMAKE_C_COMPILER
原本是保存環境變量"CC"值的變量,而CC是編譯C語言的首選編譯器,但是在新的CMP0054策略中如果設置的CMAKE_C_COMPILER則會忽略CC的值。

CMAKE_CXX_COMPILER
與CMAKE_C_COMPILER類似,不過這個變量對應的環境變量是CXX,是編譯C++語言的編譯器。

結果如下:

$ cmake ..
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
...

3. 配置編譯參數

假設我使用g++編譯器,添加"-std=c++11", “-Wall"和”-Werror"等參數為例。

3.1 使用add_compile_options命令

通過在CMakeLists.txt文件中添加add_compile_options命令可以起到添加參數的作用,如:

add_compile_options(-std=c++11 -Wall -Werror)

但是這個命令是針對所有類型編譯器的,也就是說這里添加的選項會在所有的編譯器中運用,比如-std=c++11是針對C++的編譯器參數,也會被運用在C語言編譯器中,雖然不一定會報錯但是終究體驗感不好。而且此命令添加的參數是遞歸的,即在多層目錄結構中,根文件下設置選項后,在所有的子目錄編譯時都會運用。

3.2 通過設置CMAKE_CXX_FLAGS來配置

CMAKE_CXX_FLAGS是針對C++編譯器的參數選項,默認保存環境變量CXX_FLAGS的內容,但是如果直接修改這個參數值,那么系統會忽略原CXX_FLAGS的內容。設置方式如下:

set(CMAKE_CXX_FLAGS
    -std=c++11
    -Wall
    -Werror
)
 

這個變量只在當前文件有效,如果項目中有多個模塊,多個編譯文件,那么需在每一個CMakeLists.txt文件中都添加對應的命令和參數。

3.3 兩種方式比較

add_compile_options CMAKE_CXX_FLAGS
對所有編譯器有效 只針對C++編譯器
作用域是全局,對所有編譯文件有效 作用域是單個編譯文件

綜上,對於一些在整個項目中通用的編譯選項可以使用add_compile_options命令來添加比較方便,對於各個模塊中的獨立選項則使用CMAKE_CXX_FLAGS變量更好。

4. 命令解析

4.1 add_compile_options

將編譯器選項添加到當前及子目錄的源文件的編譯中。

用法

add_compile_options(<option> ...)
 
  • option:編譯選項,注意對於不同編譯器,支持的選項可能不一樣。

示例

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

4.2 add_compile_definitions

將預編譯參數添加到源文件的編譯中,對下級子目錄同樣有效。

用法

add_compile_definitions(<definition> ...)

預編譯命令會添加到COMPILE_DEFINITIONS目錄屬性中。

5. CMAKE__FLAGS變量

這里用到的CMAKE_CXX_FLAGS變量是只針對C++編譯器的選項,對於其他編程語言,只要替換部分就可以,在當前cmake版本(3.17.2)中支持如下語言:

  • CMAKE_C_FLAGS:C語言編譯器選項,對應於環境變量CFLAGS
  • CMAKE_CXX_FLAGS:C++語言編譯器選項,對應於環境變量CXXFLAGS
  • CMAKE_CUDA_FLAGS:CUDA語言編譯器選項,對應於環境變量CUDAFLAGS
  • CMAKE_Fortran_FLAGS:Fortran語言編譯器選項,對應於環境變量FFLAGS
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM