Disallowed property name when evaluating an INTERFACE library property genex with CMake 3.18
It does not seem possible to evaluate a generator expressions that queries a non INTERFACE_
property value from an INTERFACE library inside a custom command with CMake 3.18. I know, it's a mouthful.
Providing standalone project that exhibits the issue with CMake 3.18.
cmake_minimum_required(VERSION 3.18)
project(app LANGUAGES CXX)
set(helper_inc_dir "${CMAKE_CURRENT_BINARY_DIR}/subdir")
set(helper_header_file_path "${helper_inc_dir}/helper.hpp")
set(in_file_path "${CMAKE_CURRENT_BINARY_DIR}/in.hpp")
set(out_file_path "${CMAKE_CURRENT_BINARY_DIR}/header_out.o")
set(app_file_path "${CMAKE_CURRENT_BINARY_DIR}/app.cpp")
# Create helper header file provided by exported imported_helper target
file(WRITE "${helper_header_file_path}" "class Foo {};\n")
# In the real project, this is an actual exported shared library target,
# that propagates include dirs and the genex link flag which might be set
# by some consuming application.
add_library(imported_helper INTERFACE IMPORTED)
set_target_properties(imported_helper PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${helper_inc_dir}")
set_target_properties(imported_helper PROPERTIES INTERFACE_LINK_LIBRARIES "$<$<BOOL:$<TARGET_PROPERTY:USE_SPECIAL_LINK_FLAG>>:-w>")
# App that consumes imported_helper target and sets USE_SPECIAL_LINK_FLAG.
file(WRITE "${app_file_path}" "int main(){return 0;}\n")
add_executable(app "${app_file_path}")
set_target_properties(app PROPERTIES USE_SPECIAL_LINK_FLAG TRUE)
target_link_libraries(app PRIVATE imported_helper)
# Create header file that we want to check for warnings
file(WRITE "${in_file_path}" "
#include \"helper.hpp\"
int foo(Foo f);\n")
# Custom command that wants to consume the include dirs of imported_helper
set(cxx_flags ${CMAKE_CXX_FLAGS})
set(header_clean_flags -Wall -Wextra)
# Fails with CMake 3.18 <=
# Works with CMake 3.19 >=
set(include_dirs "-I$<TARGET_PROPERTY:imported_helper,INTERFACE_INCLUDE_DIRECTORIES>")
add_custom_command(
OUTPUT "${out_file_path}" DEPENDS "${in_file_path}"
COMMAND
"${CMAKE_CXX_COMPILER}"
-c ${cxx_flags}
${header_clean_flags}
${include_dirs} # <------------- include dirs from genex
-xc++ "${in_file_path}"
"-o${out_file_path}"
VERBATIM)
add_custom_target(headers_are_clean ALL DEPENDS "${out_file_path}")
Configuring with CMake 3.18 outputs:
CMake Error at CMakeLists.txt:17 (add_library):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "USE_SPECIAL_LINK_FLAG" is not allowed.
With CMake 3.19 the project configures and builds fine.
From observation, the $<$<BOOL:$<TARGET_PROPERTY:USE_SPECIAL_LINK_FLAG>>:-w>
genex is evaluated just fine in the context of an EXECUTABLE
target, because the target context for USE_SPECIAL_LINK_FLAG
is app
.
Whereas in the custom command the target context ends up being imported_lib
? and because CMake 3.18 disallows upper case property names that are not prefixed with INTERFACE_
, the configuration fails.
Renaming the property to INTERFACE_USE_SPECIAL_LINK_FLAG
doesn't really make sense, because it's meant to be set by an EXECUTABLE
target, and a INTERFACE_
named property sends the wrong message.
Renaming it to be lower cased also seems to be against CMake conventions for property names.
Is there a way out of this conundrum for CMake versions < 3.19?