Tom*_*Tom 2 macos linker rpath cmake dyld
我在Xcode中有一个项目,我在环境变量窗格中设置了DYLD_FALLBACK_LIBRARY_PATH,以设置我的应用程序应该查找要链接到的库的位置(这对我来说很有用)
我正在编写一个CMakeLists.txt文件来生成这个项目,我想从脚本中设置这个属性.
我知道我可以这样做:
SET(ENV{DYLD_FALLBACK_LIBRARY_PATH} ${DYLD_FALLBACK_LIBRARY_PATH} /path/to/lib)
Run Code Online (Sandbox Code Playgroud)
但是当我跑步时我得到这个错误:
'dyld: Library not loaded ... Reason: image not found'
Run Code Online (Sandbox Code Playgroud)
启动应用程序时.我想这句话不一样.
有人知道如何从CMakeLists.txt中获得与Xcode相同的功能吗?
我隐约知道CMake RPATH的东西,但如果可能的话,我宁愿避免这种情况.
感谢您的时间!
干杯!
汤姆
我最终使用稍微不同的方法来完成这项工作.这可能不是一个完美的解决方案,并且可以在所有情况下使用,但希望这可以帮助那些遇到类似问题的人.
我试图链接到的dylib是 libSDL2-2.0.0
如果我导航到该文件所在的位置并运行:
otool -L libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
我在输出中得到的顶线是这样的:
/usr/local/lib/libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
如果我然后导航到我构建的可执行文件并运行相同的命令,我看到同样的事情:
/usr/local/lib/libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
(我的可执行文件链接到SDL)
我的问题libSDL2-2.0.0.dylib
实际上并不在那里,它在我的项目结构中的libs文件夹中.为了让链接器在运行时找到lib,我必须在dylib上运行此命令
install_name_tool -id "@executable_path/../path/to/lib/<lib_name>" <lib_name>
Run Code Online (Sandbox Code Playgroud)
@executable_path
运行应用程序的位置在哪里- 在我的情况下,这是 -build/debug
项目结构:
root/
CMakeLists.txt
project/
lib/
libSDL2-2.0.0.dylib
build/
debug/
my_app
Run Code Online (Sandbox Code Playgroud)
为清晰起见,这是精确的映射:
install_name_tool -id "@executable_path/../../project/lib/libSDL2-2.0.0.dylib" libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
如果我跑,otool -L libSDL2-2.0.0.dylib
我现在看到:
@executable_path/../../sdl-test/lib/libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
在输出的第一行.
如果我现在再次构建我的项目(我只是在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)
Run Code Online (Sandbox Code Playgroud)
(有关详细信息,请参阅https://cmake.org/Wiki/CMake_RPATH_handling)
这里${PROJ_LIB_DIR}
是我的dylibs位于:
SET(PROJ_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}/lib)
Run Code Online (Sandbox Code Playgroud)
然后我跑了:
例:
install_name_tool -id "@rpath/<my-dylib>.dylib" <my-dylib>.dylib
Run Code Online (Sandbox Code Playgroud)
实际:
install_name_tool -id "@rpath/libSDL2-2.0.0.dylib" libSDL2-2.0.0.dylib
Run Code Online (Sandbox Code Playgroud)
在我的dylib所在的目录中(在我的例子中是libSDL2-2.0.0.dylib)
现在当我运行cmake然后构建我的项目时,我的新可执行文件将在运行时在我在CMakeLists.txt文件中设置的位置搜索库.@rpath
将被替换为CMakeLists.txt文件中指定的路径,一切正常工作,而无需显式设置@executable_path
或@loader_path
归档时间: |
|
查看次数: |
7929 次 |
最近记录: |