<div dir="ltr"><div class="gmail_quote"><div dir="ltr">Dear CMake users,<div><br></div><div>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.</div><div><br></div><div>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).</div><div><br></div><div>Here is a toy example taken from the manual:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>add_library(archive archive.cpp)</div></div><div><div>target_compile_definitions(archive PUBLIC USING_ARCHIVE_LIB)</div></div><div><div><br></div></div><div><div>add_library(serialization serialization.cpp)</div></div><div><div>target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB)</div></div><div><div><br></div></div><div><div>add_library(archiveExtras extras.cpp)</div></div><div><div>target_link_libraries(archiveExtras PUBLIC archive)</div></div><div><div>target_link_libraries(archiveExtras PRIVATE serialization)</div></div><div><div># archiveExtras is compiled with -DUSING_ARCHIVE_LIB</div></div><div><div># and -DUSING_SERIALIZATION_LIB</div></div><div><div><br></div></div><div><div>add_executable(consumer consumer.cpp)</div></div><div><div># consumer is compiled with -DUSING_ARCHIVE_LIB</div></div><div><div>target_link_libraries(consumer archiveExtras)</div></div></blockquote><div><br></div><div>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:<br></div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>foreach (lib archive serialization archiveExtras consumer)</div></div><div><div>  get_property(ill TARGET ${lib} PROPERTY INTERFACE_LINK_LIBRARIES)</div></div><div><div>  get_property(ll TARGET ${lib} PROPERTY LINK_LIBRARIES)</div></div><div><div>  get_property(icd TARGET ${lib} PROPERTY INTERFACE_COMPILE_DEFINITIONS)</div></div><div><div>  get_property(cd TARGET ${lib} PROPERTY COMPILE_DEFINITIONS)</div></div><div><div>  message(STATUS "${lib}: INTERFACE_LINK_LIBRARIES = \"${ill}\" "</div></div><div><div>    "LINK_LIBRARIES = \"${ll}\"")</div></div><div><div>  message(STATUS "${lib}: INTERFACE_COMPILE_DEFINITIONS = \"${icd}\" "</div></div><div><div>    "COMPILE_DEFINITIONS = \"${cd}\"")</div></div><div><div>endforeach()</div></div></blockquote><div><br></div><div>I can see that archiveExtras inherits the link libraries of archive, <b>but not its compile_definitions</b> (nor the include directories if I try to inherit them instead):</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>-- archive: INTERFACE_LINK_LIBRARIES = "" LINK_LIBRARIES = ""</div><div>-- archive: INTERFACE_COMPILE_DEFINITIONS = "USING_ARCHIVE_LIB" COMPILE_DEFINITIONS = "USING_ARCHIVE_LIB"<br></div></div><div><div><br></div><div>-- serialization: INTERFACE_LINK_LIBRARIES = "" LINK_LIBRARIES = ""</div><div>-- serialization: INTERFACE_COMPILE_DEFINITIONS = "USING_SERIALIZATION_LIB" COMPILE_DEFINITIONS = ""</div><div>                                </div></div><div><div>-- archiveExtras: INTERFACE_LINK_LIBRARIES = "archive;$<LINK_ONLY:serialization>" LINK_LIBRARIES = "archive;serialization"</div></div><div><div>-- archiveExtras: INTERFACE_COMPILE_DEFINITIONS = "" COMPILE_DEFINITIONS = ""</div></div><div><br></div><div><div>-- consumer: INTERFACE_LINK_LIBRARIES = "archiveExtras" LINK_LIBRARIES = "archiveExtras"</div></div><div><div>-- consumer: INTERFACE_COMPILE_DEFINITIONS = "" COMPILE_DEFINITIONS = ""</div></div></blockquote><div><br></div><div>The COMPILE_DEFINITIONS of archiveExtras is empty; it has not inherited anything. </div><div><br></div><div>The manual says:</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">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...<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">"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."</blockquote><div><br></div><div>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).</div><div><br></div><div>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?</div><div><br></div><div>Thanks in advance, Chris.</div><div><br></div></div>
</div><br></div>