一尘不染

打包Linux专用软件

linux

我正在做跨平台开发,我想为Linux构建一个漂亮的,自包含的(!)软件包。我知道这不是通常的方式,但是应用程序需要将所有数据集中在一个地方,因此我将其安装到/
opt中,就像许多其他专有软件包一样。我最终将提供deb和rpm软件包,但目前仅是.tar.gz。用户应该将其提取到某个地方,并且应该可以工作。我宁愿没有安装程序。

首先是我的问题,然后是详细信息:

  1. 其他人如何打包Linux专用软件?
  2. 是否有用于打包软件(包括共享库)的工具?

现在获取一些详细信息:这是我的项目的布局(为此我将其称为 foo )布局:

  • foo(二进制)
  • config.ini
  • 数据

现在,在程序包中,将有两个附加元素:

  • foo.sh

libs 将包含项目所需的所有共享库,而 foo.sh 是一个脚本,用于将LD_LIBRARY_PATH设置为包括 libs 。因此,用户将执行
foo.sh ,程序应启动。

我有一个shell脚本,可以按以下步骤打包软件:

  1. 创建空目录并将foo.sh复制到该目录
  2. 调用构建过程并 安装 到新目录中
  3. 从文件系统复制共享库
  4. 将所有内容打包为.tar.gz

你觉得这怎么样?这种方法存在一些问题:

  • 我必须对所有依赖项进行硬编码两次(一次在CMake中,一次在打包脚本中)
  • 我必须两次定义版本号(一次在源代码中,一次在打包脚本中)

你怎么做呢?

编辑: 刚刚出现的另一个问题:如何确定软件所依赖的库?我做了一个 ldd foo
,但是有很多。我查看了WorldOfGoo软件包的外观,它们仅提供了很少的库。我该如何假设哪个库将出现在用户的系统上而哪个库不存在?只需将所有目标发行版安装到虚拟机中,看看有什么要求?


阅读 198

收藏
2020-06-07

共1个答案

一尘不染

通用问题

打包(带有相关库)/opt内容的方法是打包专有(甚至是开源)软件的方式。这是Linux
Foundation的推荐做法。

外部库既可以从头开始编译,也可以作为一个单独的步骤(尤其是如果您对其进行了修改)嵌入到您的构建过程中,也可以从某些发行版的软件包中获取。第二种方法比较容易,但是第一种方法具有更大的灵活性。

请注意,没有必要在软件包中包含一些真正的底层库(例如glibc,Xorg)。他们最好留给系统供应商进行调整,而您可能只是假设它们存在。此外,还有一个Linux标准库,其中记录了最重要的库。这些库几乎无处不在,并且可以信任。

还要注意,如果您是在较新的系统下编译,则很可能旧系统的用户将无法使用它,反之则不然。因此,为了达到更好的兼容性,在比今天早两年的系统下编译软件包可能会很有用。

我只是概述了一些通用的内容,但是我相信Linux Developers
Network
网站包含有关打包和可移植性的更多信息。

打包

从我在开放源代码分发项目中看到的内容来看,您的脚本以与分发供应商打包软件相同的方式进行操作。他们的脚本会自动修补源代码,模拟软件安装并将结果文件夹打包到DEB和RPM中。

当然,Tar.gz也可以工作,但是例如创建RPM并不足够复杂,以至于您错过了使用户生活变得如此轻松的机会。

回答您的问题,

  • 是的,您必须对依赖项进行两次硬编码。

事实是,当您在CMake中对它们进行加固时,可以使用其他术语来指定它们,而不是在打包脚本中指定它们时。CMake是指 共享库头文件
,而打包脚本是指 软件包

程序包名称与共享库和标头之间没有交叉分布的一对一关系。它随分布而变化。因此,应指定两次。

但是,发行版供应商可以很容易地重新打包该软件包,尤其是当您努力将所有相关的lib打包到其中时(这样对port的外部依赖性就会减少)。另外,一个可以将软件包从一个发行版本移植到另一个发行版本的工具将很快出现(发布时我将更新我的答案)。

  • 是的,您必须指定两次版本。

但事实是,您可以以一种 打包和软件版本永远不会同步
的方式来组织打包过程。只需使打包脚本从您的存储库中签出(或从您的网站下载),就与该脚本将写入包装规范的版本完全相同。

分析依赖

要分析软件的依赖性,您可以使用我们的开放源代码,免费的Linux Application Checker工具。它将报告它所依赖的库列表,显示与您的软件兼容的发行版,并帮助您的应用程序在各个发行版之间更具可移植性。事实证明,有时只需付出很少的努力就可以实现更多的跨发行版兼容性,而您不必将自己锁定在仅支持少数几个发行版的支持上。

2020-06-07