CMake: How to pass preprocessor macros
Asked Answered
N

2

54

How can I pass a macro to the preprocessor? For example, if I want to compile some part of my code because a user wants to compile unit test, I would do this:

#ifdef _COMPILE_UNIT_TESTS_
    BLA BLA
#endif //_COMPILE_UNIT_TESTS_

Now I need to pass this value from CMake to the preprocessor. Setting a variable doesn't work, so how can I accomplish this?

Nelsonnema answered 9/3, 2012 at 18:53 Comment(2)
You cannot pass a macro to the compiler, macros are evaluated by the precompiler before they reach the compiler.Moxa
Sorry for being inexact! I'm refering to MACROS passed to make conditional compilation.Nelsonnema
D
65

add_definitions(-DCOMPILE_UNIT_TESTS) (cf. CMake's doc) or modify one of the flag variables (CMAKE_CXX_FLAGS, or CMAKE_CXX_FLAGS_<configuration>) or set COMPILE_FLAGS variable on the target.

Also, identifiers that begin with an underscore followed by an uppercase letter are reserved for the implementation. Identifiers containing double underscore, too. So don't use them.

Dollarfish answered 9/3, 2012 at 19:6 Comment(5)
Can also be done from the command line a la cmake .. -DCOMPILE_UNIT_TESTSNormally
@dantswain: That sets CMake cache variable.Dollarfish
To add a definition only to specific targets, use COMPILE_DEFINITIONS. For example: set_target_properties(target1 target2 PROPERTIES COMPILE_DEFINITIONS "COMPILE_UNIT_TESTS")Novobiocin
Or target_compile_definitions in CMake 3.0Vida
Ugh ... "organically grown" build systems without uniform support across platforms are really a pain. Never know which one is the right option. Besides, how do I express undefining a preprocessor symbol?Emolument
N
22

If you have a lot of preprocessor variables to configure, you can use configure_file:

Create a configure file, e.g., config.h.in with

#cmakedefine _COMPILE_UNIT_TESTS_
#cmakedefine OTHER_CONSTANT
...

Then in your CMakeLists.txt:

set(_COMPILE_UNIT_TESTS_ ON CACHE BOOL "Compile unit tests") # Configurable by user
set(OTHER_CONSTANT OFF) # Not configurable by user
configure_file(config.h.in config.h)

In the build directory, file config.h is generated:

#define _COMPILE_UNIT_TESTS_
/* #undef OTHER_CONSTANT */

As suggested by robotik, you should add something like include_directories(${CMAKE_CURRENT_BINARY_DIR}) to your CMakeLists.txt file for #include "config.h" to work in C++.

Novobiocin answered 9/3, 2012 at 20:13 Comment(1)
@robotik suggests that you need include_directories(${PROJECT_BINARY_DIR}) or else CMake will not bea ble to find the generated config.h.Madelenemadelin

© 2022 - 2024 — McMap. All rights reserved.