如何设置dylib搜索路径OSX

时间:2016-07-31 15:36:17

标签: macos linker cmake dyld rpath

我在Xcode中有一个项目,我在环境变量窗格中设置了DYLD_FALLBACK_LIBRARY_PATH,以设置我的应用程序应该查找要链接到的库的位置(这对我的目的很有效)

enter image description here

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

我知道我可以这样做:

ncclient

但是当我跑步时我得到了这个错误:

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

启动应用程序时。我想这个陈述是不一样的。

有人知道如何从CMakeLists.txt获得与Xcode相同的功能吗?

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

感谢您的时间!

干杯!

汤姆

1 个答案:

答案 0 :(得分:5)

我终于使用稍微不同的方法来实现这一点。这可能不是一个完美的解决方案,并且适用于所有情况,但希望这可以帮助那些遇到类似问题的人。

我尝试链接的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文件夹中。为了让链接器在运行时找到lib,我必须在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_EXECUTABLETARGET_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