[CMake] Undesirable behavior of TARGET_LINK_LIBRARIES()

Darrin West darrin.west at emergent.net
Wed Jun 27 21:57:46 EDT 2007


 

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.

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://public.kitware.com/pipermail/cmake/attachments/20070627/69376ae3/attachment.html


More information about the CMake mailing list