80

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?

4
  • 2
    If you solved this by now I would be interested in the solution Commented Mar 2, 2012 at 10:03
  • 1
    @ybungalobill: You can't inject macros from the commandline, you can only modify existing macros that are defined in CMakeLists.txt. Also, set params=-D MY_MACRO=1 should be set params=-DMY_MACRO=1 Commented Jan 8, 2018 at 8:57
  • 1
    @TimMeyer: yes, see my answer below. Commented Apr 7, 2019 at 22:45
  • @ybungalobill I was interested 7 years ago ;) Thanks for providing an answer anyway, I'm sure it will help many others. Commented Apr 8, 2019 at 20:23

5 Answers 5

45

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.

Sign up to request clarification or add additional context in comments.

4 Comments

This requires modifications of the CMakeLists, so it's not a solution (-1).
@YakovGalka not entierly true, he suggest to change the CmakeLists.txt prior, so the macro can be defined/undefined at subsequent builds. Agree it doesn't provide mose flexiblity, but for most use-cases it is what people need.
One can use add_compile_definitions instead of add_definitions. See define preprocessor macro through cmake.
I've tried to setup my project like this, and I'm not sure why, it keeps on failing with Unknown argument -DDEFINE_MACRO=0 ; Usage: cmake --build <dir> [options] [-- [native-options]]
30

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.

2 Comments

This is a good workaround for command line building but I'd also want users to be able to open the generated solution file with the IDE in which case this wouldn't work. It's a pity that even in 2020 there's no way to add to CMAKE_CXX_FLAGS rather than specifying (overwriting) them.
After stumbling on this problem, I found that cmake -E env CXXFLAGS="-DMY_MACRO" cmake SourcePath works in my case (src: stackoverflow.com/a/44357387/1666181). Not sure though if this would override completely too.
25

Try this: -D CMAKE_CXX_FLAGS=/DMY_MACRO=1

5 Comments

It half works indeed. It overwrites the value of CMAKE_CXX_FLAGS. I've tried -D CMAKE_CXX_FLAGS="/DMY_MACRO=1 ${CMAKE_CXX_FLAGS}" but ${CMAKE_CXX_FLAGS} is not get expanded. Anyone knows how to fix this?
Double-quoted strings on the command line will be expanded by bash. Since you have no environment variable named CMAKE_CXX_FLAGS, bash expands it to "", before cmake even sees it. Use single quotes instead.
@Tolli that doesn't seem to work either. It prevents bash from expanding the variable, but cmake doesn't expand it either. It passes the literal value /DMY_MACRO=1 ${CMAKE_CXX_FLAGS} directly to the compiler.
@Tolli: I didn't run it on bash. Not all the world is bash.
` -DCMAKE_CXX_FLAGS:="-D_GLIBCXX_USE_CXX11_ABI=0 -DTSI_OPENSSL_ALPN_SUPPORT=0"` seems work for me
2

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 .

Comments

-8

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>).

3 Comments

modifying CMakeLists.txt doesn't count as a command-line solution. And yes, I have a good reason to not do this. I have to automate the build process, and I should not change the sources.
Sorry about the space; I wanted to add a commandline solution, but it wasn't quite what you were looking for. Nonetheless, doing it from the commandline is only going to make your day miserable, trust me.
Sometimes the commandline is more useful than a gui application and sometimes not. I really don't think that you can say that this will make your day miserable, as it really depends on the situation, skill of the user, and personal preference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.