【问题标题】:How to set dylib search path OSX如何设置dylib搜索路径OSX
【发布时间】:2016-12-05 18:01:11
【问题描述】:

我在 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 的东西,但如果可能的话,我宁愿避免这样做。

感谢您的宝贵时间!

干杯!

汤姆

【问题讨论】:

  • I am vaguely aware of the CMake RPATH stuff but I'd rather avoid that if possible. - 但这是做你想做的事情的正确方法。有关更多信息,请参阅cmake.org/Wiki/CMake_RPATH_handlingSET(ENV{..}) 仅在 cmake 运行阶段设置环境变量,它不会影响构建或运行阶段的环境。
  • 嗨!我可能应该模糊地强调......:P 我的情况是我有一个 dylib(在本例中为 SDL),我想在运行时链接,但我不想将它添加到系统路径(/usr/ local/bin ..) 我查看了 RPATH 的东西,但它看起来非常复杂。我已经阅读了那篇文章并尝试了它说要使用的一些 CMake 东西,但运气不佳。我必须做 dylib install_name_tool 的事情吗?我想避免这种情况,因为它看起来有点奇怪。我的背景主要是 Windows,所以也许我遗漏了一些明显的东西!谢谢!
  • 如果您在阅读关于 RPATH 的 CMake 文章时遇到问题,请描述具体问题。
  • 在您提到的链接中,我尝试使用“始终完整 RPATH”部分下的 CMake 示例 - 但我不确定是否需要修改现有的 dylib。如果我运行 otool -L,路径是绝对的,并且我的应用程序正在 usr/local/bin 中寻找我的共享库(如果不是)我真的不想修改 dylib 如果我可以帮助它,而且我还没有自己建造。
  • 可能有点晚了,但如果其他人想避免 @rpath 的内容并看到这篇文章,只需调用您编译的程序,如 DYLD_LIBRARY_PATH=<path to lib> ./<program>。信用:superuser.com/a/282451

标签: macos linker cmake dyld rpath


【解决方案1】:

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

我试图链接的 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_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

【讨论】:

    猜你喜欢
    • 2014-06-06
    • 2017-03-12
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 2011-06-20
    • 1970-01-01
    相关资源
    最近更新 更多