CMakeLists.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. cmake_minimum_required(VERSION 3.0)
  2. project(CompatibleInterface)
  3. include(GenerateExportHeader)
  4. set(CMAKE_INCLUDE_CURRENT_DIR ON)
  5. add_library(iface1 INTERFACE)
  6. set_property(TARGET iface1 APPEND PROPERTY
  7. COMPATIBLE_INTERFACE_BOOL
  8. BOOL_PROP1
  9. BOOL_PROP2
  10. BOOL_PROP3
  11. BOOL_PROP4
  12. BOOL_PROP5
  13. )
  14. set_property(TARGET iface1 APPEND PROPERTY
  15. COMPATIBLE_INTERFACE_STRING
  16. STRING_PROP1
  17. STRING_PROP2
  18. STRING_PROP3
  19. STRING_PROP4
  20. )
  21. set_property(TARGET iface1 APPEND PROPERTY
  22. COMPATIBLE_INTERFACE_NUMBER_MIN
  23. NUMBER_MIN_PROP1
  24. NUMBER_MIN_PROP2
  25. NUMBER_MIN_PROP3
  26. NUMBER_MIN_PROP4
  27. NUMBER_MIN_PROP5
  28. NUMBER_MIN_PROP6
  29. )
  30. set_property(TARGET iface1 APPEND PROPERTY
  31. COMPATIBLE_INTERFACE_NUMBER_MAX
  32. NUMBER_MAX_PROP1
  33. NUMBER_MAX_PROP2
  34. NUMBER_MAX_PROP3
  35. NUMBER_MAX_PROP4
  36. )
  37. set(CMAKE_DEBUG_TARGET_PROPERTIES
  38. BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5
  39. STRING_PROP1 STRING_PROP2 STRING_PROP3 STRING_PROP4
  40. NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4 NUMBER_MIN_PROP5 NUMBER_MIN_PROP6
  41. NUMBER_MAX_PROP1 NUMBER_MAX_PROP2 NUMBER_MAX_PROP3 NUMBER_MAX_PROP4
  42. )
  43. set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
  44. set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
  45. set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 ON)
  46. set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
  47. set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
  48. set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP4 prop4)
  49. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
  50. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
  51. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP3 0x10)
  52. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP4 0x10)
  53. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP5 5)
  54. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP6 6)
  55. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
  56. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
  57. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP3 3)
  58. set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP4 4)
  59. add_executable(CompatibleInterface main.cpp)
  60. target_link_libraries(CompatibleInterface iface1)
  61. add_library(foo STATIC foo.cpp)
  62. add_library(bar SHARED bar.cpp)
  63. set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
  64. set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
  65. # Use LINK_ONLY to suppress usage requirements and allow the check to pass.
  66. set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:foo>)
  67. set_property(TARGET CompatibleInterface PROPERTY SOMEPROP OFF)
  68. target_link_libraries(CompatibleInterface bar)
  69. set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
  70. set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
  71. set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
  72. set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
  73. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
  74. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
  75. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xa)
  76. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP4 0x1A)
  77. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
  78. set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
  79. target_compile_definitions(CompatibleInterface
  80. PRIVATE
  81. $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
  82. $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
  83. $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
  84. $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
  85. $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
  86. $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
  87. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50>
  88. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
  89. $<$<EQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
  90. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10>
  91. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP5>,5>:NUMBER_MIN_PROP5=5>
  92. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
  93. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
  94. $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP3>,3>:NUMBER_MAX_PROP3=3>
  95. # Static libraries compute COMPATIBLE_INTERFACE_ properties transitively.
  96. $<$<BOOL:$<TARGET_PROPERTY:static1,BOOL_PROP1>>:STATIC1_BOOL_PROP1>
  97. $<$<STREQUAL:$<TARGET_PROPERTY:static1,STRING_PROP1>,prop1>:STATIC1_STRING_PROP1>
  98. $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP3>,3>:STATIC1_NUMBER_MAX_PROP3>
  99. $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP5>,5>:STATIC1_NUMBER_MIN_PROP5>
  100. # Object libraries do not compute COMPATIBLE_INTERFACE_ properties transitively.
  101. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,BOOL_PROP1>,>>:OBJECT1_BOOL_PROP1>
  102. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,STRING_PROP1>,>>:OBJECT1_STRING_PROP1>
  103. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP3>,>>:OBJECT1_NUMBER_MAX_PROP3>
  104. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP5>,>>:OBJECT1_NUMBER_MIN_PROP5>
  105. # Interface libraries do not compute COMPATIBLE_INTERFACE_ properties transitively.
  106. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,BOOL_PROP1>,>>:IFACE3_BOOL_PROP1>
  107. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,STRING_PROP1>,>>:IFACE3_STRING_PROP1>
  108. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP3>,>>:IFACE3_NUMBER_MAX_PROP3>
  109. $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP5>,>>:IFACE3_NUMBER_MIN_PROP5>
  110. # Static libraries compute COMPATIBLE_INTERFACE_ properties transitively.
  111. $<$<BOOL:$<TARGET_PROPERTY:static1,BOOL_PROP5>>:STATIC1_BOOL_PROP5>
  112. $<$<STREQUAL:$<TARGET_PROPERTY:static1,STRING_PROP4>,prop4>:STATIC1_STRING_PROP4>
  113. $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP6>,6>:STATIC1_NUMBER_MIN_PROP6>
  114. $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP4>,4>:STATIC1_NUMBER_MAX_PROP4>
  115. # Object libraries do not compute COMPATIBLE_INTERFACE_ properties transitively,
  116. # but can have properties set on them.
  117. $<$<BOOL:$<TARGET_PROPERTY:object1,BOOL_PROP5>>:OBJECT1_BOOL_PROP5>
  118. $<$<STREQUAL:$<TARGET_PROPERTY:object1,STRING_PROP4>,prop4>:OBJECT1_STRING_PROP4>
  119. $<$<EQUAL:$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP6>,7>:OBJECT1_NUMBER_MIN_PROP6>
  120. $<$<EQUAL:$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP4>,1>:OBJECT1_NUMBER_MAX_PROP4>
  121. # Interface libraries do not compute COMPATIBLE_INTERFACE_ properties transitively,
  122. # but can have properties set on them.
  123. $<$<BOOL:$<TARGET_PROPERTY:iface3,BOOL_PROP5>>:IFACE3_BOOL_PROP5>
  124. $<$<STREQUAL:$<TARGET_PROPERTY:iface3,STRING_PROP4>,prop4>:IFACE3_STRING_PROP4>
  125. $<$<EQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP6>,7>:IFACE3_NUMBER_MIN_PROP6>
  126. $<$<EQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP4>,1>:IFACE3_NUMBER_MAX_PROP4>
  127. )
  128. add_library(iface2 SHARED iface2.cpp)
  129. generate_export_header(iface2)
  130. set_property(TARGET iface2 APPEND PROPERTY
  131. COMPATIBLE_INTERFACE_STRING
  132. Iface2_PROP
  133. )
  134. # For the LINK_LIBRARIES and related properties, we should not evaluate
  135. # properties defined only in the interface - they should be implicitly zero
  136. set_property(TARGET iface2
  137. APPEND PROPERTY
  138. LINK_INTERFACE_LIBRARIES $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP4>>:nonexistent>
  139. )
  140. target_link_libraries(CompatibleInterface iface2
  141. $<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:nonexistent>
  142. )
  143. # Test that this does not segfault:
  144. target_compile_definitions(CompatibleInterface
  145. PRIVATE
  146. $<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:SOME_DEFINE>
  147. )
  148. # The COMPATIBLE_INTERFACE_* properties are only read from dependencies
  149. # in the interface. Populating it on the CompatibleInterface target does
  150. # not have any effect on the interpretation of the INTERFACE variants
  151. # in dependencies.
  152. set_property(TARGET iface1 PROPERTY
  153. INTERFACE_NON_RELEVANT_PROP ON
  154. )
  155. set_property(TARGET iface2 PROPERTY
  156. INTERFACE_NON_RELEVANT_PROP ON
  157. )
  158. set_property(TARGET CompatibleInterface APPEND PROPERTY
  159. COMPATIBLE_INTERFACE_BOOL
  160. NON_RELEVANT_PROP
  161. )
  162. add_library(static1 STATIC foo.cpp)
  163. set_property(TARGET static1 PROPERTY BOOL_PROP5 ON)
  164. set_property(TARGET static1 PROPERTY STRING_PROP4 prop4)
  165. set_property(TARGET static1 PROPERTY NUMBER_MIN_PROP6 7)
  166. set_property(TARGET static1 PROPERTY NUMBER_MAX_PROP4 1)
  167. target_link_libraries(static1 PUBLIC iface1)
  168. add_library(object1 OBJECT foo.cpp)
  169. set_property(TARGET object1 PROPERTY BOOL_PROP5 ON)
  170. set_property(TARGET object1 PROPERTY STRING_PROP4 prop4)
  171. set_property(TARGET object1 PROPERTY NUMBER_MIN_PROP6 7)
  172. set_property(TARGET object1 PROPERTY NUMBER_MAX_PROP4 1)
  173. target_link_libraries(object1 PUBLIC iface1)
  174. add_library(iface3 INTERFACE)
  175. set_property(TARGET iface3 PROPERTY BOOL_PROP5 ON)
  176. set_property(TARGET iface3 PROPERTY STRING_PROP4 prop4)
  177. set_property(TARGET iface3 PROPERTY NUMBER_MIN_PROP6 7)
  178. set_property(TARGET iface3 PROPERTY NUMBER_MAX_PROP4 1)
  179. target_link_libraries(iface3 INTERFACE iface1)
  180. # Test COMPATIBLE_INTERFACE_* property evaluation outside of usage requirements.
  181. add_custom_target(check ALL VERBATIM
  182. COMMAND CompatibleInterface
  183. # expect actual
  184. "1" "$<TARGET_PROPERTY:CompatibleInterface,BOOL_PROP1>"
  185. "prop1" "$<TARGET_PROPERTY:CompatibleInterface,STRING_PROP1>"
  186. "3" "$<TARGET_PROPERTY:CompatibleInterface,NUMBER_MAX_PROP3>"
  187. "5" "$<TARGET_PROPERTY:CompatibleInterface,NUMBER_MIN_PROP5>"
  188. "1" "$<TARGET_PROPERTY:static1,BOOL_PROP1>"
  189. "prop1" "$<TARGET_PROPERTY:static1,STRING_PROP1>"
  190. "3" "$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP3>"
  191. "5" "$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP5>"
  192. "" "$<TARGET_PROPERTY:object1,BOOL_PROP1>"
  193. "" "$<TARGET_PROPERTY:object1,STRING_PROP1>"
  194. "" "$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP3>"
  195. "" "$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP5>"
  196. "" "$<TARGET_PROPERTY:iface3,BOOL_PROP1>"
  197. "" "$<TARGET_PROPERTY:iface3,STRING_PROP1>"
  198. "" "$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP3>"
  199. "" "$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP5>"
  200. "ON" "$<TARGET_PROPERTY:static1,BOOL_PROP5>"
  201. "prop4" "$<TARGET_PROPERTY:static1,STRING_PROP4>"
  202. "6" "$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP6>"
  203. "4" "$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP4>"
  204. "ON" "$<TARGET_PROPERTY:object1,BOOL_PROP5>"
  205. "prop4" "$<TARGET_PROPERTY:object1,STRING_PROP4>"
  206. "7" "$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP6>"
  207. "1" "$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP4>"
  208. "ON" "$<TARGET_PROPERTY:iface3,BOOL_PROP5>"
  209. "prop4" "$<TARGET_PROPERTY:iface3,STRING_PROP4>"
  210. "7" "$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP6>"
  211. "1" "$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP4>"
  212. )