CMake語法—選項(option)
1 選項
1.1 定義
option(<variable> "<help_text>" [value])
1.2 說明
- variable 選項名
- help_text 描述、解釋、備注
- value 選項初始化值(除ON而外全為OFF)
2 應用注意事項
2.1 代碼結構
-
learn_cmake:為根目錄
-
build:為CMake配置輸出目錄(在此例中即生成sln解決方案的地方)
-
CMakeLists.txt:CMake腳本
-
cmake_config.bat:執行CMake配置過程的腳本(雙擊直接運行)
@echo off set currentDir=%~dp0 set buildDir=%currentDir% set cmakeOutputDir=%currentDir%\build cmake -S %buildDir% -B %cmakeOutputDir% -G"Visual Studio 16 2019" -T v140 -A x64 pause
2.2 注意事項
2.2.1 不初始化或賦為非ON的值,全部視為OFF
-
示例代碼
cmake_minimum_required(VERSION 3.18) # 設置工程名稱 set(PROJECT_NAME KAIZEN) # 設置工程版本號 set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默認版本號") # 工程定義 project(${PROJECT_NAME} LANGUAGES CXX C VERSION ${PROJECT_VERSION} ) # 打印開始日志 message(STATUS "\n########## BEGIN_TEST_OPTION") ## 示例1:不賦值 option(${PROJECT_NAME}_BUILD_TEST "構建測試模塊") if (DEFINED ${PROJECT_NAME}_BUILD_TEST) message(STATUS "defined KAIZEN_BUILD_TEST") else() message(STATUS "not defined KAIZEN_BUILD_TEST") endif() if (${PROJECT_NAME}_BUILD_TEST) message(STATUS "KAIZEN_BUILD_TEST is ON") else() message(STATUS "KAIZEN_BUILD_TEST is OFF") endif() message(STATUS "\n") ## 示例2:賦值為非ON、非OFF值 option(${PROJECT_NAME}_BUILD_EXAMPLE "構建示例模塊" AAA) if (DEFINED ${PROJECT_NAME}_BUILD_EXAMPLE) message(STATUS "defined KAIZEN_BUILD_EXAMPLE") else() message(STATUS "not defined KAIZEN_BUILD_EXAMPLE") endif() if (${PROJECT_NAME}_BUILD_EXAMPLE) message(STATUS "KAIZEN_BUILD_EXAMPLE_1 is ON") else() message(STATUS "KAIZEN_BUILD_EXAMPLE_1 is OFF") endif() if (${${PROJECT_NAME}_BUILD_TYPE}) message(STATUS "KAIZEN_BUILD_EXAMPLE_2 is ON") else() message(STATUS "KAIZEN_BUILD_EXAMPLE_2 is OFF") endif() message(STATUS "\n") ## 示例3:賦值為ON option(${PROJECT_NAME}_BUILD_GUI "構建視圖模塊" ON) if (DEFINED ${PROJECT_NAME}_BUILD_GUI) message(STATUS "defined KAIZEN_BUILD_GUI") else() message(STATUS "not defined KAIZEN_BUILD_GUI") endif() if (${PROJECT_NAME}_BUILD_GUI) message(STATUS "KAIZEN_BUILD_GUI is ON") else() message(STATUS "KAIZEN_BUILD_GUI is OFF") endif() # 打印結束日志 message(STATUS "########## END_TEST_OPTION\n")
-
運行結果
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763. -- The CXX compiler identification is MSVC 19.0.24245.0 -- The C compiler identification is MSVC 19.0.24245.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- ########## BEGIN_TEST_OPTION -- defined KAIZEN_BUILD_TEST -- KAIZEN_BUILD_TEST is OFF -- -- defined KAIZEN_BUILD_EXAMPLE -- KAIZEN_BUILD_EXAMPLE_1 is OFF -- KAIZEN_BUILD_EXAMPLE_2 is OFF -- -- defined KAIZEN_BUILD_GUI -- KAIZEN_BUILD_GUI is ON -- ########## END_TEST_OPTION -- Configuring done -- Generating done -- Build files have been written to: F:/learn_cmake/build 請按任意鍵繼續. . .
2.2.2 在定義語句執行后才有效;在定義之前均視為未定義(除過在CMake命令中通過-D預定義)
-
示例代碼
cmake_minimum_required(VERSION 3.18) # 設置工程名稱 set(PROJECT_NAME KAIZEN) # 設置工程版本號 set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默認版本號") # 工程定義 project(${PROJECT_NAME} LANGUAGES CXX C VERSION ${PROJECT_VERSION} ) # 打印開始日志 message(STATUS "\n########## BEGIN_TEST_OPTION") ## 定義之前是看不到的 if (DEFINED ${PROJECT_NAME}_BUILD_TEST) message(STATUS "defined KAIZEN_BUILD_TEST") else() message(STATUS "not defined KAIZEN_BUILD_TEST") endif() ## 定義語句 option(${PROJECT_NAME}_BUILD_TEST "構建測試模塊" ON) ## 定義后才可以看到 if (DEFINED ${PROJECT_NAME}_BUILD_TEST) message(STATUS "defined KAIZEN_BUILD_TEST") else() message(STATUS "not defined KAIZEN_BUILD_TEST") endif() ## 定義后再應用 if (${PROJECT_NAME}_BUILD_TEST) message(STATUS "KAIZEN_BUILD_TEST is ON") else() message(STATUS "KAIZEN_BUILD_TEST is OFF") endif() # 打印結束日志 message(STATUS "########## END_TEST_OPTION\n")
-
運行結果
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763. -- The CXX compiler identification is MSVC 19.0.24245.0 -- The C compiler identification is MSVC 19.0.24245.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- ########## BEGIN_TEST_OPTION -- not defined KAIZEN_BUILD_TEST -- defined KAIZEN_BUILD_TEST -- KAIZEN_BUILD_TEST is ON -- ########## END_TEST_OPTION -- Configuring done -- Generating done -- Build files have been written to: F:/learn_cmake/build 請按任意鍵繼續. . .
2.2.3 已定義option選項會存儲在CMakeCache.txt中。等價於緩存變量作用。
運行2.2.1中的示例代碼,然后可以查看build目錄下的CMakeCache.txt文件。如下圖:
2.2.4 如果出現同名的變量(普通或緩存變量),則option會被忽略
-
示例代碼
cmake_minimum_required(VERSION 3.18) # 設置工程名稱 set(PROJECT_NAME KAIZEN) # 設置工程版本號 set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默認版本號") # 工程定義 project(${PROJECT_NAME} LANGUAGES CXX C VERSION ${PROJECT_VERSION} ) # 打印開始日志 message(STATUS "\n########## BEGIN_TEST_OPTION") ## 1.1先定義普通變量 set(${PROJECT_NAME}_BUILD_TEST "構建測試模塊") if (DEFINED ${PROJECT_NAME}_BUILD_TEST) message(STATUS "defined KAIZEN_BUILD_TEST") else() message(STATUS "not defined KAIZEN_BUILD_TEST") endif() message(STATUS "KAIZEN_BUILD_TEST_1: ${${PROJECT_NAME}_BUILD_TEST}\n") ## 1.2再定義同名option選項 option(${PROJECT_NAME}_BUILD_TEST "構建測試模塊" ON) message(STATUS "KAIZEN_BUILD_TEST_2: ${${PROJECT_NAME}_BUILD_TEST}\n") ### 2.1先定義option選項 option(${PROJECT_NAME}_BUILD_EXAMPLE "構建示例模塊" OFF) if (DEFINED ${PROJECT_NAME}_BUILD_EXAMPLE) message(STATUS "defined KAIZEN_BUILD_EXAMPLE") else() message(STATUS "not defined KAIZEN_BUILD_EXAMPLE") endif() message(STATUS "KAIZEN_BUILD_EXAMPLE_1: ${KAIZEN_BUILD_EXAMPLE}") ### 2.2再定義普通同名變量 set(${PROJECT_NAME}_BUILD_EXAMPLE "構建示例模塊") message(STATUS "KAIZEN_BUILD_EXAMPLE_2: ${KAIZEN_BUILD_EXAMPLE}") # 打印結束日志 message(STATUS "########## END_TEST_OPTION\n")
-
運行結果
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763. -- The CXX compiler identification is MSVC 19.0.24245.0 -- The C compiler identification is MSVC 19.0.24245.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- ########## BEGIN_TEST_OPTION -- defined KAIZEN_BUILD_TEST -- KAIZEN_BUILD_TEST_1: 構建測試模塊 -- KAIZEN_BUILD_TEST_2: 構建測試模塊 -- defined KAIZEN_BUILD_EXAMPLE -- KAIZEN_BUILD_EXAMPLE_1: OFF -- KAIZEN_BUILD_EXAMPLE_2: 構建示例模塊 -- ########## END_TEST_OPTION -- Configuring done -- Generating done -- Build files have been written to: F:/learn_cmake/build 請按任意鍵繼續. . .
2.2.5 CMake命令中通過-D預設同名變量,則option也會被忽略(其本質與2.2.4相同)
-
示例代碼
cmake_minimum_required(VERSION 3.18) # 設置工程名稱 set(PROJECT_NAME KAIZEN) # 設置工程版本號 set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默認版本號") # 工程定義 project(${ PROJECT_NAME } LANGUAGES CXX C VERSION ${ PROJECT_VERSION } ) # 打印開始日志 message(STATUS "\n########## BEGIN_TEST_OPTION") if (DEFINED ${ PROJECT_NAME }_BUILD_EXAMPLE) message(STATUS "defined KAIZEN_BUILD_EXAMPLE") else() message(STATUS "not defined KAIZEN_BUILD_EXAMPLE") endif() ## 定義option選項 option(${ PROJECT_NAME }_BUILD_EXAMPLE "構建示例模塊" OFF) message(STATUS "KAIZEN_BUILD_EXAMPLE: ${KAIZEN_BUILD_EXAMPLE}") # 打印結束日志 message(STATUS "########## END_TEST_OPTION\n")
-
cmake_config.bat
@echo off set currentDir=%~dp0 set buildDir=%currentDir% set cmakeOutputDir=%currentDir%\build cmake -S %buildDir% -B %cmakeOutputDir% -G"Visual Studio 16 2019" -T v140 -A x64 -DKAIZEN_BUILD_EXAMPLE=ON pause
-
運行結果
--Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763. --The CXX compiler identification is MSVC 19.0.24245.0 --The C compiler identification is MSVC 19.0.24245.0 --Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler : C: / Program Files(x86) / Microsoft Visual Studio 14.0 / VC / bin / amd64 / cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler : C: / Program Files(x86) / Microsoft Visual Studio 14.0 / VC / bin / amd64 / cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- ########## BEGIN_TEST_OPTION -- defined KAIZEN_BUILD_EXAMPLE -- KAIZEN_BUILD_EXAMPLE: ON -- ########## END_TEST_OPTION -- Configuring done -- Generating done -- Build files have been written to : F: / learn_cmake / build 請按任意鍵繼續. . .
2.2.6 修改option選項值(建議通過緩存變量方式修改)
-
示例代碼
cmake_minimum_required(VERSION 3.18) # 設置工程名稱 set(PROJECT_NAME KAIZEN) # 設置工程版本號 set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默認版本號") # 工程定義 project(${ PROJECT_NAME } LANGUAGES CXX C VERSION ${ PROJECT_VERSION } ) # 打印開始日志 message(STATUS "\n########## BEGIN_TEST_OPTION") if (DEFINED ${ PROJECT_NAME }_BUILD_EXAMPLE) message(STATUS "defined KAIZEN_BUILD_EXAMPLE") else() message(STATUS "not defined KAIZEN_BUILD_EXAMPLE") endif() ## 定義option選項 option(${ PROJECT_NAME }_BUILD_EXAMPLE "構建示例模塊" OFF) message(STATUS "KAIZEN_BUILD_EXAMPLE_1: ${KAIZEN_BUILD_EXAMPLE}") ## 方式一:修改option選項值(無效方式,請忽略) option(${ PROJECT_NAME }_BUILD_EXAMPLE "構建示例模塊" ON) message(STATUS "KAIZEN_BUILD_EXAMPLE_2: ${KAIZEN_BUILD_EXAMPLE}") ## 方式二:通過cache變量方式修改(正確方式,力推薦) set(${ PROJECT_NAME }_BUILD_EXAMPLE ON CACHE BOOL "構建示例模塊" FORCE) message(STATUS "KAIZEN_BUILD_EXAMPLE_3: ${KAIZEN_BUILD_EXAMPLE}") # 打印結束日志 message(STATUS "########## END_TEST_OPTION\n")
-
運行結果
--Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763. --The CXX compiler identification is MSVC 19.0.24245.0 --The C compiler identification is MSVC 19.0.24245.0 --Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler : C: / Program Files(x86) / Microsoft Visual Studio 14.0 / VC / bin / amd64 / cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler : C: / Program Files(x86) / Microsoft Visual Studio 14.0 / VC / bin / amd64 / cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- ########## BEGIN_TEST_OPTION -- not defined KAIZEN_BUILD_EXAMPLE -- KAIZEN_BUILD_EXAMPLE_1: OFF -- KAIZEN_BUILD_EXAMPLE_2 : OFF -- KAIZEN_BUILD_EXAMPLE_3 : ON -- ########## END_TEST_OPTION -- Configuring done -- Generating done -- Build files have been written to : F: / learn_cmake / build 請按任意鍵繼續. . .
當然,也可以通過定義同名普通變量方式進行修改。
但是,通過普通變量方式修改后,CMakeCache.txt中的值仍然為舊值。感興趣可自行驗證。
option選項本質與緩存變量相同,即會存儲在CMakeCache.txt中。因此修改其值也推薦使用緩存變量的方式,這樣會直接修改CMakeCache.txt中的存儲值,更徹底、更本質、更安全。