cmake: how to check if preprocessor is defined

11,926

Solution 1

This is to complete the answer by arrowd.

I also tried the COMPILE_DEFINITIONS option as mentioned above by arrowd unsuccessfully.

Following the documentation of CMake, at least for version 3.x, it turns out that when you call add_definitions() in CMake, it adds the definitions to the COMPILE_DEFINITIONS directory property.

Therefore, lets say you are defining the following as per your code:

add_definitions(-DOS=LINUX)

To retrieve the string with the definitions added into the variable "MYDEFS" you can use the following lines in CMake:

get_directory_property(MYDEFS COMPILE_DEFINITIONS)
MESSAGE( STATUS "Compile defs contain: " ${MYDEFS} )

Then you can check if in ${MYDEFS} the define you are looking for exists or not. For instance

if(MYDEFS MATCHES "^OS=" OR MYDEFS MATCHES ";OS=")
    MESSAGE( STATUS "OS defined" )
else()
    # You can define your OS here if desired
endif()

Solution 2

Normally, all definitions that are passed to the compiler are controlled by CMake. That is, you create a CMake variable with

option(SOMEFEATURE "Feature description" ON)

or

set(OS "" CACHE STRING "Select your OS")

User sets them via cmake -D OS=DOS or in the CMake GUI. Then you can use if() operator to conditionally add_definitions() to the compiler command line.

UPDATE:

If you really want to access preprocessor flags, there is a COMPILE_DEFINITIONS target property. You can access it this way:

get_target_property(OUTVAR target COMPILE_DEFINITIONS)
Share:
11,926
Mandeep Sandhu
Author by

Mandeep Sandhu

Updated on June 24, 2022

Comments

  • Mandeep Sandhu
    Mandeep Sandhu almost 2 years

    I can't get cmake to test if a preprocessor has been defined or not. Eg:

    cmake_minimum_required(VERSION 2.8.9)
    project (cmake-test)
    add_definitions(-DOS=LINUX)
    
    if(NOT <what condition goes here?>)
        message(FATAL_ERROR "OS is not defined")
    endif()
    

    The following tests don't work:

    if (NOT COMMAND OS)
    if (NOT DEFINED OS)
    if (NOT OS)
    

    I can get it to work by using set() and just testing for a regular cmake variable and then defining the preprocessor macro. Eg:

    set(OS LINUX)
    if (OS)
        add_definitions(-DOS=${OS})
    else()
        message(FATAL_ERROR "OS is not defined")
    endif()
    

    In case, you're wondering why I need to test it if the variable/preprocessor is in the same file, it's because in the final implementation these will come from an external file which is includeed in the main CMakeFile.txt Eg:

    include(project_defs.txt)
    if (OS)
        ....
    
  • Mandeep Sandhu
    Mandeep Sandhu over 8 years
    So then the second approach I mentioned is probably the only way to do this I guess.It would've been nice if cmake would allow testing stuff set via add_definitions.
  • Mandeep Sandhu
    Mandeep Sandhu over 8 years
    Thanks for the update. I did look in the COMPILE_DEFINITIONS as the docs for add_definitions() mention it. However I was unable to fetch the defines specified (I tried your suggestion of using get_target_property but got NOTFOUND instead). I'm using cmake 2.8.12.2
  • arrowd
    arrowd over 8 years
    This is strange, because even for 2.8 such property exists: cmake.org/cmake/help/v2.8.12/… Try using more recent CMake.