Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File path with cmake add_definitions

I am trying to replace a hard coded preprocessor

#define MY_FILE_PATH "/usr/local/myfile"

with add_definitions in cmake

add_definitions(-DMY_FILE_PATH=${MY_FILE_PATH})

and while calling cmake I use -DMY_FILE_PATH=/usr/tmp/myfile but get all kind of errors e.g., expected primary expression before '/' token and tmp not find etc. Is it possible to use add_definitions in my scenario or should I try configure_file. Does add_definitions only supports integer values?

like image 923
user1566277 Avatar asked Oct 05 '15 11:10

user1566277


People also ask

What does Add_definitions do in Cmake?

Add -D define flags to the compilation of source files. Adds definitions to the compiler command line for targets in the current directory, whether added before or after this command is invoked, and for the ones in sub-directories added after.


2 Answers

None of the answers here and from googling the internet worked for me (CMake 3.4.1 on Windows). I've finally found a solution, so here you go, hope this helps someone:

The trick is to quote the whole content of each definition you want to add with add_definitions, not just the value part of it, and escape the inner quotes which will go to the shell. Remember that each definition should consist a separate string. Like this:

add_definitions( "-D_SOME_DEFINE=\"Some value with spaces, etc\"" "-D DEF1=\"Another string\"")

The answer isn't restrained to paths only, but is applicable to any general string you want to supply as a preprocessor directive. It is the only way I was able to supply a string containing space characters.

like image 159
Roman Kruglov Avatar answered Oct 17 '22 09:10

Roman Kruglov


Don't use add_definitions; it is deprecated as of CMake 3.12. Use target_compile_definitions instead. This code works as far back as CMake 3.0.

cmake_minimum_required(VERSION 3.0)
project(example)

set(MY_FILE_PATH "/usr/local/myfile")

add_executable(main main.cpp)
target_compile_definitions(main PRIVATE "MY_FILE_PATH=\"${MY_FILE_PATH}\"")

If main.cpp contains:

#include <cstdio>

int main () { std::puts(MY_FILE_PATH); }

Then we get the following interaction:

dev@host:~/example$ cmake -S . -B build
...
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dev/example/build
dev@host:~/example$ cmake --build build/
...
[100%] Built target main
dev@host:~/example$ ./build/main
/usr/local/myfile

Though it is always preferred to use target properties, if you must absolutely use a directory property, the function replacing add_definitions is add_compile_definitions. You could call it like so:

add_compile_definitions("MY_FILE_PATH=\"${MY_FILE_PATH}\"")
like image 24
Alex Reinking Avatar answered Oct 17 '22 10:10

Alex Reinking