[CMake] more linking problems

Brad King brad.king at kitware.com
Thu Apr 21 13:18:04 EDT 2005


Alexander Neundorf wrote:
> -Wl,-rpath,/usr/X11R6/lib:/usr/src/kde3-HEAD/kdevelop/lib/interfaces:/usr/src/kde3-HEAD/kdevelop/lib/interfaces/extensions:/usr/src/kde3-HEAD/kdevelop/lib/interfaces/external:/usr/src/kde3-HEAD/kdevelop/lib/util:/usr/src/kde3-HEAD/kdevelop/lib/widgets/propeditor:/opt/kde/lib:/usr/src/qt-copy/lib
>  
> I have three problems with this approach: 
>  
> 1) how do I link to a shared library which isn't installed yet ? 
> I added lines like this one: 
> ${CMAKE_BINARY_DIR}/lib/interfaces/external/libkinterfacedesigner.so

Turn on CMAKE_SKIP_RPATH to avoid getting the build-tree rpath compiled 
in and then just specify the library by name "kinterfacedesigner".  The 
install location should not matter as long as the system is configured 
with the proper library search paths.  Several linux distributions ban 
rpaths from their binaries, so avoiding rpaths is generally considered 
good for installed packages.  CMake adds rpaths by default so that 
shared-library builds can work out-of-the-box from the build tree.

> 2) In kdevelop libkdevelop links to several shared libs and also to some 
> static libs. E.g. libkdevinterfaces.a is approx. 500 kb big and the stuff 
> contained in it should be contained in the resulting libkdevelop. But 
> with the given link command this isn't the case. The resulting 
> libkdevelop is only about 6 kb big and doesn't contain the objects from 
> the static libs it linked to.
> Is there a way to achieve this ?

When a static library is linked using -lmylib objects from it will only 
be included if something references a symbol from them.  Some linkers 
(but I don't think all) will copy the entire static library if linked 
with the full name of the archive (libmylib.a).

As far as I know the only cross-platform reliable way to get everything 
into the shared library is to create a source file in the shared library 
that references at least one symbol from every object in the static 
library.  The symbol doesn't need to do anything it just needs to be 
referenced.  One symbol per object file should do it.  Even then the 
symbols may not be exported from the shared library and available for 
use by other code.  This depends whether the objects in the static 
library were compiled with a flag like -fPIC.  The behavior is 
platform-dependent, but on Linux at least everything is compiled 
"sharable" by default.

Alternatively you can do the restructing to put all the sources into the 
same shared library.

> 3) In the kdevelop tree there are two targets "kdevelop": a library 
> ADD_LIBRARY(kdevelop ...) and a binary ADD_EXECUTABLE(kdevelop ...) in 
> different directories. 

This is currently a CMake limitation.  There can be only one target with 
a given name anywhere in the build tree.  The reason is that Visual 
Studio solutions/workspaces must have unique names for the projects in 
them.  Each project corresponds to a library or executable.  Therefore 
they must have unique names.  Eventually we might do some kind of name 
encoding based on the source directory where the target was added but 
this is not yet implemented.

You can get around this problem by splitting the build process into two 
pieces.  The main build will create all the libraries and utility 
executables.  At the end of this build you can have a custom command 
that runs ctest --build-and-test to drive a second build process in a 
subdirectory.  This is done in VTK right now to build the examples using 
a single target in the top-level build process.

-Brad


More information about the CMake mailing list