[CMake] INSTALL(EXPORT) does not honor LINK_INTERFACE_LIBRARIES?

Brad King brad.king at kitware.com
Thu Mar 31 15:26:31 EDT 2011


On 03/31/2011 09:14 AM, Rolf Eike Beer wrote:
> See below. Looks like the only way to prevent this is to set
> LINK_INTERFACE_LIBRARIES to empty for every lib that uses the static lib.
> Which may be a good idea anyway as that transitive linking is harmful.

CMake has always done said transitive linking for historical reasons.
The default behavior cannot change now.  It is not necessarily harmful
if the static library objects are built with -fPIC and are not all
absorbed into the shared library that initially links it.

The documented way to turn off transitive linking is to set the
LINK_INTERFACE_LIBRARIES property.  Once that is done then install(EXPORT)
will not complain about the transitive static libraries anymore.  However,
it *will* complain about the *shared* libraries for the reason I explained
in my earlier response to this thread.

On 03/29/2011 05:36 PM, Rolf Eike Beer wrote:
> Am Dienstag, 29. März 2011, 09:41:36 schrieb Brad King:
>> CMake running in an outside application needs to know these private runtime
>> dependencies.  It needs them ensure that the application link line is
>> generated such that the linker can find the transitive dependencies (e.g.
>> -rpath-link) of the public library.
>
> No, why should it?

See the sample script below.  CMake needs to know where bar's transitive
dependencies are installed so that it can pass the right thing to -rpath-link.
This is is how IMPORTED_LINK_DEPENDENT_LIBRARIES is used and why the
install(EXPORT) command needs all the targets in the export.

Since one target can be installed to multiple locations, or accidentally
not at all, the install(TARGETS) for 'foo' must list the same EXPORT as
the install(TARGETS) for 'bar' so that CMake can associate the right copy
of the dependency.

-Brad


echo 'int foo(void) { return 0; }' > foo.c
echo 'extern int foo(void);
int bar(void) { return foo(); }' > bar.c
echo 'extern int bar(void);
int main() { return bar(); }' > main.c
mkdir -p lib
gcc -shared -fPIC -o lib/libfoo.so -Wl,-soname,libfoo.so foo.c
gcc -shared -fPIC -o libbar.so -Wl,-soname,libbar.so bar.c lib/libfoo.so
ldd ./libbar.so |grep libfoo.so
#        libfoo.so => not found
gcc -o main main.c libbar.so
#/usr/bin/ld: warning: libfoo.so, needed by libbar.so, not found (try using -rpath or -rpath-link)
#libbar.so: undefined reference to `foo'
gcc -o main -Wl,-rpath-link,lib main.c libbar.so


More information about the CMake mailing list