CMake語法—環境變量(Environment Variable)
1 定義環境變量
set(ENV{<variable>} [<value>])
- ENV:環境變量標志性前綴
- variable:變量名稱
- value:變量值
2 應用環境變量
2.1 代碼結構
- learn_cmake:為根目錄
- build:為CMake配置輸出目錄(在此例中即生成sln解決方案的地方)
- cmake_config.bat:執行CMake配置過程的腳本(雙擊直接運行)
- CMakeLists.txt:CMake腳本
2.2 示例代碼
-
示例代碼(CMakeLists.txt文件內容)
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_ENV_VARIABLE") # 判斷JAVA_HOME變量是否定義 if(DEFINED ENV{JAVA_HOME}) message("JAVA_HOME: $ENV{JAVA_HOME}") else() message("NOT DEFINED JAVA_HOME VARIABLES") endif() # 定義環境變量 set(ENV{CMAKE_PATH} "F:/cmake") # 判斷CMAKE_PATH環境變量是否定義 if(DEFINED ENV{CMAKE_PATH}) message("CMAKE_PATH_1: $ENV{CMAKE_PATH}") else() message("NOT DEFINED CMAKE_PATH VARIABLES") endif() # 定義測試函數,在函數中新定義環境變量 function(test_env_variable) # 訪問環境變量CMAKE_PATH message("CMAKE_PATH_2: $ENV{CMAKE_PATH}") # 函數內定義環境變量 set(ENV{CMAKE_FUNC} "F:/cmake/dir") # 判斷CMAKE_FUNC環境變量是否定義 if(DEFINED ENV{CMAKE_FUNC}) message("CMAKE_FUNC_1: $ENV{CMAKE_FUNC}") else() message("NOT DEFINED CMAKE_FUNC_1 VARIABLES") endif() endfunction() # 調用函數 test_env_variable() # 判斷CMAKE_FUNC環境變量是否定義 if(DEFINED ENV{CMAKE_FUNC}) message("CMAKE_FUNC_2: $ENV{CMAKE_FUNC}") else() message("NOT DEFINED CMAKE_FUNC_2 VARIABLES") endif() # 如果沒有參數值 set(ENV{CMAKE_FUNC}) # 判斷CMAKE_FUNC環境變量是否定義 if(DEFINED ENV{CMAKE_FUNC}) message("CMAKE_FUNC_3: $ENV{CMAKE_FUNC}") else() message("NOT DEFINED CMAKE_FUNC_3 VARIABLES") endif() # 定義測試宏,在函數中新定義環境變量 macro(test_env_var) # 訪問環境變量CMAKE_PATH message("CMAKE_PATH_3: $ENV{CMAKE_PATH}") # 宏內定義環境變量 set(ENV{CMAKE_MACRO} "F:/cmake/macro") # 判斷CMAKE_MACRO環境變量是否定義 if(DEFINED ENV{CMAKE_MACRO}) message("CMAKE_MACRO_1: $ENV{CMAKE_MACRO}") else() message("NOT DEFINED CMAKE_MACRO_1 VARIABLES") endif() endmacro() # 調用宏 test_env_var() # 判斷CMAKE_MACRO環境變量是否定義 if(DEFINED ENV{CMAKE_MACRO}) message("CMAKE_MACRO_2: $ENV{CMAKE_MACRO}") else() message("NOT DEFINED CMAKE_MACRO_2 VARIABLES") endif() # 如果多個參數值 set(ENV{CMAKE_FILE} "F:/cmake/cmake1.txt" "F:/cmake/cmake2.txt") # 判斷CMAKE_FILE環境變量是否定義 if(DEFINED ENV{CMAKE_FILE}) message("CMAKE_FILE: $ENV{CMAKE_FILE}") else() message("NOT DEFINED CMAKE_FILE VARIABLES") endif() # 打印結束日志 message(STATUS "########## END_TEST_ENV_VARIABLE\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 pause
2.3 運行結果
-
本地環境
本地安裝VS版本:Visual Studio 2019(2015工具集)
CMake版本:3.18.2
F:\learn_cmake λ cmake --version cmake version 3.18.2 CMake suite maintained and supported by Kitware (kitware.com/cmake).
-
輸出結果
-- 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_ENV_VARIABLE JAVA_HOME: C:\Program Files\Java\jdk1.8.0_201 CMAKE_PATH_1: F:/cmake CMAKE_PATH_2: F:/cmake CMAKE_FUNC_1: F:/cmake/dir CMAKE_FUNC_2: F:/cmake/dir NOT DEFINED CMAKE_FUNC_3 VARIABLES CMAKE_PATH_3: F:/cmake CMAKE_MACRO_1: F:/cmake/macro CMAKE_MACRO_2: F:/cmake/macro CMake Warning (dev) at CMakeLists.txt:98 (set): Only the first value argument is used when setting an environment variable. Argument 'F:/cmake/cmake2.txt' and later are unused. This warning is for project developers. Use -Wno-dev to suppress it. CMAKE_FILE: F:/cmake/cmake1.txt -- ########## END_TEST_ENV_VARIABLE -- Configuring done -- Generating done -- Build files have been written to: F:/learn_cmake/build 請按任意鍵繼續. . .
3 小結
-
設定或讀取環境變量時,都通過ENV前綴來訪問環境變量。
-
讀取環境變量值時,要在ENV前加$符號;但if判斷是否定義時,不用加$符號。
-
設定環境變量,此命令只影響當前CMake進程,不影響調用CMake的進程,也不影響整個系統環境。
-
設定環境變量時,沒有給變量賦值:
如果有同名環境變量,此命令將清除已存在的同名環境變量;
如果沒有同名環境變量,此命令將被視為無效代碼。
如示例程序中第62行,將清除已存在的環境變量CMAKE_FUNC,這樣導致輸出結果第21行:NOT DEFINED CMAKE_FUNC_3 VARIABLES
-
設定環境變量時,變量值僅有一個。多余的值會被忽略,並且會提示警告信息。
如示例程序中第98行,變量值為2個,結果第二個值被忽略,且會有CMake Warning打印到輸出結果內容中。
-
環境變量,不存在作用域的區分。即函數、宏、子目錄、包含模塊中都一樣,只會影響當前CMake進程。
如示例程序中第52、88行,經過調用函數和宏的測試,其內部可以訪問外部的環境變量;在其內部定義的環境變量,在外部也可以正常使用。
子目錄與函數屬於同類(有作用域區分),宏和包含模塊屬於同類(無作用域區分),因此,在此只用測試兩種即可說明問題。