1 2cmake_minimum_required(VERSION 2.8.12) 3 4project(TargetIncludeDirectories) 5 6macro(create_header _name) 7 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}") 8 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "/* ${_name}.h */\n") 9endmacro() 10 11create_header(bar) 12create_header(bat) 13create_header(foo) 14create_header(baz) 15create_header(bang) 16create_header(bing) 17create_header(bung) 18create_header(arguments) 19create_header(list) 20create_header(target1) 21create_header(target2) 22 23set(CMAKE_INCLUDE_CURRENT_DIR ON) 24 25include_directories("${CMAKE_CURRENT_BINARY_DIR}/bar") 26include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/bang>") 27 28add_executable(TargetIncludeDirectories main.cpp) 29 30set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bat") 31set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo") 32set_property(TARGET TargetIncludeDirectories APPEND PROPERTY 33 INCLUDE_DIRECTORIES "$<1:${CMAKE_CURRENT_BINARY_DIR}/bing>") 34 35include_directories("${CMAKE_CURRENT_BINARY_DIR}/baz") 36include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/bung>") 37include_directories("sing$<1:/ting>") 38 39include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/arguments;${CMAKE_CURRENT_BINARY_DIR}/list>") 40 41create_header(fee) 42create_header(fiy) 43create_header(foh) 44create_header(fum) 45 46file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp" "#include \"fee.h\"\n") 47add_library(lib1 "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp") 48set_property(TARGET lib1 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fee") 49set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy") 50set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${CMAKE_CURRENT_BINARY_DIR}/foh>") 51 52file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp" "#include \"fiy.h\"\n") 53add_library(lib2 "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp") 54set_property(TARGET lib2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fum;$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>") 55set_property(TARGET lib2 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>") 56 57file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n#include \"fum.h\"\nint main(int,char**) { return 0; }\n") 58add_executable(exe3 "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp") 59set_property(TARGET exe3 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib2,INTERFACE_INCLUDE_DIRECTORIES>") 60 61# Test cycles 62file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n") 63add_library(lib3 "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp") 64set_property(TARGET lib3 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$<TARGET_PROPERTY:lib4,INTERFACE_INCLUDE_DIRECTORIES>") 65set_property(TARGET lib3 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$<TARGET_PROPERTY:lib4,INTERFACE_INCLUDE_DIRECTORIES>") 66 67file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n") 68add_library(lib4 "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp") 69set_property(TARGET lib4 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>") 70set_property(TARGET lib4 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>") 71 72add_library(somelib::withcolons UNKNOWN IMPORTED) 73set_property(TARGET somelib::withcolons PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/target1") 74set_property(TARGET somelib::withcolons PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/target1") 75 76set_property(TARGET TargetIncludeDirectories 77 APPEND PROPERTY INCLUDE_DIRECTORIES 78 "$<TARGET_PROPERTY:somelib::withcolons,INTERFACE_INCLUDE_DIRECTORIES>" 79) 80 81add_library(somelib_aliased UNKNOWN IMPORTED GLOBAL) 82set_property(TARGET somelib_aliased PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/target2") 83add_library(somelib::withcolons2 ALIAS somelib_aliased) 84 85set_property(TARGET TargetIncludeDirectories 86 APPEND PROPERTY INCLUDE_DIRECTORIES 87 "$<TARGET_PROPERTY:somelib::withcolons2,INTERFACE_INCLUDE_DIRECTORIES>" 88) 89 90add_custom_target(test_custom_target 91 "some_bogus_custom_tool" 92 $<TARGET_PROPERTY:TargetIncludeDirectories,COMPILE_DEFINITIONS> 93 WORKING_DIRECTORY 94 "${CMAKE_CURRENT_SOURCE_DIR}") 95 96file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bad") 97file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bad/common.h" "#error Should not be included\n") 98file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/good") 99file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/good/common.h" "#include \"othergood.h\"\n") 100file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/othergood") 101file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "/* No error */\n") 102 103file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp" "// No content \n") 104add_library(libothergood "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp") 105set_property(TARGET libothergood APPEND PROPERTY 106 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/othergood" 107) 108 109file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp" "// No content \n") 110add_library(libgood "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp") 111set_property(TARGET libgood APPEND PROPERTY 112 INTERFACE_INCLUDE_DIRECTORIES 113 "${CMAKE_CURRENT_BINARY_DIR}/good;$<TARGET_PROPERTY:libothergood,INTERFACE_INCLUDE_DIRECTORIES>" 114) 115 116file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp" "// No content \n") 117add_library(libbad "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp") 118set_property(TARGET libbad APPEND PROPERTY 119 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bad" 120) 121 122add_library(lib6 SHARED other.cpp) 123add_library(lib7 SHARED other.cpp) 124target_link_libraries(lib7 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:lib6>) 125target_include_directories(lib7 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:/lib7/include>) 126add_custom_target(head_target_test "some_bogus_custom_tool \"$<TARGET_PROPERTY:lib7,INCLUDE_DIRECTORIES>$<TARGET_PROPERTY:lib7,INTERFACE_INCLUDE_DIRECTORIES>\"") 127 128add_library(includes_source_good empty.cpp) 129target_include_directories(includes_source_good 130 INTERFACE 131 "${CMAKE_CURRENT_BINARY_DIR}/good" 132 "${CMAKE_CURRENT_BINARY_DIR}/othergood/" 133) 134add_library(includes_source_bad empty.cpp) 135target_include_directories(includes_source_bad 136 INTERFACE 137 "${CMAKE_CURRENT_BINARY_DIR}/bad" 138) 139 140add_library(includes_proxy SHARED empty.cpp) 141target_link_libraries(includes_proxy includes_source_good) 142target_link_libraries(includes_proxy LINK_INTERFACE_LIBRARIES includes_source_bad) 143add_executable(copy_includes copy_includes.cpp) 144target_include_directories(copy_includes PRIVATE $<TARGET_PROPERTY:includes_proxy,INCLUDE_DIRECTORIES>) 145 146 147file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n") 148add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp") 149 150# Assuming the link order must be: 151target_link_libraries(lib5 libbad libgood) 152 153# Oops!. 154# As include directory order and link order are the same when using target_link_libraries, we have to 155# get the libgood includes in before the libbad includes. 156# We do that with this command: 157target_include_directories(lib5 158 BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES> 159) 160 161file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat") 162file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "/* prefix_foo_bar_bat.h */\n") 163 164target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>") 165 166# Test that the language generator expressions work 167set_property(TARGET TargetIncludeDirectories 168 APPEND PROPERTY INCLUDE_DIRECTORIES 169 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:${CMAKE_CURRENT_BINARY_DIR}/bad>" 170 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:${CMAKE_CURRENT_BINARY_DIR}/good>" 171 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:${CMAKE_CURRENT_BINARY_DIR}/othergood/>" 172) 173 174add_executable(TargetIncludeDirectories_C main.c) 175set_property(TARGET TargetIncludeDirectories_C 176 APPEND PROPERTY INCLUDE_DIRECTORIES 177 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:${CMAKE_CURRENT_BINARY_DIR}/bad>" 178 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:${CMAKE_CURRENT_BINARY_DIR}/good>" 179 "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:${CMAKE_CURRENT_BINARY_DIR}/othergood/>" 180) 181