为 Linux 打包专有软件

2023-11-24

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

首先是我的问题,然后是细节:

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

现在了解一些细节:这是我的项目(我称之为foo为此目的)布局:

  • foo(二进制)
  • 配置文件
  • data

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

  • libs
  • foo.sh

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

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

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

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

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

你怎么做呢?

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


一般问题

将你的东西(带有依赖库)打包到/opt这就是专有(甚至开源)软件的打包方式。 Linux 基金会推荐的做法(请参阅我对另一个问题的回答用于链接)。

外部库可以从头开始编译并作为单独的步骤嵌入到构建过程中(特别是如果您修改它们),也可以从某些发行版的包中获取。第二种方法更容易,但第一种方法具有更大的灵活性。

请注意,没有必要将一些非常低级的库(例如 glibc、Xorg)包含到您的包中。它们最好留给系统供应商来调整,您可能只是假设它们存在。此外,还有一个Linux 标准库,记录了最重要的库;这些库几乎无处不在,并且值得信赖。

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

我只是概述了一些通用的东西,但我相信Linux 开发者网络网站包含有关包装和便携性的更多信息。

包装

根据我在开源分发项目中看到的情况来看,您的脚本的执行方式与分发供应商打包软件的方式相同。他们的脚本自动修补源代码、模拟软件安装并将生成的文件夹打包到 DEB 和 RPM 中。

当然,Tar.gz 也可以,但是创建 RPM 之类的东西还不够复杂,您不会错过这样一个让用户的生活变得更加轻松的机会。

回答您的问题,

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

    问题是,当您在 CMake 中对它们进行硬编码时,您可以使用其他术语来指定它们,而不是在打包脚本中指定它们。 CMake指的是共享库 and 头文件,而打包脚本指的是packages.

    包名称与共享库和标头之间不存在跨发行版的一对一关系。它因发行版而异。因此,应指定两次。

    但是发行版供应商可以轻松地重新打包该包,特别是如果您努力将所有依赖库打包到其中(因此需要移植的外部依赖项会更少)。此外,一种可以将软件包从一个发行版移植到另一个发行版的工具很快就会出现(我将在发布时更新我的​​答案)。

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

    但问题是你可以这样组织你的包装过程:软件包和软件版本永远不会不同步。只需使打包脚本从您的存储库中签出(或从您的网站下载)与脚本将写入包规范的版本完全相同即可。

分析依赖关系

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 Linux 打包专有软件 的相关文章

  • 在centos中安装sqlite3 dev和其他包

    我正在尝试使用 cpanel 在 centos 机器上安装 sqlite dev 和其他库 以便能够编译应用程序 我对 debian 比 centos 更熟悉 我知道我需要的库是 libsqlite3 dev libkrb5 dev lib
  • Linux 上的静态 Qt5 构建:部署时如何处理字体?

    我使用这些配置选项创建了 Qt 5 2 0 库的静态版本 Ubuntu 12 04 开源 确认许可 force pkg config 发布 静止的 前缀 home juzzlin qt5 无icu opengl桌面 无油嘴滑舌 辅助功能 n
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • C 语言的符号表

    我目前正在开发一种执行模式匹配的静态分析工具 我在用Flex https github com westes flex生成词法分析器 我编写了代码来管理符号表 我不太有经验C 所以我决定将符号表实现为线性链表 include
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • 打包 Perl 应用程序,以便它可以在 Perl 的默认前缀之外工作

    我正在使用 Module Build 尽管我在构建环境上很灵活 来打包我正在编写的一些 Perl 软件 供我工作的内部使用 它包括一些脚本和一些辅助模块 我的计划是这样你就可以指定任何你想要的前缀 即perl默认值之外的东西 INC 在构建
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • Linux 为一组进程保留一个处理器(动态)

    有没有办法将处理器排除在正常调度之外 也就是说 使用sched setaffinity我可以指示线程应该在哪个处理器上运行 但我正在寻找相反的情况 也就是说 我想从正常调度中排除给定的处理器 以便只有已明确调度的进程才能在那里运行 我还知道
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • cdc_acm:无法设置 dtr/rts - 无法与 USB cdc 设备通信

    我试图使用 pic24fj128gb206 枚举 usb cdc 设备 设备似乎已正确枚举 但是当我将设备连接到 Linux PC 时 我从内核收到以下警告消息 cdc acm 1 8 1 6 7 1 0 failed to set dtr
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 为什么 XRecordDisableContext() 不起作用?

    void Callback XPointer XRecordInterceptData pRecord std cout lt lt my logs n int main if auto const pDisplay XOpenDispla
  • 如何wget目录中最新的文件

    我想编写一个 bash 脚本来下载并安装最新的每日构建程序 RStudio 是否有可能使wget仅下载目录中最新的文件http www rstudio org download daily desktop http www rstudio
  • 如何在shell脚本中给出密码?

    在 shell 脚本文件中 我使用一些命令 例如scp and make install要求我输入密码 我运行一个 shell 脚本来编译一个大项目 一段时间后它会要求我输入密码才能使用scp 我需要等待该过程并在此之后提供密码 我只想通过
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • 如何找到进程启动时使用的原始用户名?

    有一个 perl 脚本需要以 root 身份运行 但我们必须确保运行该脚本的用户最初没有以用户 foo 身份登录 因为它将在脚本运行期间被删除 那么 我如何查明自登录以来可能已多次起诉的用户是否在该链中的任何时间都没有模拟过 foo 我发现
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu

随机推荐