CMake 未在 macOS 上添加完整的 RPATH

Gab*_*iel 5 c++ rpath cmake

我有以下 MWE,其中 Conan 用于安装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)
Run Code Online (Sandbox Code Playgroud)

当我检查可执行文件时,otool -l main我发现该fmt库没有绝对路径,这是我希望发生的情况。因此,executbale 也无法运行,因为它找不到libfmtd.6.dylib.

问题是,这里设置错误是什么?为什么可执行文件中没有编码完整路径?

输出otool

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)
Run Code Online (Sandbox Code Playgroud)

链接命令是:

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
Run Code Online (Sandbox Code Playgroud)

Gab*_*iel 1

问题可能在于 conan 如何在没有 RPATH 含义的fmt情况下conan_cmake_install 构建它,生成的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
Run Code Online (Sandbox Code Playgroud)

并且该路径name libfmtd.8.dylib ...被嵌入到可执行文件中main

库 fmt 应该在启用 RPATH 的情况下构建,从而导致

Load command 4
          cmd LC_ID_DYLIB
      cmdsize 40
         name @rpath/libfmtd.8.dylib (offset 24)
Run Code Online (Sandbox Code Playgroud)

以及可执行文件中的附加 RPATH main,它将指向“

/Users/.../.conan/data/fmt/8.0.1/_/_/package/09858fb580f8c1d91b81bfdbedd881822cc5da84/lib/
Run Code Online (Sandbox Code Playgroud)

它将由 cmake 自动添加(IMO?)。