Skip to content

[wip] pass -rpath-link via CMakeToolchain #18068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: develop2
Choose a base branch
from

Conversation

jcar87
Copy link
Contributor

@jcar87 jcar87 commented Apr 3, 2025

CMake itself tries to pass -rpath (and -rpath-link) to the linker (via the compiler). However we know this is not sufficient in some scenarios:

  • In legacy CMakeDeps, in some cases CMake does not have enough information to derive the correct -rpath-link, and it fails - mostly when cross-compiling in the presence of a sysroot. Conan knows all the directories in the host context that may contain runtime libraries, so we can pass -rpath-link globally for the entire build. This would solve problems such as this [fast-dds] Fix crosscompilation issues conan-center-index#25195 - which are recurrent in Conan Center, not that even with the new CMakeDeps, there are corner cases
  • When not cross-building, but when having a --sysroot, CMake only passes -rpath (even correctly, pointing to the directories in the Conan cache) - but in the presence of a sysroot the linker will re-root them in a way that it won't find them inside the sysroot (and fail)
  • Some recipes in Conan Center have one of the following hacks sometimes when the linker cannot find indirect runtime dependencies:

Either:
A)

        if self.settings.os == "Linux":
            # Workaround for: https://github.com/conan-io/conan/issues/13560
            libdirs_host = [l for dependency in self.dependencies.host.values() for l in dependency.cpp_info.aggregated_components().libdirs]
            tc.variables["CMAKE_BUILD_RPATH"] = ";".join(libdirs_host)

or
B)

        if not cross_building(self):
            vrenv = VirtualRunEnv(self)
            vrenv.generate(scope="build")

A) does not work when we are crossbuilding and we have a sysroot (because the linker reroots them)
B) does not work when crossbuilding (so the recipe may build fine when doing a native build due to this workaround, but wont fully support crossbuilding when using shared libraries), but even when not crossbuilding, it wont work if using a sysroot, or using a toolchain for a separate distro (think poco where os=Linux and arch=x86_64). It also introduces risks of runtime clashes when the libraries for the host are picked up by executables that run at build time.

Passing -rpath-link via the toolchain would remove the need for workarounds and mitigate all of the cases above, including the corner cases where Conan + (new) CMakeDeps + CMake cannot correctly derive that -rpath-link is needed.

WIP: still needs tests and probably a flag to control behaviour

@jcar87 jcar87 requested review from uilianries and memsharded April 3, 2025 14:53
@@ -252,6 +252,27 @@ def context(self):
return
return {"arch_flag": arch_flag}

class RpathLinkFlagsBlock(Block):
# TODO: should do this only on Linux, or toggled by an opt-in conf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably what we want to do is to enable this directly in the conan_cmakedeps_paths.cmake generated by the CMakeConfigDeps. That file is loaded by the CMakeToolchain, but not only for this, so it can be also used by other solutions as cmake-conan, because otherwise whatever we put in the toolchain is not available for cmake-conan and the CLion-plugin.

So the opt-in would be to use CMakeConfigDeps? It is getting more ready and mature, it is known to solve a lot of problems, so probably it is good to start moving it forward a bit more?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants