jme*_*kow 5 linux installation cmake
我正在做一个项目,我们正在开始发行二进制文件。我们正在使用CMake来生成构建文件,并使用CPack来创建二进制文件。我们的二进制文件可以工作,但是我们遇到共享对象的问题。本质上,许多问题是由系统上的符号链接引起的,尤其是对于具有多个链接的共享对象。因此,可以说来自ldd(或otool)的某些可执行文件包括libmpich.so.10的RPATH结果,并且我已经从cmake链接了/usr/lib/x86_64-linux-gnu/libmpich.so,这些文件都像这样关联:
/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
Run Code Online (Sandbox Code Playgroud)
现在,由于某种原因,RPATH使用中间链接(so.10),但libmpich.so上的readlink(或get_filename_component(... REALPATH))返回libmpich.so.10.0.4。因此,如果我以libmpich.so或libmpich.so.10.0.4的名称安装libmpich.so.10.0.4(或创建一个到另一个的符号链接),我仍然会错过RPATH中要求的库。
在处理这些问题和/或使用文件Glob尝试抢占中间链接时,我一直在打w鼠,但我想做一些更强大的事情。有人为此使用好的设计模式吗?
我一直在研究使用诸如GET_PREREQUISITES之类的功能,但是那些功能需要构建对象,因此我需要以某种方式将其添加到安装脚本中……。感觉它们应该是一种更好的方法。
-詹姆森
PS我也很想寻找有关使用cmake或一般情况下构建二进制文件的最佳实践指南。我们正在Windows,Linux和Mac上生成二进制文件。如果您知道一些好的链接,也请发布它们。
小智 4
我最近刚刚亲自处理过这个问题。cmake 命令 get_filename_component(... 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
Run Code Online (Sandbox Code Playgroud)