While I have been working for target_include_directories
, I have noticed it would be smarter that interfaces of compilation may be propagated as PUBLIC
.
OTOH, PUBLIC
shall break CMAKE_LINK_WHAT_YOU_USE
in BUILD_SHARED_LIBS
.
I propose a few compatible options for this.
Introduce “direct link only for SHARED and EXECUTABLE”
- Don’t use
target_link_libraries(PUBLIC)
by default. - Use
$<COMPILE_ONLY>
for SHARED libs.$<COMPILE_ONLY>
will be introduced in the next release of CMake.- I can emulate it with a weird genex.
add_library(foo SHARED) target_link_libraries(foo PRIVATE bar) target_link_libraries(foo INTERFACE $<IF:$<BOOL:$<LINK_ONLY:1>>:,,bar>
- Use
INTERFACE/PUBLIC
for STATIC.
Introduce the rule to propagate PUBLIC INTERFACE libs
- Define
add_library(INTERFACE)
for PUBLIC interfaces. Assume tablegen targets. - Propagate INTERFACE libs manually to traverse dependents in
AddLLVM.cmake
.- Re-add INTERFACE libs manually as PUBLIC/INTERFACE
Background
When I was playing CMake a decade years ago, target_link_libraries(PUBLIC)
behaved messily. I introduced target_link_libraries(INTERFACE)
to avoid such messiness.
I supposed then I could maintain complexity due to INTERFACE. (Sorry I had abandoned for long time)
For several years, CMake has been improved.
- Isolate dependencies between compilation and linking (3.9)
- Introduce
CMAKE_OPTIMIZE_DEPENDENCIES
(3.19)
Then I concluded we could use PRIVATE.
That said, I strongly disagree introducing PUBLIC unconditionally, due to the reason for SHARED, above.