您可以使用cmake创建可重定位的安装(跨机器)吗?

时间:2018-06-20 08:43:10

标签: c++ cmake

我想从源代码构建第三方库,并为可与项目共享(可重定位)的预构建库具有可导入的cmake目标。

我正在建立的库有几种风格:

  • 现代cmake,可以导出目标
  • 旧cmake,它不导出目标,但可能具有pkgconf
  • Autoconf /经常包含pkgconf输出的常规makefiles
  • 没有构建文件的小批量订单。

库之间可能存在一些依赖关系,例如一些系统依赖关系:

  • LibA取决于LibB
  • LibB取决于系统上找到的某些库:sysLibXX,sysLibYY

问题

如何打包预构建的库,以便可以共享和导入cmake目标和预构建的库,以便在其他计算机上构建项目?

问题

  • 使用cmake“安装”到可以与项目共享的路径,会固有地产生不可重定位的依赖关系。例如,如果cmake找到了数学库libm,则将其写为由cmake /usr/lib/x86_64-linux-gnu/libm.so生成的生成的导出目标中的绝对路径。这不适用于其他具有不同系统库路径的机器。

    • 我可以以某种方式告诉cmake保持可重定位的库引用在导出的目标中吗? (例如:-lm
  • 并非所有软件包都导出cmake文件,即使它们导出,也可能会错误地执行。

    • 我应该手动编辑或重新编写XXConfig.cmake脚本以使其可重定位吗?

有用的见识

利用pkgconf或自动生成的导出目标之类的任何信息,描述从上述各种情况下的源到可再发行脚本的过程,将很有帮助。

例如:

使用香草生成脚本,我可以做到:

./configure --prefix="`pwd`/temp"
make
make install

然后也许我可以手动修复pkgconf脚本以删除绝对路径,并使用cmake功能在自定义XXConfig.cmake中读取pkgconf?

知道是否有人尝试过这种方法并对它的可维护性有一定了解,这将非常有帮助。

1 个答案:

答案 0 :(得分:0)

事实证明,cmake能够制作可重定位的程序包,问题主要出在遵循反模式的各种第三方库上。

https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-relocatable-packages

我已决定构建所有这样的第三方包装:

  • 受信任的库可以直接安装到可重定位的安装文件夹中。
  • 未写入临时位置的库会被清理以自动将完整链接路径转换为仅-lLib声明。

该脚本如下:

for FILE in ${CMAKE_FILES}; do
  # Find any paths that begin with "/usr/" and end with "/lib<something>.so"
  # And replace them with -l<something>
  # [^;] is used instead of .*, because ; delimites paths, and there's only greedy regex here.
  sed 's@/usr/[^;]*/lib\([^;]*\)\.so@-l\1@g' "${FILE}" > "${SCRUBBED_CMAKE_PATH}/${FILE#${TEMP_CMAKE_PATH}}"
  echo -e "Scrubbing ${FILE#${TEMP_CMAKE_PATH}}..."
  set +e  # disable error checking for a moment, because diff returns non-0 error codes intentionally
  diff "${FILE}" "${SCRUBBED_CMAKE_PATH}/${FILE#${TEMP_CMAKE_PATH}}"
  set -e  # re-enable error checking
done

这真的不是可移植的,并且处理起来很烦人,因此,如果我能够解决不可重定位的问题,我倾向于尝试先破解第三方CMakeScripts.txt。即。 https://github.com/leethomason/tinyxml2/pull/681