Reputation: 1705
How do I force CMake's function target_include_directories()
to treat the value as an absolute path?
For example, I want this line of code:
target_include_directories(foobar PRIVATE "%FOOBAR_INCLUDE%")
to simply add %FOOBAR_INCLUDE%
to the list of include directories.
However, what we actually get is c:\path\to\foobar\%FOOBAR_INCLUDE%
.
I know that I could do
target_include_directories(foobar PRIVATE "$ENV{FOOBAR_INCLUDE}")
but that's not what I want. That would expand the value of the environment variable and insert the current setting of the FOOBAR_INCLUDE
value.
We need for it to simply push the environment variable, and then during development the developers will change the value of FOOBAR_INCLUDE
manually without having to re-run CMake each time.
Upvotes: 3
Views: 5715
Reputation: 18243
It is not possible to add something that looks like a relative directory (i.e. "%FOOBAR_INCLUDE%"
) to the include directories this way. CMake will always try to manipulate these into absolute paths. This is more-or-less stated in the include_directories
documentation:
Relative paths are interpreted as relative to the current source directory.
but applies to the target_include_directories()
command as well.
Even if you try to circumvent this, and set the INCLUDE_DIRECTORIES
property of the target manually:
set_target_properties(foobar PROPERTIES
INCLUDE_DIRECTORIES "%FOOBAR_INCLUDE%"
)
CMake will throw an error during the generation stage:
CMake Error in CMakeLists.txt:
Found relative path while evaluating include directories of "foobar":
"%FOOBAR_INCLUDE%"
You could compromise, providing a full path, but allowing the %FOOBAR_INCLUDE%
variable to stay:
target_include_directories(foobar PRIVATE "C:/%FOOBAR_INCLUDE%")
but this ties you and your fellow developers to the C: drive.
I would recommend following the approach you suggested, using an environment variable:
target_include_directories(foobar PRIVATE "$ENV{FOOBAR_INCLUDE}")
or creating a FOOBAR_INCLUDE
CMake cache variable that can be populated by each developer before they re-run CMake. If each developer's environment is different, CMake should be re-configured to match that environment.
Upvotes: 2
Reputation: 1085
You can trick CMake into accepting literal values through generator expressions
target_include_directories(foobar PRIVATE $<1:%FOOBAR_INCLUDE%>)
This, however, won't work as CMake will generate an error about the path not being absolute.
Luckily its an include directory, so therefore you can try to add the include flag manually:
target_compile_definitions(foobar PRIVATE -I%FOOBAR_INCLUDE%)
Upvotes: 1