在我的一个工作项目中,注意到以下内容并向我询问。 二进制文件将链接,然后再次链接到名为“Relink”文件夹的文件夹中。 我也检查了二进制文件在两个地方,并且链接发生了两次。
使用的CMAKE版本是2.6 - 补丁2。
我发现在build文件夹中,生成的cmake_install.cmake包含以下条目
IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" MATCHES "^(Unspecified)$")
IF("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/path/to/binary/file/folder/CMakeFiles/CMakeRelink.dir/<binary name>").....
如果在CMAKE中使用INSTALL,并且未使用install命令创建COMPONENT并且构建是Debug构建,则会创建此Relink文件夹并将二进制文件链接两次。问题是为什么会发生这种情况? 链接两次会增加过度构建时间。 那么这个目的是什么呢? 如果省略Install命令或构建是Debug构建,则不会发生这种情况。 为什么不,如果构建是否是Debug构建,为什么它是相关的? 我搜索了文档和这个网站,但找不到解释。
示例输出:
.....
Linking CXX shared library lib<library-name>.so <== Linking the first time
[100%] Built target <another library name>
[ 15%] Built target <another-library-name1>
[ 92%] Built target <another-library-name2>
[ 92%] Built target <another-library-name3>
[100%] Built target <another-library-name4>
[100%] Built target <another-library-name5>
Linking CXX shared library CMakeFiles/CMakeRelink.dir/lib<library-name>.so <== Second linking.
当添加以下CMAKELists条目
时,将显示此Relink目录install(TARGETS <binary/library name>
RUNTIME
DESTINATION "bin")
因此,将此构建为Debug构建和非COMPONENT安装会显示此行为。 构建在Jenkins上的相同代码没有这个,因为Jenkins构建是Release / Optimized构建而不是Debug构建。
答案 0 :(得分:2)
看起来在安装二进制文件之前重新链接与在构建中保留RPATH有很大关系。
所以我尝试完成对COMPONENT定义的初始检查,然后看到生成的CMake,它显示了要实现的新条件。 在这里找到一些相关信息 http://public.kitware.com/pipermail/cmake/2006-October/011377.html
因此,在启用COMPONENT构建的测试项目中,对于cmake的INSTALL命令,再次发生重新链接以满足此时间的另一个条件。在这种情况下,选中install_public选项,该选项已在项目中启用。
IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" MATCHES "^(install_public)$")
IF("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib64" TYPE SHARED_LIBRARY
#install CMakeRelink.dir/<library_name>.so.<library_version> ......
此处的一些信息也在文档中 https://cmake.org/Wiki/CMake_2.8.0_Docs
在上述链接中搜索重新链接。 所以我在应用程序CMAKEList中通过改变CMAKELists.txt并将CMAKE_INSTALL_RPATH设置为OFF来测试另一个构建。 这也阻止了双重链接。