3

I want to use a value declared in my CMakeLists.txt in my C++ code. I've tried to do like that :

ADD_DEFINITIONS( -D_MYVAR=1 )

and

#if -D_MYVAR == 1
    #define var "someone"
#else
    #define var "nobody"
#endif
int main(){
    std::cout << "hello" << var << std::endl;
    return 0;
}

But it doesn't work, and I don't understand why. Maybe I don't use ADD_DEFINITIONS correctly...

Ideally, I wish do something like that :

ADD_DEFINITIONS( -D_MYVAR=\"someone\" )

and

#define var D_MYVAR

int main(){
    std::cout << "hello" << var << std::endl;
    return 0;
}

Is it possible ?

Thanks !

2

4 Answers 4

11
add_definitions ( -DVARNAME=... )

is the correct way of using add_definitions.

To check for a constant then, use

#ifdef VARNAME
...
#endif
Sign up to request clarification or add additional context in comments.

Comments

6

Thanks to πάντα ῥεῖ

His solution works for my first question, and I've could do that :

CMakeLists.txt:

ADD_DEFINITIONS( -D_VAR=\"myValue\" )

main.cpp:

#include <iostream>

#ifdef _VAR
    #define TXT _VAR
#else
    #define TXT "nobody"
#endif

int main(){
    std::cout << "hello " << TXT << " !" << std::endl;
    return 0;
}

Comments

1

As of CMake 3.12 add_definitions has been superseeded by other alternatives.

For this question, you should use add_compile_definitions in the same way you were using add_definitions:

add_compile_definitions( MY_VAR )

(note that the -D is not needed anymore).

And then in your *.cpp file:

#ifdef MY_VAR
// do something if var defined
#endif

Comments

0

Actually there is a much more elegant way to do this, that does not require to go through the C/C++ preprocessor. (I hate #ifdef...)

In CMakeLists.txt:

set( myvar "somebody" )

# Replaces occurrences of @cmake_variable@ with the variable's contents.
# Input is ${CMAKE_SOURCE_DIR}/main.cpp.in,
# output is ${CMAKE_BINARY_DIR}/main.cpp
configure_file( main.cpp.in main.cpp @ONLY )

In main.cpp.in:

#include <iostream>
int main(){
    // myvar below gets replaced
    std::cout << "hello @myvar@" << std::endl;
    return 0;
}

Note, however, that a file so configured gets saved in ${CMAKE_BINARY_DIR}, so you have to prefix it as such when listing it in the source files (as those default to ${CMAKE_SOURCE_DIR}):

add_library( myproject foo.cpp bar.cpp ${CMAKE_BINARY_DIR}/main.cpp )

3 Comments

Why you hate ifdef ? This is equivalent or maybe worse as it ties your program even more with cmake and on the other hand a definition could exist on a cpp folder ,this doesn't
@SpyrosMourelatos: And for that you necro a six-year-old answer?
@SpyrosMourelatos: I didn't say that. I said that I (pesonally) dislike #ifdef. In most Unix-ish software, #ifdef has been over-/abused to the point where it gets really hard to see which parts are actually compiled and which aren't. And half the time those #ifdef's don't actually check what the author thought they would. Also, many of the things that are #ifdef'ed (platform dependencies) usually impact linker phase / library selection as well. So why not have and handle them at one central point (CMakeLists.txt), together with e.g. version numbers, author contact info...

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.