CMake 没有在 macOS 上添加完整的 RPATH
Posted
技术标签:
【中文标题】CMake 没有在 macOS 上添加完整的 RPATH【英文标题】:CMake not adding full RPATH on macOS 【发布时间】:2022-01-11 17:05:01 【问题描述】:我有以下 MWE,其中柯南用于安装 fmt
库(共享)。
cmake_minimum_required(VERSION 3.21)
project(Test CXX)
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH $CMAKE_BINARY_DIR)
list(APPEND CMAKE_PREFIX_PATH $CMAKE_BINARY_DIR)
if(NOT EXISTS "$CMAKE_BINARY_DIR/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake"
"$CMAKE_BINARY_DIR/conan.cmake"
EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484
TLS_VERIFY ON)
endif()
include($CMAKE_BINARY_DIR/conan.cmake)
conan_cmake_configure(REQUIRES fmt/6.1.2
OPTIONS fmt:shared=True
GENERATORS cmake_find_package)
conan_cmake_autodetect(settings)
conan_cmake_install(PATH_OR_REFERENCE .
BUILD missing
REMOTE conancenter
SETTINGS $settings)
find_package(fmt)
add_executable(main main.cpp)
target_link_libraries(main fmt::fmt)
当我检查可执行文件 otool -l main
时,我看到了
fmt
库没有绝对路径,我希望这会发生。 所以这个可执行文件也无法运行,因为它没有找到libfmtd.6.dylib
。
问题是,这里的设置有什么错误,为什么可执行文件中没有完整路径编码?
输出otool
:
Load command 13
cmd LC_LOAD_DYLIB
cmdsize 40
name libfmtd.6.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 6.1.2
compatibility version 6.0.0
Load command 14
cmd LC_LOAD_DYLIB
cmdsize 48
name /usr/lib/libc++.1.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1200.3.0
compatibility version 1.0.0
Load command 15
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1311.0.0
compatibility version 1.0.0
链接命令是:
/usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -g
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk
-mmacosx-version-min=11.4 -Wl,-search_paths_first
-Wl,-headerpad_max_install_names
CMakeFiles/main.dir/main.cpp.o
-o main
/Users/.../.conan/data/fmt/6.1.2/_/_/package/8cb4659713397fdd78e4947cac0468f7f7ca515d/lib/libfmtd.dylib
【问题讨论】:
看起来github.com/conan-io/cmake-conan#keep_rpaths 是您所需要的。我没有使用柯南的经验,但是查看打包路径似乎他们有理由删除基于柯南的路径。 但我在质疑,哪个 Cmake 代码会产生这种行为。我在柯南生成的 Findfmt.cmake 脚本中没有看到任何可疑之处。 ? @NickolayOlshevsky:KEEP_RPATHS
没有被 Conan.cmake 用于这种方法,并且没有任何效果。
它位于您正在下载的 conan.cmake
脚本中的某个位置。无法快速追踪它,但此页面描述了行为:docs.conan.io/en/latest/howtos/manage_shared_libraries/…
@NickolayOlshevsky 不,它不存在,它不被尊重,也没有影响。运行 conan install 后,仅涉及 CMake。
【参考方案1】:
问题可能在于柯南在conan_cmake_install
期间如何构建fmt
它在没有 RPATH 含义的情况下构建它,生成的 fmt
库包含
LC_ID_DYLIB
部分:
otool -L /Users/.../.conan/data/fmt/8.0.1/_/_/package/09858fb580f8c1d91b81bfdbedd881822cc5da84/lib/libfmtd.dylib
给出:
Load command 4
cmd LC_ID_DYLIB
cmdsize 40
name libfmtd.8.dylib (offset 24)
time stamp 1 Thu Jan 1 01:00:01 1970
current version 8.0.1
compatibility version 8.0.0
并且这条路径 name libfmtd.8.dylib ...
被嵌入到可执行文件 main
中。
库 fmt 应该在启用 RPATH 的情况下构建,从而导致
Load command 4
cmd LC_ID_DYLIB
cmdsize 40
name @rpath/libfmtd.8.dylib (offset 24)
与可执行文件main
中的附加 RPATH 一起指向“”
/Users/.../.conan/data/fmt/8.0.1/_/_/package/09858fb580f8c1d91b81bfdbedd881822cc5da84/lib/
cmake 会自动添加(IMO?)。
【讨论】:
以上是关于CMake 没有在 macOS 上添加完整的 RPATH的主要内容,如果未能解决你的问题,请参考以下文章
Big Sur 内置的 CMake MacOS 应用程序无法在 Catalina 上运行
如何强制 cmake 在没有完整路径的情况下使用 cl.exe?