如何设置dylib搜索路径OSX

问题描述 投票:0回答:1

我在 Xcode 中有一个项目,我在环境变量窗格中设置 DYLD_FALLBACK_LIBRARY_PATH 来设置我的应用程序应在何处查找要链接的库(这非常适合我的目的)

我正在编写一个 CMakeLists.txt 文件来生成此项目,我想从脚本中设置此属性。

我知道我可以做到这一点:

SET(ENV{DYLD_FALLBACK_LIBRARY_PATH} ${DYLD_FALLBACK_LIBRARY_PATH} /path/to/lib)

但是当我运行时出现此错误:

'dyld: Library not loaded ... Reason: image not found' 

启动应用程序时。我想这句话是不一样的。

有人知道我如何从 CMakeLists.txt 中实现与 Xcode 中相同的功能吗?

我隐约知道 CMake RPATH 的东西,但如果可能的话我宁愿避免它。

感谢您的宝贵时间!

干杯!

汤姆

macos linker cmake dyld rpath
1个回答
17
投票

我终于使用稍微不同的方法完成了这项工作。这可能不是完美的解决方案并且在所有情况下都有效,但希望这能帮助那些与我遇到类似问题的人。

我试图链接到的 dylib 是

libSDL2-2.0.0

如果我导航到该文件所在的位置并运行:

otool -L libSDL2-2.0.0.dylib

我在输出中得到的第一行是这样的:

/usr/local/lib/libSDL2-2.0.0.dylib

如果我然后导航到我构建的可执行文件并运行相同的命令,我会看到同样的事情:

/usr/local/lib/libSDL2-2.0.0.dylib

(我的可执行文件链接到 SDL)

我的问题是

libSDL2-2.0.0.dylib
实际上并不位于那里,它位于我的项目结构中的libs文件夹中。为了让链接器在运行时找到该库,我必须在 dylib 上运行此命令

install_name_tool -id "@executable_path/../path/to/lib/<lib_name>" <lib_name>

其中

@executable_path
是要运行的应用程序的位置 - 在我的例子中,它位于 -
build/debug

项目结构:

root/
    CMakeLists.txt
    project/
        lib/
            libSDL2-2.0.0.dylib
    build/
        debug/
            my_app

为了清晰起见,这是一个精确的映射:

install_name_tool -id "@executable_path/../../project/lib/libSDL2-2.0.0.dylib" libSDL2-2.0.0.dylib

如果我跑步

otool -L libSDL2-2.0.0.dylib
我现在看到:

@executable_path/../../sdl-test/lib/libSDL2-2.0.0.dylib

在输出的第一行。

如果我现在再次构建我的项目(我只是在 Xcode 中构建),这会使用 dylib 的新相对路径更新我的应用程序。您只需在库上运行

install_name_tool
,您不必在可执行文件上运行它,它会在您构建它时更新。

如果我运行

otool -L myapp
我现在会看到与
libSDL2-2.0.0.dylib

相同的相对路径

这样,当启动应用程序时,它就能够成功找到dylib!

我的理解是,这是在 OSX 上实现这一目标的方法,并且没有一个出色的替代方案(除了我在问题中提到的

DYLD_FALLBACK_LIBRARY_PATH

希望这对和我有类似困难的人有一些帮助!

我发现有用的资源:

http://osiris.laya.com/coding/dylib_linking.html

https://www.fmod.org/questions/question/forum-23398/

https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac

更新:

我实际上找到了一种更好的方法来使用 rpaths 来做到这一点,并认为我应该写下如何做到这一点以供将来参考:

在我的 CMakeLists.txt 文件中,我在末尾添加了这些行(在

add_executable
target_link_libraries
之后:

# set @rpaths for libraries to link against
set(CMAKE_SKIP_BUILD_RPATH  FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 
set(CMAKE_INSTALL_RPATH "${PROJ_LIB_DIR}")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

(有关更多信息,请参阅 https://cmake.org/Wiki/CMake_RPATH_handling

其中

${PROJ_LIB_DIR}
是我的 dylib 所在的位置:

set(PROJ_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}/lib)

然后我跑了:

示例:

install_name_tool -id "@rpath/<my-dylib>.dylib" <my-dylib>.dylib

实际:

install_name_tool -id "@rpath/libSDL2-2.0.0.dylib" libSDL2-2.0.0.dylib

在我的dylib所在的目录中(在我的例子中是libSDL2-2.0.0.dylib)

现在,当我运行 cmake 然后构建项目时,我的新可执行文件将在运行时在 CMakeLists.txt 文件中设置的位置搜索库。

@rpath
将替换为 CMakeLists.txt 文件中指定的路径,并且一切都可以正常工作,而无需显式设置
@executable_path
@loader_path

© www.soinside.com 2019 - 2024. All rights reserved.