target_link_libraries可以很好地链接私有框架,但无法将框架复制到应用程序捆绑包的frameworks目录中。它也没有办法更新可执行文件到框架的路径。
所以本质上我需要CMake:
- 与私人dylib链接
- 将该dylib复制到应用程序捆绑包的Frameworks目录中
- 更新可执行文件到dylib的路径
我决定为最终可执行文件编写自己的rpath。为了防止CMake写入构建路径,请设置CMAKE_SKIP_BUILD_RPATH
。这需要在add_executable之前设置。
set(CMAKE_SKIP_BUILD_RPATH TRUE)
然后,我将所有想要嵌入的dylib复制到构建的应用程序包的Frameworks目录中。在这种情况下,我正在复制存储在项目中的MoltenVK。${PROJECT_NAME}
是可执行文件的名称。
set(APP_BUNDLE_CONTENTS_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents")
set(APP_BUNDLE_FRAMEWORKS_DIR "${APP_BUNDLE_CONTENTS_DIR}/Frameworks")
file(GLOB VULKAN_DYLIB_PATHS "${CMAKE_SOURCE_DIR}/external/vulkan/builds/mac/*")
target_link_libraries(${PROJECT_NAME} ${VULKAN_DYLIB_PATHS})
file(COPY ${VULKAN_DYLIB_PATHS} DESTINATION ${APP_BUNDLE_FRAMEWORKS_DIR})
然后,我在可执行文件中添加一个rpath作为构建后命令。
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD COMMAND
install_name_tool -add_rpath "@executable_path/../Frameworks/"
"${APP_BUNDLE_CONTENTS_DIR}/MacOS/${PROJECT_NAME}")
这适用于使用CMake进行构建和调试。这在生成Xcode项目时不起作用。希望我能找到一种更好更干净的方式,但这目前有效。