Issue
I want to have an interface library which propagates CXX_COMPILER_LAUNCHER
to another target.
As I understood the documentation (see below) something like this should work but it doesn't.
add_library(lib INTERFACE)
set_property(TARGET lib INTERFACE_CXX_COMPILER_LAUNCHER "echo")
add_executable(main)
target_link_library(main
INTERFACE lib)
but...
get_property(_VAR TARGET main PROPERTY CXX_COMPILER_LAUNCHER)
message(FATAL_ERROR "compiler launcher: ${_VAR})
What am I doing wrong?
cmake: compatible-interface-properties
cmake: transitive-usage-requirements
EDIT: put together a minimal example and added Tsyvarevs hint. Still no success.
cmake_minimum_required(VERSION 3.18)
project(lib)
add_library(lib INTERFACE)
set_target_properties(lib PROPERTIES
INTERFACE_CXX_COMPILER_LAUNCHER "echo 'Hello, World'"
INTERFACE_C_COMPILER_LAUNCHER "echo 'Hello, World'"
)
set_property(TARGET lib APPEND PROPERTY COMPATIBLE_INTERFACE_STRING CXX_COMPILER_LAUNCHER)
set_property(TARGET lib APPEND PROPERTY COMPATIBLE_INTERFACE_STRING C_COMPILER_LAUNCHER)
add_library(main SHARED)
target_link_libraries(main
INTERFACE
lib
)
get_target_property(_VarMain main CXX_COMPILER_LAUNCHER)
get_target_property(_VarLib lib INTERFACE_CXX_COMPILER_LAUNCHER)
message(WARNING "varLib: ${_VarLib}")
message(FATAL_ERROR "varMain: ${_VarMain}")
Solution
Only a property which INTERFACE_*
counterpart is listed as known property is propagated out-of-the-box.
For tell CMake to propagate other properties, you need to add those properties into one of COMPATIBLE_INTERFACE_*
list-like properties. Selection of the list determines how the final value of the consumer's property is selected from its initial value (if it is explicitly set) and propagated values:
- COMPATIBLE_INTERFACE_BOOL requires that all values should be equal as boolean. (E.g.
TRUE
andON
are compatible values). - COMPATIBLE_INTERFACE_STRING requires that all values should be equal as string. (E.g. "FOO" and "foo" are incompatible values).
- COMPATIBLE_INTERFACE_NUMBER_MAX selects maximum from the numeric values.
- COMPATIBLE_INTERFACE_NUMBER_MIN selects minimum from the numeric values.
The other important thing: properties are propagated only at the end of configuration process. That is, the propagated value cannot be extracted via get_property
command. Instead, generator expressions should be used.
While CMake is aware about the property CXX_COMPILER_LAUNCHER, it doesn't know its INTERFACE-prefixed variant INTERFACE_CXX_COMPILER_LAUNCHER
.
Since the property has string semantic, you could add it to the COMPATIBLE_INTERFACE_STRING
list:
set_property(TARGET lib APPEND PROPERTY COMPATIBLE_INTERFACE_STRING CXX_COMPILER_LAUNCHER)
After that the property will be automatically propagated to the consumers of your library.
For observe the result of the propagation, you could add custom target with $<TARGET_PROPERTY>
generator expression:
add_custom_target(print_prop ALL
COMMAND echo "Property for main:" $<TARGET_PROPERTY:main,CXX_COMPILER_LAUNCHER>
)
so building the project (using make
) will give:
Property for main: echo
Answered By - Tsyvarev Answer Checked By - Clifford M. (WPSolving Volunteer)