[CMake] shared library linking question

Alexander Neundorf a.neundorf-work at gmx.net
Sun Feb 14 12:27:12 EST 2010


On Saturday 13 February 2010, Andreas Pakulat wrote:
> On 13.02.10 11:00:52, Tim Blechmann wrote:
> > hi andreas,
> >
> > >> common/libcommon.so
> > >> target1/target1
> > >> target2/target2
> > >>
> > >> both target1 and target2 are linked with libcommon, both work fine in
> > >> the build directory, the libraries are resolved correctly.
> > >>
> > >> after installing them, they are formatted like:
> > >> $PREFIX/lib/libcommon.so
> > >> $PREFIX/bin/target1
> > >> $PREFIX/bin/target2
> > >>
> > >> now libcommon.so cannot be resolved, probably because the targets are
> > >> linked with ../common/libcommon.so, so the loader cannot find the
> > >> shared library. what is the best way to resolve this issue?
> > >
> > > How did you write your cmake file? Usually you'd be using the libcommon
> > > target name in target_link_libraries for target1 and target2.
> >
> > in common/ i build libcommon
> > add_library(libcommon SHARED ...)
> >
> > in the target directories, i build the target:
> > add_executable(targetX ...)
> > target_link_libraries(targetX libcommon)
> >
> > the targets are built with
> > -rdynamic -L../common ../common/libcommon.so Wl,-
> > rpath,../common:/path/to/common
> >
> > from my limited understanding of the linking process, it should link with
> > -lcommon instead of using ../common/libcommon.so, since the rpath is
> > already set to ../common. but how can i tell cmake to do this?

The RPATH is only used when executing the resulting binary, it does not affect 
the searching for the library file during the linking step. So this is ok.

> As far as I can see this is ok. At least its the same in the cmake
> projects I'm using. The point is that cmake will change this rpath when
> you run make install (provided you have used install( TARGETS)). It'll
> then set the RPATH to the absolute path of the install location of
> libcommon.so.

This depends on the settings.

By default, when not doing anything, "make install" will make the RPATH of the 
installed files empty.
That's why your installed executable didn't find the shared library.
If you want an RPATH in your installed binaries, you have to set up some 
RPATH-related target properties.
Either you know exactly in which non-standard directories the loader should 
search for the libraries when executing the binary, then set the 
INSTALL_RPATH target property to these directories.
E.g.
set_target_properties(target1 PROPERTIES 
                      INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)

Then the RPATH will be set to the install directory of your own libs.

Or you can let cmake do that automatically:
set_target_properties(target1 PROPERTIES 
                      INSTALL_RPATH_USE_LINK_PATH TRUE)

This will set the RPATH of the installed executable to the automatically 
calculated RPATH used for the same executable in the build tree (which 
contains all directories of all linked libs), except those directories which 
were inside the build directory.
Still in this case you probably still want to add the install directory of 
your libraries additionally to the RPATH:
set_target_properties(target1 PROPERTIES 
                      INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib
                      INSTALL_RPATH_USE_LINK_PATH TRUE)

Alex


More information about the CMake mailing list