Property inheritance thru target_link

I was attempting to validate my understanding of the inheritance of PROPERTYs through target link libraries. That is, I thought that if target1 was given a property and target2 linked that target, it would inherit that property, such that $<TARGET_PROPERTY:target2,property_name> would reveal that value.

Is this wrong, or is my test case simply wrong?

cmake_minimum_required (VERSION 3.17)
project (test LANGUAGES C)

add_library (l1 STATIC f1.c)
set_property (TARGET l1 PROPERTY FOO "FOO property from l1")
target_compile_definitions (l1 PUBLIC -DBAR="public Dbar from l1")
target_compile_definitions (l1 PRIVATE -DBAR="Dbar from l1")

add_library (l2 STATIC f2.c)
target_link_libraries (l2 PUBLIC l1)
target_compile_definitions (l2 PRIVATE -DFOO_L1="$<TARGET_PROPERTY:l1,FOO>")
target_compile_definitions (l2 PRIVATE -DFOO_L2="$<TARGET_PROPERTY:l2,FOO>")

add_executable (test main.c)
target_link_libraries (test l2)

what this finds is that l1,FOO resolves to a value, but l2,FOO is empty in this scenario.

f1BAR:[Dbar from l1] f2bar:[public Dbar from l1] f2foo1:[FOO property from l1] f2foo2:[]

Is this a limitation of target_compile definitions or a misunderstanding of properties?

Inheriting properties like that is not allowed. The other thing that cannot be asked is “what else has the end target used?”. These both run into the “this is false” paradox:

  • target A says “set property P”
  • target B says “link to A if property P is not set”

If target T links to B, should property P be set or not? If it is not set, it links to A and has P set. But then it should not link to A because only B said “if P is not set”.

Instead, what CMake provides are “usage requirements”: “if you link to me, here is what you must also do”. There is a post-resolution check via the COMPATIBLE_INTERFACE properties that can check for consistency, but they cannot fix an inconsistency.

1 Like