[CMake] Obtaining dependencies of static libraries

Philip Lowman philip at yhbt.com
Sun Jan 25 10:25:31 EST 2009


On Fri, Jan 23, 2009 at 3:37 PM, Robert Dailey <rcdailey at gmail.com> wrote:

> On Fri, Jan 23, 2009 at 3:36 AM, Mike Arthur <mike at mikearthur.co.uk>wrote:
>
>> On Thursday 22 January 2009 23:26:47 Robert Dailey wrote:
>> > With all do respect, why does it matter? Yes, in the generated target
>> > dependencies are handled for me but when I call get_target_property()
>> with
>> > LINK_INTERFACE_LIBRARIES it only includes the dependencies I specific
>> for
>> > only that executable target, it does not provide me the transitive
>> > dependencies. This is a problem for me.
>>
>> It matters because:
>> a) You're asking for help on a list of mostly volunteers so sometimes we
>> ask
>> why you're doing something so we can direct you if you've just missed
>> something in CMake.
>> b) You may have uncovered a bug in CMake and we'd like to help make CMake
>> better than it is.
>
>
> Most of the time it is extremely difficult or impossible to express my tone
> of voice through text. I did not mean for my initial question to sound rude,
> but if it seemed that way I do apologize. I'm used to the case where people
> ask "Why are you doing that in the first place" and when I respond they
> usually retaliate with rude remarks, like "You're doing that completely
> wrong and it's evil". So I make every effort to avoid such questions because
> of this.
>
> In any case, the reason why I'm doing this is rather complicated and I
> could spend a few paragraphs explaining it. However if you are really
> interested in knowing I don't mind explaining:
>
> For my specific project, I keep all of my third party dependencies
> versioned with the source code. So I may have a directory called
> "project/source", that contains all of my source code, and a directory named
> "project/third_party" which contains various third party libraries. Using
> the Boost library as an example on the Windows platform, we would have
> import libraries located here:
>
> "project/third_party/boost/libs/<lib files here>"
>
> In the same directory that the import libraries (LIB) files are located in,
> we also have the shared library files (DLL). We group them like this because
> we want CMake to be able to get a list of import library dependencies and
> simply replace the extension with DLL in order to find the corresponding
> shared library so that we may copy those DLL files to the binary output
> directory, which would be "CMAKE_BINARY_DIR/bin/<configuration>".
>
> However, this situation gets a little more complex. Suppose I have 3
> projects: A, B, and C. Projects A and B are defined as static library
> projects in CMake and both A and B have had target_link_libraries() called
> on them to place dependencies on various boost import libraries. Project C
> is an executable project and it has had the following called on it:
>
> target_link_libraries( C A B <more boost libraries> )
>
> Since project C now links against A and B, we need to ensure that the
> executable generated by building project C is able to find the DLL files
> required by projects A, B, and C itself. Because of this, I need to be able
> to "recursively" find all of the import library dependencies for project C
> (Which if done correctly would provide a list of library dependencies of A
> and B as well).
>
> Once I have this "flattened" list of dependencies, I replace all the *.LIB
> extensions with *.DLL (On windows) and copy those DLL files to the location
> of the executable!
>
> Because this problem is so complex, I avoided explaining it to begin with
> to save some trouble.


Sorry, I don't have the answer to your question but I thought I'd share the
way we solved a similar problem at work in case you can't figure out a way
to do it the way you want.

At work we simply add the DLL files manually to one of several lists.  We
use one list for MSVC Debug builds, one for MSVC Release builds, and one for
MinGW builds.  Then at the bottom of our toplevel CMakeLists.txt we call a
macro to have these DLL files copied to the build tree.  It's not exactly
elegant but it gets the job done.

Many of our 3rd party packages use different DLL filenames than their LIB
imports which is certainly something to think about when pondering the
approach you've outlined above.  In the event an external package has a lot
of DLLs we have used FILE(GLOB...) in the past so not everything has to be
listed explicitly.

We don't have the problem of dealing with dependencies that you have.  One
approach you could use is to add the logic that selects the DLLs to install
alongside ADD_EXECUTABLE() and ADD_LIBRARY().  If target A, B, and C need
boost_signals DLL for example you could simply have it add the filename to
the global list.  Then at the bottom of your main CMakeLists.txt simply
perform the copy of all of the files that you need and/or call INSTALL_*().
Duplicate files could simply be excluded by calling
LIST(REMOVE_DUPLICATES..)



-- 
Philip Lowman
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090125/0115e875/attachment.htm>


More information about the CMake mailing list