如何管理从源代码安装的软件?

时不时地,我们可能需要从源代码安装一些东西,原因各种各样。虽然对于给定适当依赖的软件如何安装是相当标准的,但我不清楚如何管理这种安装以便将来更加方便。
更具体地说:
1. 为了确保轻松且干净地卸载(包括那些刚刚为从源代码安装的软件而安装的依赖项),我们可以采取哪些措施?
2. 为了确保同一软件的轻松且干净的升级(很可能再次从源代码安装),我们可以采取哪些措施?
3. 如果既有默认包(使用apt-get安装)又有该软件的(更新的)版本(从源代码安装),我们可以采取哪些措施来最大程度地减少潜在冲突?
4个回答

使用checkinstall make install命令将创建一个临时包并安装它。这意味着它会被记录在软件包管理器中,并可以进行卸载。

最好的做法是自己制作较新版本的Debian软件包。dpkg和apt工具可以完成你提到的三个任务,并且专为此目的而设计。使用它们而不是重新发明轮子。有很多关于打包的指南可供参考。如果软件已经存在于存储库中,你可能可以获取源代码包(apt-get src),用于学习和启动自己的软件包。
这个回答https://askubuntu.com/a/485230/158442可能对你作为一般指导有所帮助。
虽然checkinstall对于快速解决问题很好,但从长远来看,你应该使用适当的打包方法。

感谢您的建议。当您说“软件已存在于存储库中”时,我理解您指的是由Ubuntu维护的官方存储库。如果是这样,在许多情况下,这些存储库可能不提供更新版本,特别是在较旧的Ubuntu发布版上。因此,在这种情况下,“apt-get src”可能无法帮助。 - skyork
@skyork 也许他们不这样做。但是你可以使用旧版本的软件包来学习。打包人员可能会进行一些定制化操作,编写一些自定义维护脚本。没有理由忽视所有这些,从头开始。重复造轮子似乎是一个主题。 - muru

首先,很大程度上取决于您如何管理源代码。我会创建一个名为~/sources的目录,并将每个程序放在其子目录中,而其他人则会为每个程序创建一个新目录。
类似地,像我这样的人会为每个新版本创建一个新的子子目录,并且只有在确保新版本中没有重大错误会影响我的工作时才删除旧版本。
没有一种固定的方法来做到这一点,但无论您选择哪种方式,都要选择一种对您来说最容易管理的方式。
  1. 清理卸载

    • 我建议创建一个名为rem_dep.sh的脚本,内容如下:

      #! /bin/bash
      sudo apt-get remove dep1 dep2 ... depn
      

      其中dep1, dep2, depn是依赖项。

  2. 简洁易用的升级

    • 如果你从自动版本控制系统(如gitbazaar)获取源代码,或者链接是可预测的,你可以创建一个Shell脚本来执行以下操作:

      #1 备份旧版本
      #2 获取新的源代码
      #3 配置、构建/编译源代码
      #5 如果编译成功,删除旧版本
      #6 安装新版本,更新必要的依赖项
      
    • 在其他情况下,你也可以手动创建这样的脚本。

  3. 冲突管理

    • 最好的方法是在安装软件及其依赖项时使用--prefix选项。
    • 另一个重要的事情是保持系统更新,以尽量减少冲突。
注意:如果你发现自己编译的软件超过了你应该编译的数量(可以为自己设定一个最大限制,比如5个、10个或100个),最好离开Ubuntu并转向Arch Linux。

构建依赖:

据我所知,它们应该手动记录。您可以创建一个类似于README的文件来保存手动安装的依赖项列表。
如果该软件已经在Ubuntu或PPA存储库中有一个构建二进制文件。在安装过程中跟踪依赖关系应该更容易:
sudo apt-get build-dep 目标软件包

清理卸载:

保留已配置和安装的源文件夹。最好将所有源文件收集到特定文件夹,并包含已安装依赖项的文件。

清洁升级和已安装文件隔离:

将它们安装在特定的--prefix目录下(最好是--prefix=/opt/software_name-version/)。

这将解决许多问题:与仓库中的版本并行存在;清洁升级;如果源文件被删除,更容易进行不完全卸载。

更复杂或者最佳的方式,参考@muru的答案,在Debian软件包中构建(适用于Ubuntu/PPA仓库中可用的软件包)。