我正在使用cmake构建一个多二进制项目并在Debian中部署。 CMakeLists.txt减少到这样的程度:
add_library(mylib SHARED lib.cpp) #creates libmylib.so
add_executable(myapp main.cpp)
target_link_libraries(myapp my-lib)
install(TARGETS mylib myapp
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
如果我将其安装到(-DCMAKE_INSTALL_PREFIX=/usr
),那么我没有问题。但是,如果我安装到其他地方(-DCMAKE_INSTALL_PREFIX=/opt/myapp
,甚至-DCMAKE_INSTALL_PREFIX=/usr/local
),那么我就有问题了。
当我运行$ /opt/myapp/bin/myapp
时,我的应用程序无法找到.so。
我可以使用设置了myapp的脚本部署脚本:
#!/bin/sh
export LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib:$LD_LIBRARY_PATH
exec ${CMAKE_INSTALL_PREFIX}/bin/myapp $*
但这感觉就像是黑客。另外,需要在配置时使用${CMAKE_INSTALL_PREFIX}/lib
生成脚本。
我认为有一种更原生的方式来处理这个问题,这让我只需在安装后从/opt
或/usr/local
执行我的应用程序。它最好在配置,编译或安装时处理,而不是在运行时之前,最好不要求某人修改他们的~/.bashrc
或~/.profile
。
请问您是否有办法将linux中的标准bin
,lib
结构部署到任意路径而无需预运行时脚本?
答案 0 :(得分:1)
你应该:
LD_LIBRARY_PATH
。设置RPATH的示例:
if(APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path/../lib;@loader_path")
elseif(UNIX)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/")
endif()
注意:在macos上你现在应该使用@rpath
注意2:在macos上,您可以使用otool -l
和otool -L
进行介绍
注3:您可以在GNU / Linux上使用ldd lib.so
和objdump -p lib.so
。
注意:更喜欢使用GNUInstallDirs
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)