Yakov Galka
Yakov Galka

Reputation: 72449

How can I define a C++ preprocessor macro through the command line with CMake?

I try to set a preprocessor macro in the command line of CMake. I've tried:

set generator="Visual Studio 8 2005"
set params=-D MY_MACRO=1
cmake.exe -G %generator% %params% ..\some_project

but it's neither defined when I compile nor can I find the name MY_MACRO in the files generated by CMake at all, except for CMakeCache.txt where it's present in the form:

MY_MACRO:UNINITIALIZED=1

How can I do it?

Upvotes: 74

Views: 83735

Answers (5)

freitass
freitass

Reputation: 6694

A good alternative would be to define a CMake option:

OPTION(DEFINE_MACRO "Option description" ON) # Enabled by default

Followed by a condition:

IF(DEFINE_MACRO)
    ADD_DEFINITIONS(-DMACRO)
ENDIF(DEFINE_MACRO)

Then you can turn that option ON/OFF via the command line with CMake using the -D flag. Example:

cmake -DDEFINE_MACRO=OFF ..

To make sure the compiler is receiving the definition right, you can call make in verbose mode and check for the macro being defined or not:

make VERBOSE=1

This is a good solution also because make will recompile your code when any of CMake options changes.

Upvotes: 41

Alex Che
Alex Che

Reputation: 7112

One more way is to use the documented CXXFLAGS environment variable. This environmental variable is used to initialize CMAKE_CXX_FLAGS cache entry, so it needs to be used when first generating build files, and if you then need to change the CXXFLAGS value, then you'll need to regenerate the build files again.

E.g.:

# CD to the build directory
cd <build_dir>

# Clean the build files including cmake cache
rm -rf *

# Generate build files with the CMAKE_CXX_FLAGS containing our MYMACRO define
CXXFLAGS=-DMYMACRO cmake <source_dir>

# Build the project with the MYMACRO being defined 
cmake --build .

Upvotes: 2

Yakov Galka
Yakov Galka

Reputation: 72449

The motivation behind the question was to batch build 3rd party libraries, which is why I wanted to avoid modifying CMakeLists. So years later, even though I don't need that anymore, I figured out that it's easily achievable by means external to CMake:

  • Invoke CMake as usual, no special flags.

  • Then:

    • With MSVC: The compiler reads the CL environment variable to get extra command line arguments. So

        set CL=/DMY_MACRO=1 %CL%
      

      then invoke MSBuild to do its job.

    • With Makefiles: The generated makefiles use the CFLAGS and CXX_FLAGS variables as makefiles are expected to do. So the build can be started by

        make CXX_FLAGS=-DMY_MACRO=1
      

      or by setting the corresponding environment variables.

Upvotes: 27

hiobs
hiobs

Reputation: 636

Unless you have a good reason not to, you should use ADD_DEFINITIONS(<name>=<value>[, ...]).

Just add the following line to your CMakeLists.txt:

ADD_DEFINITIONS("MY_MACRO=1")

CMake will take care of the syntax of the switches (be it -D<name>=<value>, or /D<name>=<value>).

Upvotes: -8

SlavaNov
SlavaNov

Reputation: 2485

Try this: -D CMAKE_CXX_FLAGS=/DMY_MACRO=1

Upvotes: 24

Related Questions