Linux 使用共享对象和符号链接构建安装包
我正在做一个项目,我们正在开始发布二进制文件。我们使用CMake生成构建文件,使用CPack创建二进制文件。我们的二进制文件可以工作,但是我们遇到了共享对象的问题。从本质上讲,许多问题都是由系统上的符号链接引起的,尤其是具有多个链接的共享对象。因此,假设某些可执行文件包括libmpich.So.10的ldd(或otool)的RPATH结果,我已经从cmake链接了/usr/lib/x86_64-linux-gnu/libmpich.So,这些文件如下所示:Linux 使用共享对象和符号链接构建安装包,linux,installation,cmake,Linux,Installation,Cmake,我正在做一个项目,我们正在开始发布二进制文件。我们使用CMake生成构建文件,使用CPack创建二进制文件。我们的二进制文件可以工作,但是我们遇到了共享对象的问题。从本质上讲,许多问题都是由系统上的符号链接引起的,尤其是具有多个链接的共享对象。因此,假设某些可执行文件包括libmpich.So.10的ldd(或otool)的RPATH结果,我已经从cmake链接了/usr/lib/x86_64-linux-gnu/libmpich.So,这些文件如下所示: /usr/lib/x86_64-lin
/usr/lib/x86_64-linux-gnu/libmpich.so -> libmpich.so.10
/usr/lib/x86_64-linux-gnu/libmpich.so.10 -> libmpich.so.10.0.4
/usr/lib/x86_64-linux-gnu/libmpich.so.10.0.4
现在,由于某种原因,RPATH使用中间链接(so.10),但libmpich.so(或get_filename_组件(…REALPATH))上的readlink返回libmpich.so.10.0.4。因此,如果我以libmpich.So或libmpich.So.10.0.4的名称安装libmpich.So.10.0.4(或创建从一个到另一个的符号链接),我仍然错过了RPATH中要求的库
在处理这些问题和/或使用文件glob试图抓住中间链接时,我一直在打鼹鼠,但我想做一些更健壮的事情。有人用一个好的设计模式吗
我一直在研究如何使用诸如GET_Premissions之类的函数,但这些函数需要构建对象,因此我需要以某种方式将它们添加到安装脚本中。。。。感觉他们的方式应该更好
-詹姆逊
另外,我还一直在寻找构建二进制文件的最佳实践指南,可以是使用cmake,也可以是通用的。我们正在windows、linux和mac上生产二进制文件。如果你知道一些好的链接,请也发出来。我最近刚刚处理了这个问题。cmake命令get_filename_组件(…REALPATH)在一次调用中解析符号链接的所有级别 要解决单一级别的符号链接,您可以直接从cmake调用“readlink”,因为它可以在您可能构建的所有支持符号链接的平台(Linux、Mac OS X和*BSD)上使用 所以,如果你想复制完整的符号链接链, 您可以在cmake脚本中编写如下代码:
#If given the following library path:
set(lib "/usr/lib/x86_64-linux-gnu/libmpich.so")
#Make sure the initial path is absolute.
get_filename_component(lib "${lib}" ABSOLUTE)
#Store initial path as first element in list.
set(symlist "${lib}")
while(UNIX AND IS_SYMLINK "${lib}")
#Grab path to directory containing the current symlink.
get_filename_component(sym_path "${lib}" DIRECTORY)
#Resolve one level of symlink, store resolved path back in lib.
execute_process(COMMAND readlink "${lib}"
RESULT_VARIABLE errMsg
OUTPUT_VARIABLE lib
OUTPUT_STRIP_TRAILING_WHITESPACE)
#Check to make sure readlink executed correctly.
if(errMsg AND (NOT "${errMsg}" EQUAL "0"))
message(FATAL_ERROR "Error calling readlink on library.")
endif()
#Convert resolved path to an absolute path, if it isn't one already.
if(NOT IS_ABSOLUTE "${lib}")
set(lib "${sym_path}/${lib}")
endif()
#Append resolved path to symlink resolution list.
list(APPEND symlist "${lib}")
endwhile()
#Now symlist will contain the following:
# [...]/libmpich.so;[...]/libmpich.so.10;[...]/libmpich.so.10.0.4