步驟 4:新增產生器表達式¶
Generator expressions
會在建置系統生成期間進行評估,以產生每個建置配置特定的資訊。
Generator expressions
允許在許多目標屬性的上下文中使用,例如 LINK_LIBRARIES
、 INCLUDE_DIRECTORIES
、 COMPILE_DEFINITIONS
等等。 它們也可以在使用命令來填充這些屬性時使用,例如 target_link_libraries()
、 target_include_directories()
、 target_compile_definitions()
等等。
Generator expressions
可用於啟用條件式連結、編譯時使用的條件式定義、條件式包含目錄等等。 條件可以基於建置配置、目標屬性、平台資訊或任何其他可查詢的資訊。
有不同類型的 generator expressions
,包括邏輯、資訊和輸出表達式。
邏輯表達式用於建立條件式輸出。 基本表達式是 0
和 1
表達式。 $<0:...>
產生空字串,而 $<1:...>
產生 ...
的內容。 它們也可以巢狀使用。
練習 1 - 使用產生器表達式新增編譯器警告標誌¶
常見的 generator expressions
用法是條件式地新增編譯器標誌,例如用於語言層級或警告的標誌。 一個好的模式是將此資訊與 INTERFACE
目標關聯,允許此資訊傳播。
目標¶
在建置時新增編譯器警告標誌,但不要針對已安裝的版本。
實用資源¶
要編輯的檔案¶
CMakeLists.txt
開始¶
開啟檔案 Step4/CMakeLists.txt
並完成 TODO 1
到 TODO 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: 點擊顯示/隱藏答案
cmake_minimum_required(VERSION 3.15)
接下來,我們確定系統目前正在使用哪個編譯器進行建置,因為警告標誌會因我們使用的編譯器而異。 這是透過 COMPILE_LANG_AND_ID
產生器表達式完成的。 我們在變數 gcc_like_cxx
和 msvc_cxx
中設定結果,如下所示
TODO 2: 點擊顯示/隱藏答案
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_cxx
和 msvc_cxx
,我們可以使用另一個產生器表達式,僅在變數為真時套用各自的標誌。 我們使用 target_compile_options()
將這些標誌套用到我們的介面函式庫。
TODO 3: 點擊顯示/隱藏答案
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: 點擊顯示/隱藏答案
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)