Dear CMake users, I'm trying to use CMake to replace the complex hand-built Visual Studio configuration of our open source project, Box Backup. And I'm having trouble making it generate the correct transitive dependencies between modules, particularly for include directories.
We have a lot of modules whose header files need to be part of the public interface to link to these modules. I thought from the manual that "The usage requirements of a target can transitively propagate to dependents" but I can't make it work (for anything except link libraries). Here is a toy example taken from the manual: add_library(archive archive.cpp) target_compile_definitions(archive PUBLIC USING_ARCHIVE_LIB) add_library(serialization serialization.cpp) target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB) add_library(archiveExtras extras.cpp) target_link_libraries(archiveExtras PUBLIC archive) target_link_libraries(archiveExtras PRIVATE serialization) # archiveExtras is compiled with -DUSING_ARCHIVE_LIB # and -DUSING_SERIALIZATION_LIB add_executable(consumer consumer.cpp) # consumer is compiled with -DUSING_ARCHIVE_LIB target_link_libraries(consumer archiveExtras) My understanding is that the target_compile_definitions are part of the public interface of the archive module, and should be added to anything that links to it, which archiveExtras does. But if I add some debugging messages after the above code: foreach (lib archive serialization archiveExtras consumer) get_property(ill TARGET ${lib} PROPERTY INTERFACE_LINK_LIBRARIES) get_property(ll TARGET ${lib} PROPERTY LINK_LIBRARIES) get_property(icd TARGET ${lib} PROPERTY INTERFACE_COMPILE_DEFINITIONS) get_property(cd TARGET ${lib} PROPERTY COMPILE_DEFINITIONS) message(STATUS "${lib}: INTERFACE_LINK_LIBRARIES = \"${ill}\" " "LINK_LIBRARIES = \"${ll}\"") message(STATUS "${lib}: INTERFACE_COMPILE_DEFINITIONS = \"${icd}\" " "COMPILE_DEFINITIONS = \"${cd}\"") endforeach() I can see that archiveExtras inherits the link libraries of archive, *but not its compile_definitions* (nor the include directories if I try to inherit them instead): -- archive: INTERFACE_LINK_LIBRARIES = "" LINK_LIBRARIES = "" -- archive: INTERFACE_COMPILE_DEFINITIONS = "USING_ARCHIVE_LIB" COMPILE_DEFINITIONS = "USING_ARCHIVE_LIB" -- serialization: INTERFACE_LINK_LIBRARIES = "" LINK_LIBRARIES = "" -- serialization: INTERFACE_COMPILE_DEFINITIONS = "USING_SERIALIZATION_LIB" COMPILE_DEFINITIONS = "" -- archiveExtras: INTERFACE_LINK_LIBRARIES = "archive;$<LINK_ONLY:serialization>" LINK_LIBRARIES = "archive;serialization" -- archiveExtras: INTERFACE_COMPILE_DEFINITIONS = "" COMPILE_DEFINITIONS = "" -- consumer: INTERFACE_LINK_LIBRARIES = "archiveExtras" LINK_LIBRARIES = "archiveExtras" -- consumer: INTERFACE_COMPILE_DEFINITIONS = "" COMPILE_DEFINITIONS = "" The COMPILE_DEFINITIONS of archiveExtras is empty; it has not inherited anything. The manual says: Because archive is a PUBLIC dependency of archiveExtras, the usage > requirements of it are propagated to consumer too. Because serialization is > a PRIVATE dependency of archive, the usage requirements of it are not > propagated to consumer... > "Usage requirements are propagated by reading the INTERFACE_ variants of > target properties from dependencies and appending the values to the > non-INTERFACE_ variants of the operand. For example, the > INTERFACE_INCLUDE_DIRECTORIES of dependencies is read and appended to the > INCLUDE_DIRECTORIES of the operand." I would assume that the same happens for COMPILE_DEFINITIONS: it should be copied from the INTERFACE_COMPILE_DEFINITIONS of the dependencies. But this doesn't appear to be happening, as far as I can tell. Nor is the "consumer compiled with -DUSING_ARCHIVE_LIB", contrary to the comment (at least it's not in the COMPILE_DEFINITIONS). Can anyone tell me what I'm doing wrong? Specifiying "dependencies" the wrong way? I would really appreciate some help :) Do I have to hard-code or script all the transitive dependencies myself, or is there something I'm missing? Thanks in advance, Chris.
-- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake