Issue
There are countless similar questions on here but I can't find one that addresses exactly this issue:
I'm using to CMake to build shared libraries a
and b
and executable prog
. prog
should be linked against a
but not against b
. However, at the same time I want prog
to be rebuilt whenever b
is outdated. In practical terms, b
is a compiler plugin used while building prog
.
I have tried:
add_library(a a.cc)
add_library(b b.cc)
add_dependencies(a b)
add_executable(prog prog.cc)
target_link_libraries(prog PRIVATE a)
But this does not work, when b
needs to be rebuilt this does not result in prog
being rebuilt as well.
I have also tried:
add_library(a a.cc)
add_library(b b.cc)
target_link_libraries(a INTERFACE b)
add_executable(prog prog.cc)
target_link_libraries(prog PRIVATE a)
But this causes prog
to be linked against b
. Is there no way to achieve this?
Solution
I see that generator expression do not work in OBJECT_DEPENDS
context. Touché. Anyway, just do a small proxy:
cmake_minimum_required(VERSION 3.11)
project(test)
add_library(a a.cpp)
add_library(b b.cpp)
add_executable(prog prog.cpp)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/b_is_build
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/b_is_build
DEPENDS $<TARGET_FILE:b>
)
set_source_files_properties(prog.cpp PROPERTIES
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/b_is_build
)
Then touching b.cpp
rebuilds prog:
+ touch b.cpp
+ cmake --build _build --verbose
[1/5] /usr/bin/c++ -MD -MT CMakeFiles/b.dir/b.cpp.o -MF CMakeFiles/b.dir/b.cpp.o.d -o CMakeFiles/b.dir/b.cpp.o -c /dev/shm/.1000.home.tmp.dir/b.cpp
[2/5] : && /usr/bin/cmake -E rm -f libb.a && /usr/bin/ar qc libb.a CMakeFiles/b.dir/b.cpp.o && /usr/bin/ranlib libb.a && :
[3/5] cd /dev/shm/.1000.home.tmp.dir/_build && /usr/bin/cmake -E touch /dev/shm/.1000.home.tmp.dir/_build/b_is_build
[4/5] /usr/bin/c++ -MD -MT CMakeFiles/prog.dir/prog.cpp.o -MF CMakeFiles/prog.dir/prog.cpp.o.d -o CMakeFiles/prog.dir/prog.cpp.o -c /dev/shm/.1000.home.tmp.dir/prog.cpp
[5/5] : && /usr/bin/c++ CMakeFiles/prog.dir/prog.cpp.o -o prog liba.a && :
b is a compiler plugin used while building prog
Ideally would be to tell CMake that object files depend on that plugin file, however $<TARGET_FILE
does not work here.
set_source_file_properties(prog.cc PROPERTIES
OBJECT_DEPENDS $<TARGET_FILE:b>
)
Or tell CMake that that linking the resulting program depends on on the plugin, depending where exactly that plugin is used.
set_target_properties(prog PROPERTIES
LINK_DEPENDS $<TARGET_FILE:b>
)
Dependencies are modeled on files - for example executable file prog
depends on file b
. add_dependencies
only does ordering (one is build before the other).
Answered By - KamilCuk