我正在使用 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 $*
但这感觉像是一个 hack。另外,需要在配置时使用 ${CMAKE_INSTALL_PREFIX}/lib
生成脚本。
我想有一种更原生的方式来处理这个问题,它让我可以在安装后从 /opt
或 /usr/local
简单地执行我的应用程序。它最好在配置、编译或安装时而不是在运行时之前处理这个问题,并且最好不需要有人修改他们的 ~/.bashrc
或 ~/.profile
。
你能告诉我是否有一些方法可以将 linux 中的标准 bin
、lib
结构部署到任意路径而不需要运行前脚本?
最佳答案
你应该:
- 使用 rpath (Unix) 或 loader_path (MacOS)
- 或将其安装在常规系统路径中(/usr/lib 或/usr/local/lib 等...)
- 或使用
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
进行 introspec。
注 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}
)
关于linux - CMake 安装到 bin/lib 但应用找不到 lib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48419185/