CMake syntax - Environment Variable

CMake syntax - Environment Variable

1. Define environment variables

set(ENV{<variable>} [<value>])
  • ENV: environment variable token prefix
  • Variable: variable name
  • Value: variable value

2. Application environment variables

2.1 code structure

  • learn_cmake: is the root directory
  • build: configure the output directory for CMake (in this case, where the sln solution is generated)
  • cmake_config.bat: script to execute CMake configuration process (double click to run directly)
  • CMakeLists.txt: CMake script

2.2 example code

  1. Sample code (content of CMakeLists.txt file)

    cmake_minimum_required(VERSION 3.18)
    
    # Set project name
    set(PROJECT_NAME KAIZEN)
    
    # Set project version number
    set(PROJECT_VERSION "1.0.0.10" CACHE STRING "Default version number")
    
    # Engineering definition
    project(${PROJECT_NAME}
        LANGUAGES CXX C
        VERSION ${PROJECT_VERSION}
    )
    
    # Print start log
    message(STATUS "\n########## BEGIN_TEST_ENV_VARIABLE")
    
    # Judge Java_ Is the home variable defined
    if(DEFINED ENV{JAVA_HOME})
        message("JAVA_HOME: $ENV{JAVA_HOME}")
    else()
        message("NOT DEFINED JAVA_HOME VARIABLES")
    endif()
    
    # Define environment variables
    set(ENV{CMAKE_PATH} "F:/cmake")
    
    # Judge cmake_ Is the path environment variable defined
    if(DEFINED ENV{CMAKE_PATH})
        message("CMAKE_PATH_1: $ENV{CMAKE_PATH}")
    else()
        message("NOT DEFINED CMAKE_PATH VARIABLES")
    endif()
    
    # Define the test function and newly define the environment variable in the function
    function(test_env_variable)
        # Accessing the environment variable CMAKE_PATH
        message("CMAKE_PATH_2: $ENV{CMAKE_PATH}")
        
        # Define environment variables within functions
        set(ENV{CMAKE_FUNC} "F:/cmake/dir")
    
        # Judge cmake_ Is the func environment variable defined
        if(DEFINED ENV{CMAKE_FUNC})
            message("CMAKE_FUNC_1: $ENV{CMAKE_FUNC}")
        else()
            message("NOT DEFINED CMAKE_FUNC_1 VARIABLES")
        endif()
    endfunction()
    
    # Call function
    test_env_variable()
    
    # Judge cmake_ Is the func environment variable defined
    if(DEFINED ENV{CMAKE_FUNC})
        message("CMAKE_FUNC_2: $ENV{CMAKE_FUNC}")
    else()
        message("NOT DEFINED CMAKE_FUNC_2 VARIABLES")
    endif()
    
    # If there is no parameter value
    set(ENV{CMAKE_FUNC})
    
    # Judge cmake_ Is the func environment variable defined
    if(DEFINED ENV{CMAKE_FUNC})
        message("CMAKE_FUNC_3: $ENV{CMAKE_FUNC}")
    else()
        message("NOT DEFINED CMAKE_FUNC_3 VARIABLES")
    endif()
    
    # Define the test macro and newly define the environment variable in the function
    macro(test_env_var)
        # Accessing the environment variable CMAKE_PATH
        message("CMAKE_PATH_3: $ENV{CMAKE_PATH}")
        
        # Defining environment variables within macros
        set(ENV{CMAKE_MACRO} "F:/cmake/macro")
    
        # Judge cmake_ Is macro environment variable defined
        if(DEFINED ENV{CMAKE_MACRO})
            message("CMAKE_MACRO_1: $ENV{CMAKE_MACRO}")
        else()
            message("NOT DEFINED CMAKE_MACRO_1 VARIABLES")
        endif()
    endmacro()
    
    # Call macro
    test_env_var()
    
    # Judge cmake_ Is macro environment variable defined
    if(DEFINED ENV{CMAKE_MACRO})
        message("CMAKE_MACRO_2: $ENV{CMAKE_MACRO}")
    else()
        message("NOT DEFINED CMAKE_MACRO_2 VARIABLES")
    endif()
    
    # If more than one parameter value
    set(ENV{CMAKE_FILE} "F:/cmake/cmake1.txt" "F:/cmake/cmake2.txt")
    
    # Judge cmake_ Is the file environment variable defined
    if(DEFINED ENV{CMAKE_FILE})
        message("CMAKE_FILE: $ENV{CMAKE_FILE}")
    else()
        message("NOT DEFINED CMAKE_FILE VARIABLES")
    endif()
    
    # Print end log
    message(STATUS "########## END_TEST_ENV_VARIABLE\n")
    
  2. 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 operation results

  1. Local environment

    Local installation VS version: Visual Studio 2019 (2015 toolset)

    CMake version: 3.18.2

    F:\learn_cmake
    λ cmake --version
    cmake version 3.18.2
     
    CMake suite maintained and supported by Kitware (kitware.com/cmake).
    
  2. Output results

    -- 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
     Please press any key to continue. . .
    

3 Summary

  1. When setting or reading environment variables, environment variables are accessed through ENV prefix.

  2. When reading the value of environment variable, add the $sign before ENV; However, if does not need to add the $symbol when judging whether it is defined or not.

  3. Set the environment variable. This command only affects the current CMake process, does not affect the process calling CMake, and does not affect the entire system environment.

  4. When setting the environment variable, no value is assigned to the variable:

    If there is an environment variable with the same name, this command will clear the existing environment variable with the same name;

    If there is no environment variable with the same name, this command will be regarded as invalid code.

    As in line 62 of the sample program, the existing environment variable cmake will be cleared_ Func, which results in line 21 of the output result: NOT DEFINED CMAKE_FUNC_3 VARIABLES

  5. When setting environment variables, there is only one variable value. Redundant values are ignored and a warning message is prompted.

    As shown in line 98 of the example program, the variable value is 2, the second value of the result is ignored, and CMake Warning will be printed into the output result.

  6. Environment variable, there is no scope distinction. That is, functions, macros, subdirectories and included modules are the same, which will only affect the current CMake process.

    For example, in lines 52 and 88 of the example program, after the test of calling functions and macros, the external environment variables can be accessed internally; Environment variables defined internally can also be used externally.

    Subdirectories and functions belong to the same category (with scope distinction), and macros and containing modules belong to the same category (without scope distinction). Therefore, only two tests can explain the problem here.

Posted on Sun, 28 Nov 2021 22:31:46 -0500 by Hellusius