为一个真实的软件包制作 ebuild

jopen 9年前


在『初探 ebuild』文中讲述了 Portage 树与 ebuild 文件的基本知识。这一篇利用这些基本知识来为一个真实的软件包写一份 ebuild 文件,通过这一实例可以大致了解如何使用 Eclass 中的函数。

OCE

要安装的软件包是 OCE ,它是 Open CASCADE 项目 的社区版本。Open CASCADE 是一个开源的三维几何建模引擎。OCE 是一些非 Open CASCADE 官方的开发者在 Open Cascade 项目的基础上改进并及时纳入新补丁的项目。可以认为 OCE 项目是 Open CASCADE 项目的激进版。之所以要安装 OCE,是因为需要将其作为 FreeCAD 的几何核心。以后我会再写一个安装 FreeCAD 的 ebuild。

获取 GIT 仓库中的源代码

在『 初探 ebuild 』文中谈到,只需在 ebuild 文件中定义SRC_URI变量,ebuild.sh脚本便可以根据SRC_URI的值自动下载源码包。现在我们面临的问题是如何从 Git 仓库的服务器端迁出 OCE 源码,这时SRC_URI便无效了,需定义EGIT_REPO_URI这个变量,其值为 git 仓库地址。

即使在 ebuild 中定义了EGIT_REPO_URI,ebuild.sh也不知道应该如何处理这个变量。因为根据EGIT_REPO_URI的值从 git 仓库迁出源码的函数是在/usr/portage/eclass/git-2.eclass中定义的,因此为了能够让ebuild.sh调用这个函数,需要使用inherit函数。inherit就类似于 C 语言的#include,可以载入/usr/portage/eclass中的 Eclass 文件。

下面这个 ebuild 文件足以从 github 服务器上迁出 OCE 源码了。

# Copyright 1999-2014 Gentoo Foundation  # Distributed under the terms of the GNU General Public License v2  # $Header: $    EAPI=5    inherit git-2    DESCRIPTION="This project aims at gathering patches/changes/improvements from the OCC community over the latest release"  HOMEPAGE="https://github.com/tpaviot/oce"    EGIT_REPO_URI="git://github.com/tpaviot/oce.git"    LICENSE="LGPL"  SLOT="0"  KEYWORDS="~amd64"

CMake 编译环境的配置

OCE 的构建环境支持 Autotools,也支持 CMake,但是推荐使用后者。ebuild.sh可以通过/usr/portage/eclass/cmake-utils.elcass中定义的一些函数来调用 CMake 完成 OCE 源码的编译与安装,但是必须事先使用inherit载入cmake-utils.eclass。

由于inherit函数支持多个参数,因此可将上文中的inherit行修改为:

inherit git-2 cmake-utils

这样便使得ebuild.sh具备了操控 CMake 的能力。

OCE 项目默认的 CMake 构建环境是将/usr/local作为源码编译结果的安装目录的前缀。如果是手动编译安装 OCE,那么/usr/local这个目录前缀似乎并不坏。但是现在我们是要让 Portage 来管理 OCE 的安装与卸载,如果不使用/usr作为目录前缀,给人的感觉是太不严肃了。因此,必须要将 OCE 安装到/usr目录中。要做到这一点,需要修改 OCE 的 CMake 默认的安装目录前缀。

cmake-utils.eclass的参考文档 中给出了修改 CMake 默认构建环境的标准做法,即:

src_configure() {          local mycmakeargs=(          )          cmake-utils_src_configure  }

我们只需在mycmakeargs这个 Bash 数组中给出我们期望的编译选项即可。由于我们的目的仅仅是想修改 OCE 默认的安装目录前缀,因此只需在mycmakeargs中给出OCE_INSTALL_PREFIX变量的定义,即:
src_configure() {          local mycmakeargs=(              -DOCE_INSTALL_PREFIX=/usr          )          cmake-utils_src_configure  }

至于OCE_INSTALL_PREFIX这个变量的来历,需要懂得一些 CMake 的知识。

也就是说,Eclass 只是通过 Bash 脚本对主流的项目构建工具进行封装,便于在 ebuild 文件中调用项目构建工具。只有懂得如何应用这些项目构建工具,方能具备 ebuild 来控制它们。

安装

首先需要创建/usr/local/portage/sci-libs/oce这个分类目录,然后在该目录中添加oce-9999.ebuile文件,内容如上一节所述。

之所以使用9999这个版本号,并不是出于中国对数字9的迷恋,而是用它来表示一个最新的版本号。也就是说,gentoo 开发者认为正常的软件版本号很少会大于这个数字,因此你安装的9999版本便不会被小于这个版本号的同一软件包覆盖。

然后使用生成oce-9999.ebuild的签名文件:

# cd /usr/local/portage/sci-libs.oce # ebuild ./oce-9999.ebuild manifest 

剩下的事情就是编译安装 OCE 的源码包了,即:

# emerge -avt oce 

上面这个命令做了很多工作:

  • 从 github 服务器迁出 OCE 源代码;

  • 在/var/tmp/portage目录开辟 OCE 的编译环境,即沙盒(Sandbox);

  • 在沙盒中编译 OCE 源码,并将编译结果复制到沙盒中指定的安装目录;

  • 将沙盒中的安装目录中的文件按照目录结构复制到/目录。

这一切的工作,都是在 ebuild 文件的指示下进行的。无论是 gentoo 的官方开发者还是我们这些业余 hackers,ebuild 文件是我们与 Gentoo 系统对话的媒介。

未尽之事

编译安装 OCE,不仅构建过程中需要依赖一些软件包, OCE 库在运行时也需要依赖一些软件包。普通用户只是希望能够尽快的安装 OCE 并让它能够正常运行,他们对 OCE 依赖哪些软件包并不关心,因为这是开发者的事。所以,OCE 的 ebuild 作者需要在身体力行的编译与使用 OCE 时了解它的所有依赖包,然后在 ebuild 文件中通过DEPEND与RDEPEND这两个变量告诉 Portage 系统:『要编译安装 OCE,你必须先安装 xxx、yyy……』

有关 OCE 的依赖包问题,留待日后再解决。