如何设置dylib搜索路径OSX
How to set dylib search path OSX
我在 Xcode 中有一个项目,我在环境变量窗格中设置 DYLD_FALLBACK_LIBRARY_PATH 来设置我的应用程序应该在哪里寻找库 link 到(这对我的工作很好目的)
我现在正在写一个 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 的东西,但我宁愿尽可能避免它。
感谢您的宝贵时间!
干杯!
汤姆
我终于使用稍微不同的方法实现了这一点。这可能不是完美的解决方案并适用于所有情况,但希望这能帮助遇到与我类似问题的人。
我试图 link 的 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
(我的可执行文件 links 到 SDL)
我的问题是 libSDL2-2.0.0.dylib
实际上不在那里,它在我的项目结构中的 libs 文件夹中。为了让 linker 在 运行 时找到 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_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}
是我的动态库所在的位置:
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
我在 Xcode 中有一个项目,我在环境变量窗格中设置 DYLD_FALLBACK_LIBRARY_PATH 来设置我的应用程序应该在哪里寻找库 link 到(这对我的工作很好目的)
我现在正在写一个 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 的东西,但我宁愿尽可能避免它。
感谢您的宝贵时间!
干杯!
汤姆
我终于使用稍微不同的方法实现了这一点。这可能不是完美的解决方案并适用于所有情况,但希望这能帮助遇到与我类似问题的人。
我试图 link 的 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
(我的可执行文件 links 到 SDL)
我的问题是 libSDL2-2.0.0.dylib
实际上不在那里,它在我的项目结构中的 libs 文件夹中。为了让 linker 在 运行 时找到 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_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}
是我的动态库所在的位置:
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