target_include_directories improperly prepends path when generator expression argument contains absolute paths separated by a space or semicolon.
CMake version: 3.11.1
Platform: GNU/Linux
Generators: Unix Makefiles, Ninja
Summary
Given the command
target_include_directories(x PRIVATE $<1:/tmp/example/inc1 /tmp/example/inc2>)
the expected behaviour is that the two absolute paths /tmp/example/inc1
and /tmp/example/inc2
are added to the include directories for the target x
. Observed behaviour is that these paths have the current source directory prepended to them.
Example
% cd /tmp/example
% cat CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(example LANGUAGES C)
add_executable(x x.c)
target_include_directories(x PRIVATE $<1:/tmp/example/inc1 /tmp/example/inc2>)
get_target_property(includes x INCLUDE_DIRECTORIES)
message(STATUS "${includes}")
% mkdir b; (cd b; cmake ..)
-- The C compiler identification is GNU 8.1.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- /tmp/example/$<1:/tmp/example/inc1;/tmp/example/inc2>
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/example/b
%
This correspondingly generates the wrong include path for the target:
% (cd b; make VERBOSE=1 x)
[...]
[50%] Building C object CMakeFiles/x.dir/x.c.o
/usr/bin/cc -I/tmp/example/tmp/example/inc1 -I/tmp/example/inc2 -o CMakeFiles/x.dir/x.c.o -c /tmp/example/x.c
Using the Ninja generator similarly gives an incorrect include path.
Workaround
For paths given explicitly, a workaround is to use a separate generator expression for each; for a list of paths given in a variable, it appears necessary to use foreach
, e.g.
foreach(p ${include-dirs})
target_include_directories(x PRIVATE $<1:${p}>)
endforeach()