It seems to me that TARGET_LINK_LIBRARIES and ADD_DEPENDENCIES are "poorly" defined, and lead to problems. I think the fix is "easy", but might not be popular.
My comments might be related to the following question in the FAQ: http://www.cmake.org/Wiki/CMake_FAQ#Why_are_libraries_linked_to_my_shared_lib rary_included_when_something_links_to_it.3F The use case I'm considering is one that happens in Visual Studio 8, when constructing dll's. We have two projects, one is the application (App.exe), the other is a dll (Util.dll). I want to statically link a library into Util, say helper.lib. Let's say helper.lib is from third party SDK. There is a problem if you naïvely do this using TARGET_LINK_LIBRARIES between Util.dll to helper.lib, and again between App.exe and Util.dll. helper.lib is appended to the list of libraries used to link App.exe. cmake links App.exe with both Util.dll and helper.lib. This recursive expansion of referenced libraries is "undesirable behavior", since Util.dll was fully resolved. It means one thing to say that App.exe links to Util.dll. And another thing to say that App.exe links to both Util.dll and helper.lib. For example, there may be a symbol in helper.lib that was not referenced by Util.dll. If App.exe uses that symbol, in one case it will be unresolved, and in the other case, it will be pulled out of helper.lib. Another way of saying that is that App.exe may declare a symbol that is not in Util.dll, but is in helper.lib. In some cases, the undesirable behavior of cmake would result in a duplicate symbol, and failure to link. We understand that the build of App.exe is dependent transitively on helper.lib's build. But I don't think helper.lib should be automatically appended to App.exe's list of input libraries. If we change the behavior of cmake to not do that appending, what are the consequences? We can rely on make or dev studio's transitive dependency system, to ensure all the projects are built in the correct order. In legacy cases where the full library list was relied upon to get an app fully linked, we would now see failures. And that lack of backward compatibility might be too hard to get past from a product evolution perspective. I'm not sure how to answer that question. Perhaps having a site-wide switch that reverts to the legacy behavior? For those of us that care about the subtle difference, could we use ADD_DEPENDENCY instead? While (as we desire) that doesn't explicitly flatten all the dependencies, it also must not be changed to implicitly also link a target's build product. That doesn't make sense if the project runs yacc, or sends an email. So a third alternative is needed. Perhaps DIRECT_LINK_LIBRARIES. It would append only the explicitly and directly mentioned .libs, or .dll's to the link command, but would also ensure that all the dependencies recursively are respected. For make and dev studio, this shouldn't be any extra work, because they already do the dependency analysis recursively. In cases where extra symbols from helper.lib, or where its header files were really needed by App.exe, helper.lib would have to be added as an explicit DIRECT_LINK_LIBRARIES entry, even though Util.dll had also done so. We might worry about getting duplicate singletons (one in Util.dll, one in App.exe) from helper.lib. But that is a possibility whenever one uses dll's. If it is a concern, or would cause a bug, you simply cannot link the same lib into multiple link modules. There are ways to avoid this. Just to round out the thinking on this, another inconvenience of the existing undesirable cmake behavior is that the path to helper.lib has to be available to App.exe, even if it won't need any of its symbols. helper.lib is on the link line (where it shouldn't be), and the linker insists on finding it, or it fails. That means the location of helper.lib has to be added to LINK_DIRECTORIES for App.exe. Even when App.exe doesn't use helper.lib, and might not even know it was add to Util.dll. Should LINK_DIRECTORIES be automatically transitively inherited just like TARGET_LINK_LIBRARIES? What about INCLUDE_DIRECTORIES? We would need to determine whether "unexpected" headers and library search paths would add to the complexity, or help. Darrin West Emergent Game Technologies.
_______________________________________________ CMake mailing list [email protected] http://www.cmake.org/mailman/listinfo/cmake
