Hi,

I think I may have found a problem related to CMake’s handling of 
-Wl,-rpath-link on Linux in combination with cross-compiling against a sysroot. 
You can grab a minimal example that exposes the behavior at 
https://github.com/neverpanic/cmake-rpath-link-example.

The example uses a chain of linkage from an executable to a library B, which in 
turn links to a library A. Both libraries are in subdirectories of the build 
tree that are not part of the default search path of the linker. CMake adds 
-Wl,-rpath during the build to ensure that these libraries are found. The key 
here is that library B links against library A privately, i.e. A is not part of 
B’s link interface.

When linking the executable that uses library B, CMake adds -Wl,-rpath 
/path/to/directory/of/lib/b and path/to/libB.so to the linking command line. 
When linking executables (or libraries with --no-allow-shlib-undefined), 
binutils ld attempts to locate all transitively linked libraries to ensure no 
symbols are missing. According to the binutils ld documentation[1] “[t]he 
-rpath option is also used when locating shared objects which are needed by 
shared objects explicitly included in the link; see the description of the 
-rpath-link option.” This allows the linker to find the required library file 
(lib A in the example) when not compiling against a sysroot. However, when 
--sysroot is passed to the linker, all rpaths found in the libraries are 
prefixed with the sysroot, causing the linker to fail to locate lib A. See also 
the documentation for the -rpath-link option in [1], which explains the 
linker’s search behavior.

The solution to the problem is passing 
-Wl,-rpath-link,/path/to/directory/of/lib/a. CMake does support generating this 
flag, but does not currently do so in this case. 
cmComputeLinkInformation::AddSharedDepItem would add the required entry to 
cmComputeLinkInformation::OrderDependentRPath when SharedDependencyMode is 
SharedDepModeDir (which is the case), however AddSharedDepItem is only called 
in cmComputeLinkInformation::Compute if the LinkEntry obtained from 
cmComputeLinkDepends::Compute has the IsSharedDep flag set.

This flag gets set in cmComputeLinkDepends::HandleSharedDependency, which is 
called for every entry added to cmComputeLinkDepends::SharedDepQueue in 
cmComputeLinkDepends::FollowLinkEntry. This would require that every indirect 
library dependency (part of the link interface or otherwise) would have to be 
added to cmLinkInterface::SharedDeps as returned from 
cmGeneratorTarget::GetLinkInterface.

cmLinkInterface::SharedDeps gets set in 
cmGeneratorTarget::ComputeLinkInterface, but that currently only happens when 
cmOptionalLinkInterface::ExplicitLibraries (i.e. the INTERFACE_LINK_LIBRARIES 
property) is not null. To my mind, that does not make a lot of sense (and in 
fact, adding a library to the link interface of lib B in the example hides the 
problem).

I don’t feel familiar enough with the internals of CMake link interface 
handling to determine that changing cmGeneratorTarget::ComputeLinkInterface to 
always populate SharedDeps is the right thing to do and does not have 
unintended side effects, so I’m looking for feedback.

I’m attaching a patch that shows what a solution could look like, but I’m not 
positive that it’s correct.

Note that https://cmake.org/Bug/view.php?id=14684 seems related.


[1] https://sourceware.org/binutils/docs/ld/Options.html#Options
-- 
Clemens Lang • Development Specialist
BMW Car IT GmbH • Lise-Meitner-Str. 14 • 89081 Ulm • http://bmw-carit.com
-------------------------------------------------------------------------
BMW Car IT GmbH
Geschäftsführer: Kai-Uwe Balszuweit und Christian Salzmann
Sitz und Registergericht: München HRB 134810
-------------------------------------------------------------------------

Attachment: cmake-rpath-link.patch
Description: cmake-rpath-link.patch

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake-developers

Reply via email to