步驟 4:新增產生器表達式

產生器表達式 會在建置系統生成期間進行評估,以產生每個建置配置特定的資訊。

產生器表達式 允許在許多目標屬性的上下文中使用,例如 LINK_LIBRARIESINCLUDE_DIRECTORIESCOMPILE_DEFINITIONS 等。它們也可以在用於填充這些屬性的命令中使用,例如 target_link_libraries()target_include_directories()target_compile_definitions() 等。

產生器表達式 可用於啟用條件式連結、編譯時使用的條件式定義、條件式包含目錄等。條件可以基於建置配置、目標屬性、平台資訊或任何其他可查詢的資訊。

有不同類型的 產生器表達式,包括邏輯、資訊和輸出表達式。

邏輯表達式用於建立條件式輸出。基本表達式是 01 表達式。 $<0:...> 會產生空字串,而 $<1:...> 會產生 ... 的內容。它們也可以巢狀使用。

練習 1 - 使用產生器表達式新增編譯器警告標誌

產生器表達式 的常見用途是條件式地新增編譯器標誌,例如用於語言層級或警告的標誌。一個好的模式是將此資訊與 INTERFACE 目標相關聯,以便讓此資訊傳播。

目標

在建置時新增編譯器警告標誌,但不安裝的版本新增。

有用的資源

要編輯的檔案

  • CMakeLists.txt

開始使用

開啟檔案 Step4/CMakeLists.txt 並完成 TODO 1TODO 4

首先,在頂層的 CMakeLists.txt 檔案中,我們需要將 cmake_minimum_required() 設定為 3.15。在此練習中,我們將使用 CMake 3.15 中引入的產生器表達式。

接下來,我們新增專案所需的編譯器警告標誌。由於警告標誌因編譯器而異,因此我們使用 COMPILE_LANG_AND_ID 產生器表達式來控制給定語言和一組編譯器 ID 時要套用的標誌。

建置並執行

建立一個名為 Step4_build 的新目錄,執行 cmake 可執行檔或 cmake-gui 來配置專案,然後使用您選擇的建置工具或從建置目錄使用 cmake --build . 來建置它。

mkdir Step4_build
cd Step4_build
cmake ../Step4
cmake --build .

解決方案

更新 cmake_minimum_required() 以要求至少 CMake 版本 3.15

TODO 1:點擊以顯示/隱藏答案
TODO 1: CMakeLists.txt
cmake_minimum_required(VERSION 3.15)

接下來,我們確定系統目前使用的編譯器進行建置,因為警告標誌會因我們使用的編譯器而異。這可以使用 COMPILE_LANG_AND_ID 產生器表達式來完成。我們將結果設定在變數 gcc_like_cxxmsvc_cxx 中,如下所示

TODO 2:點擊以顯示/隱藏答案
TODO 2: CMakeLists.txt
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")

接下來,我們新增專案所需的編譯器警告標誌。使用我們的變數 gcc_like_cxxmsvc_cxx,我們可以使用另一個產生器表達式,僅在變數為 true 時套用各自的標誌。我們使用 target_compile_options() 將這些標誌套用至我們的介面程式庫。

TODO 3:點擊以顯示/隱藏答案
TODO 3: CMakeLists.txt
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
  "$<${msvc_cxx}:-W3>"
)

最後,我們只希望在建置期間使用這些警告標誌。已安裝專案的使用者不應繼承我們的警告標誌。為了指定這一點,我們使用 BUILD_INTERFACE 條件,將 TODO 3 中的標誌包裝在產生器表達式中。產生的完整程式碼如下所示

TODO 4:點擊以顯示/隱藏答案
TODO 4: CMakeLists.txt
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)