[CMake] How to avoid the explicit library location when linking with imported library targets

Brad King brad.king at kitware.com
Fri Sep 17 10:09:10 EDT 2010


On 09/17/2010 09:31 AM, Pere Mato Vila wrote:
> The problem I have is that when have already built and
> installed B I can not move anymore the location of the A. This
> is because the libraries created in B contains the absolute
> path to exported libraries in A.

The binaries in B would at most contain RPATH entries to point at the
location of A.  CMake computes this RPATH information to ensure that
the binaries can run without special environment variables by default.
This works on the original machine.  If you want to redistribute the
binaries then you have to tell CMake not to store RPATH information.
This is totally separate from whether the libraries are handed to the
linker by full path or not.  Look for mention of RPATH in the CMake
documentation (INSTALL_RPATH, INSTALL_RPATH_USE_LINK_PATH, and perhaps
CMAKE_SKIP_RPATH).

On 09/17/2010 09:32 AM, Ryan Pavlik wrote:
> Yes, however, transitive link dependencies are stored/set in the
> installed targets file with full paths to the location on the original
> build machine.  If I install the export target for a static libfoo,
> which links to /home/rpavlik/libbar.a, the targets file includes that
> full path.

Only libraries handed to target_link_libraries by full path end up in
the targets file with their full path.  CMake is preserving all the
information it was given.  This is intended to produce working dependent
builds on the machine where the project is installed.  CMake does not
have enough information to magically produce a symbolic library reference
in place of the full path the user gave it.  If it just put the library
name in there then the dependent builds would not have enough information
to guarantee that the same library is used.

If the transitive dependencies are *other* *imported* targets then just
their names appear in the <pkg->targets file.  It is up to the author
of the corresponding <pkg>-config.cmake file to load the targets file
after also loading the targets file from the dependencies.

If you want to do

  target_link_libraries(mylib /path/to/libother.a)

but do not want "/path/to/libother.a" to appear in the transitive dep
list of mylib's target file, then do this:

  add_library(other STATIC IMPORTED)
  set_property(TARGET other PROPERTY IMPORTED_LOCATION /path/to/libother.a)
  target_link_libraries(mylib other)

This will still use the full path when linking mylib itself but the
targets file will report just "other" as a dependency.  Then in your
package configuration file that loads mylib's targets file you should
somehow provide an imported target for "other", perhaps from a new
find_library result.

> However, I can envision possibly wanting to run a find_package script

and trust the user to choose a binary that is identical to the one you
originally used to build?

-Brad


More information about the CMake mailing list