-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Currently, many recipes don't produce state of the art relocatable shared libs on macOS.
It would be nice to check whether shared libs on macOS properly have @rpath/<shared> in install tree (@rpath token is supported since macOS 10.5 Leopard, so since 2007...).
It must not be <shared> or <absolute/path/to/shared> (many binaries produced by conan-center recipes on macOS have the former actually, it's bad).
see https://cmake.org/cmake/help/latest/prop_tgt/MACOSX_RPATH.html#prop_tgt:MACOSX_RPATH
Moreover, rpath should be empty in installed shared libs.
Usually, in a default CMake configuration, binaries produced in build tree have absolute paths of dependencies (direct & transitive) libs folder in their rpath, so that you can run your executable for free (on macOS, it only works if external shared libs also have @rpath token, so proper relocatable binaries), then it is cleared by CMake during installation.
It also means that all CMake based recipe must:
-
use
conan_basic_setup(KEEP_RPATHS) -
recipe should ensure that https://cmake.org/cmake/help/latest/policy/CMP0042.html#policy:CMP0042 is enabled (either by injection
CMAKE_POLICY_DEFAULT_CMP0042 NEW, or ensuringcmake_minimum_required(VERSION 3.0)or higher in upstream CMakeLists). -
recipe should call install target, not manually copying files (it can be allowed if target os is Windows), so that CMake can:
- eventually replace absolute path set in shared libs of the build tree with
@rpathfor shared libs in install tree (usually it's already@rpathin the build tree, but not always). - clear rpath (and it's also important on Linux). To do so,
CMAKE_INSTALL_RPATH&CMAKE_INSTALL_RPATH_USE_LINK_PATHshould not be manipulated.
If manual copy can't be avoided, something like this at the end of
package()may allow to add@rpathtoken into dylib files :if tools.is_apple_os(self.settings.os): with tools.chdir(os.path.join(self.package_folder, "lib")): for dylib in glob.glob("*.dylib"): command = "install_name_tool -id {0} @rpath/{1}".format(os.path.basename(dylib), dylib) self.run(command)
- eventually replace absolute path set in shared libs of the build tree with
I suspect that many issues consumers have with "all shared" builds (-o *:shared=True) on macOS would be solved. Default behavior of conan_basic_setup on macOS is really harmful.
see conan-io/conan-center-index#9052
also conan-io/conan#1238 or conan-io/conan#10253
https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html
https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling#mac-os-x-and-the-rpath
https://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html