Conditional compile definition

adamaynard
Posts: 4
Joined: Thu Oct 20, 2022 1:48 pm

Conditional compile definition

Postby adamaynard » Thu Oct 20, 2022 1:57 pm

I am trying to find a way to add compile definition based on an environment variable. I tried something like this in the main CMakeList.txt:

Code: Select all

if(DEFINED ENV{MY_ENV_VAR})
    add_compile_definitions(MY_DEFINITION)
endif()
It works fine when build is invoked initially, but after that the build system doesn't look in the Cmake files. So, no metter if MY_ENV_VAR is set or not, only the initial configuration will be used.
Is there a way to add compile definition dynamically, ie. if MY_ENV_VAR is set, then add it. When next build is started without MY_ENV_VAR being set, then do not add MY_DEFINITION.

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: Conditional compile definition

Postby ESP_igrr » Thu Oct 20, 2022 5:27 pm

What you are trying to do is a bit complicated since CMake tries hard to avoid dependencies of the build process on the environment. All the variables are captured at configuration time and the build process doesn't depend on the environment.

I happen to have a project where this was done before, and the solution we found is to:
  • Store the value of the environment variable in a file
  • Regenerate this file on every build only if the file content would change (using CMake configure_file function)
  • Make the CMake configuration stage dependent on the resulting file
This requires 3 files:

In the project CMakeLists.txt:

Code: Select all

cmake_minimum_required(VERSION 3.16)

# This will dump the environment variable to the file on the initial CMake run,
# when the file doesn't exist yet
execute_process(COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/dump_env.cmake
                WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

# This will create a build step which will update the file contents on each build.
# (dump_env.cmake uses configure_file inside, which only updates the file
# if the content changes; otherwise CMake would keep re-running over and over.)
add_custom_target(update_cache
                  ALL
                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/dump_env.cmake
                  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
                  BYPRODUCTS ${CMAKE_BINARY_DIR}/env_cache.txt)

# This adds dependency of the configuration stage on the generated file
# where the environment variable is dumped.
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS 
  ${CMAKE_BINARY_DIR}/env_cache.txt
)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello_world)
in dump_env.cmake, in the same project directory:

Code: Select all

set(MY_ENV_VAR "$ENV{MY_ENV_VAR}")
configure_file(${CMAKE_CURRENT_LIST_DIR}/env_cache.in env_cache.txt)
in env_cache.in, in the same project directory:

Code: Select all

MY_ENV_VAR=@MY_ENV_VAR@
There is an issue in CMake repository to simplify such logic: https://gitlab.kitware.com/cmake/cmake/-/issues/20892

adamaynard
Posts: 4
Joined: Thu Oct 20, 2022 1:48 pm

Re: Conditional compile definition

Postby adamaynard » Fri Oct 21, 2022 5:56 am

This works, thank you!

Who is online

Users browsing this forum: Google [Bot] and 111 guests