[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