前言
有时候某些软件的构建往往会依赖自身进行编译,这时候就需要使用Bootstrap构建方法。
本教程仅简单列举一些新人相对容易理解的、常见的Bootstrap构建方法,对于复杂的问题,可能需要额外的具体研究。
注意事项
首次通过“不干净”的方法生成的软件包请勿上传,请将这一文件添加到本地仓库,再使用官方的构建文件(或者基于官方构建文件应用了我们补丁集中的补丁的),进行正式的打包,然后上传,保证构建的可复现性。
上游给出Bootstrap构建方法的情况
某些软件包官方会给出Bootstrap构建方法,因此我们需要注意查看官方文档中是否有相关说明。
例子:vala
Vala是一种为GObject设计的高级编程语言,Vala编译器会将Vala代码编译成C代码,然后再编译成二进制文件。Vala编译器本身也是用Vala语言编写的,因此在编译Vala编译器时,我们需要使用Bootstrap构建方法。Vala官方给出了Bootstrap构建方法:Vala官方会直接发布包含Vala代码及其生成的中间C代码的tarball,我们只需要解压这个tarball,然后再禁用Vala编译,指定使用C编译器编译即可。
因此,我们只需要对Arch Linux官方的vala
软件包的PKGBUILD文件进行修改,得到vala-bootstrap
软件包的PKGBUILD文件即可。
- 修改包名并增加
provides
字段 - 修改
source
字段,使用Vala官方发布的tarball替代git源码 - 去掉对
vala
的依赖 - 根据Vala的Bootstrap文档,在构建时指定
VALAC=/no-valac
_pkgname=vala
pkgname="$_pkgname-bootstrap"
pkgver=0.56.17
pkgrel=1
pkgdesc='Compiler for the GObject type system'
url='https://wiki.gnome.org/Projects/Vala'
arch=(x86_64)
license=(LGPL-2.1-or-later)
depends=(
gcc
glib2
glibc
graphviz
gtk-doc
pkg-config
ttf-font
)
makedepends=(
autoconf-archive
git
help2man
libxslt
)
checkdepends=(
dbus
gobject-introspection
libx11
)
provides=(
libvala{,doc}-${pkgver%.*}.so
valadoc
$_pkgname
)
conflicts=(valadoc)
replaces=(valadoc)
source=("http://download.gnome.org/sources/vala/${pkgver%.*}/vala-$pkgver.tar.xz")
b2sums=('c4b8d5b7c810893728f82d2cbbf2f0dd70ad17bd4eeb323ab5d31d99f37b5a5508b7d2447f0249f3a925013d7110bb6f145b32c833b990b15f18d9949035293f')
build() {
cd "vala-$pkgver"
VALAC=/no-valac ./configure --prefix=/usr
sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
make
}
check() {
cd "vala-$pkgver"
make check
}
package() {
cd "vala-$pkgver"
make DESTDIR="$pkgdir" install
}
这样的vala-bootstrap
软件包构建完成后,我们可以将其添加到本地仓库,然后使用vala-bootstrap
软件包构建vala
软件包。最后,我们再将得到的干净的vala
软件包上传。
利用其他发行版的二进制包构建
如果某个软件包在Loong Arch Linux上还没有,但是其他支持LoongArch的发行版上已经构建好了二进制包,我们可以尝试使用其他发行版的二进制包构建。我们同样可以构建一个-bootstrap
软件包,然后在build()
或者package()
函数中,使用bsdtar
解压其他发行版的二进制包,直接安装到$pkgdir
中。(同样需要注意添加provides
字段)
这一方法容易遇到一些问题:
- 不同发行版的路径结构可能不同,有时候可能需要手动调整
- 比如
/usr/lib
和/usr/lib64
的区别 - 比如
/usr/bin
和/usr/local/bin
的区别
- 比如
- 不同发行版的二进制包可能有不同的依赖
- 可能会遇到链接到不存在的库的问题
- 包括依赖缺失或者soname不同
- 需要手动调整或者导入依赖包
- 可能会遇到链接到不存在的库的问题
利用有“功能替代”作用的其他软件包构建
某些软件包一般是需要自身构建的,但是有时候我们可以利用有“功能替代”作用的其他软件包构建。
一个非常常见的例子就是gcc系列的编译器与llvm系列的编译器往往有相互对应或者近似相互对应的关系。
当然,有时候直接代替构建可能会出现问题,还需要根据具体情况调整编译参数、引入组件、临时禁用功能等。
例子:ldc
LDC编译器是基于LLVM的D语言编译器。Loong Arch Linux在还没有LDC时就已经有了GDC(GDC是基于GCC的D语言编译器)。因此我们可以利用GDC构建LDC。
然而,如果我们直接将makedepends
中的ldc
替换为gcc-d
就构建,会出现以下问题:
CMake Error at cmake/Modules/FindDCompiler.cmake:80 (message):
No supported D compiler (ldmd2, dmd, gdmd) found! Try setting the
'D_COMPILER' variable or 'DMD' environment variable.
这是因为LDC的CMake脚本在检测D编译器时,只支持ldmd2
、dmd
和gdmd
这些接受D语言参考实现dmd
参数风格的编译器,而实际上gcc-d
并没有提供gdmd
(不同的是ldc
是提供ldmd2
的)。
PS: 对于新手来说,上面这条知识本身可能不是那么关键,因为它已经被记录在我的教程里面了,很容易查阅到。但是笔者是怎么知道的呢?在遇到相关问题时知道怎么查/怎么做可能才更关键。笔者此前也对D语言编译器相关的一切完全不了解,遇到这个问题时,笔者首先去AUR查找了gdmd
,找到了gdmd-git
这个包,包的描述是DMD-like wrapper for GDC
,即gdmd
是GDC
的DMD
的包装器。再去专门查找一下相关知识,即可知道想要构建ldc
,仅仅有gcc-d
是不够的,还需要gdmd
,因此笔者打包了AUR的gdmd-git
并添加到本地仓库,然后在ldc
的PKGBUILD文件中添加了gdmd
到makedepends
中。
从AUR获取gdmd-git
并构建、添加到本地仓库,且在修改的ldc
的PKGBUILD文件中额外添加gdmd
到makedepends
后,即可尝试构建ldc
。
然而,这样直接构建时又会遇到问题。Arch Linux的ldc
软件包的PKGBUILD文件中指定了一些编译参数:
...
-DD_COMPILER_FLAGS="-link-defaultlib-shared=false -linker=lld --flto=thin" \
-DADDITIONAL_DEFAULT_LDC_SWITCHES="\"-link-defaultlib-shared\"," \
...
经过尝试,我们可以发现,gdmd
并不能接受这些参数,进而报错。我们可以在build()
函数中,临时禁用这些参数再次构建。
构建完成后,我们可以将ldc
软件包添加到本地仓库,然后使用这一用gcc-d
构建的ldc
软件包,利用Arch Linux官方的ldc
的PKGBUILD文件,构建干净的ldc
软件包。
不幸的是,我们又会遇到一个与架构及发行版环境有关的问题,即ldc
这一软件包本身需要Patch。如果直接按照官方的PKGBUILD文件构建,在check阶段会报错:
/usr/bin/ld: /build/ldc/src/ldc/build/lib/libdruntime-ldc-unittest-shared.so: undefined reference to `__atomic_compare_exchange_16'
/usr/bin/ld: /build/ldc/src/ldc/build/lib/libdruntime-ldc-unittest-shared.so: undefined reference to `__atomic_load_16'
/usr/bin/ld: /build/ldc/src/ldc/build/lib/libdruntime-ldc-unittest-shared.so: undefined reference to__atomic_store_16'
collect2: error: ld returned 1 exit status
可见,libatomic
库的链接问题导致了这一测试用例的构建失败。此时需要在CMake配置时显式指定链接到libatomic
库:
...
-DLD_FLAGS="-Wl,--no-as-needed -latomic -Wl,--as-needed" \
...
然后再次构建,即得到了干净且测试全部通过的ldc
软件包。上传补丁和ldc
软件包即可。