Alpine Linux编译package

背景

最近由于工作原因需要使用WiredTiger特定版本去修复数据,查看了各个Docker镜像发现支持的版本不一样,比如Ubuntu支持3.2.1,Alpine Linux3.16支持到3.0.0。原本想使用Alpine Linux编译下3.2.1版本,发现编译通过不了,索性不整了,把官方的3.0.0的编译脚本学习下,借机会学下Apline Linux平台的包编译。

Alpine Linux Package

平台使用Ubuntu平台,包格式是deb包,Alpine Linux平台使用apk格式的package。

官方维护有官方的仓库,但是每个版本的pacakge有变化,比如Alpine Linux v3.16维护了libexecinfo-dev,但是后面的版本没有了,wiredtiger在v3.9后就不维护了。

每个版本的apk包的编译脚本在官方的aports中维护,里面包括不同类型的仓库,包括main、community、testing。

编译apk包使用abuild命令,需要在Alpine中安装alpine-sdk,她依赖abuild、build-base、git。

本文主要利用wiredtiger官方脚本在v3.16中编译成apk包。

Package Build

包编译最重要的文件是APKBUILD,类似shell脚本,里面包含了编译相关的各种信息,官方维护的aport里面有所有软件的APKBUILD。APKBUILD里面的变量解释本文不介绍,遇到了可以查看官方文档。下面看下wiredtiger的官方脚本。

bash 复制代码
# Maintainer: Philipp Andronov <filipp.andronov@gmail.com>
# Contributor: Marc Vertes <mvertes@free.fr>

pkgname=wiredtiger
mongodb_version=3.6.3
pkgver=3.0.0.$mongodb_version
pkgrel=0
pkgdesc="High performance, scalable, production quality, NoSQL, Open Source extensible platform for data management"
url="http://www.wiredtiger.com"
arch="x86_64"
license="(GPL-2.0 or GPL-3.0) and MIT and BSD"
depends=""
depends_dev="autoconf automake libtool linux-headers"
makedepends="$depends_dev lz4-dev zlib-dev snappy-dev libexecinfo-dev"

options=""
subpackages="$pkgname-doc $pkgname-dev $pkgname-libs"

install=""
source="$pkgname-$pkgver-mongodb-$mongodb_version.tar.gz::https://github.com/wiredtiger/wiredtiger/archive/mongodb-$mongodb_version.tar.gz
	makemake-remove-libtool-version.patch
	10-fix-code-generator.patch
	"

_builddir="$srcdir"/$pkgname-mongodb-$mongodb_version
prepare() {
	local i

	cd "$_builddir"
	for i in $source; do
		case $i in
		*.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
		esac
	done
	sh autogen.sh || return 1
}

build() {
	cd "$_builddir"
	./configure --prefix=/usr \
		--disable-static \
		--enable-verbose \
		--enable-lz4 \
		--with-builtins=zlib,snappy \
		|| return 1
	make || return 1
}

package() {
	cd "$_builddir"
	make DESTDIR="$pkgdir" install
	install -Dm644 LICENSE "$pkgdir"/usr/share/licenses/$pkgname/LICENSE
}
sha512sums="051342439eea7bfb65dddbd42eab646bc007e9768d8bb82aeab6245cefcc99f9c3acae66a4caf60304256fd2cd55ceeba8b09b91743756b36ec6f367281070ca  wiredtiger-3.0.0.3.6.3-mongodb-3.6.3.tar.gz
9eb56a81cbf0b8c695ab86d5c6aa319aee8e6ffc4d4ac94c5ecb17a639cab352f83fdf15db467d3f2961cd05fd00c2b96c3cc357daa32972dd07fb3dfa95852f  makemake-remove-libtool-version.patch
a24360c18a8dd677a1942fc66ecdfdb8bc514af6de3e19be822293fdc83c051c43f3270f91eaa4524f30b5bc82c6ecad5162ce5b3f5ff470bab4e1a5d9eb79ec  10-fix-code-generator.patch"

上述是官方的WiredTiger的脚本,脚本类似shell脚本,里面的各种variable名字已经说明了,可以参考官方文档。主要是全局环境变量和lifecycle自定义函数,其中有两个注意点:

  1. patch文件。apk编译支持patch文件,使用git diff生成,比如
bash 复制代码
git diff dist/s_typedef > fix-code-generator-3_2_1.patch
  1. 最后的sha512sums是可以官方命令根据source参数生成
bash 复制代码
# 需要进入有APKBUILD文件的文件夹执行
abuild checksum

当APKBUILD和patch文件完成后,在当前目录中执行

bash 复制代码
REPODIST=~/packages/ abuild -r

Docker环境下编译

有了大致了解后,因为没有Alpine Linux环境,可以使用Docker环境,方便快捷,关键还不污染宿主机环境。 在实验中,中间经过了大量的测试,下面Dockerfile是最终脚本。

bash 复制代码
# Dockerfile 
# docker build --progress plain -t wiredtiger-multistep:0.0.2 . 2>&1 | tee build.log 
FROM alpine:3.16 as builder 
COPY APKBUILD 10-fix-code-generator.patch makemake-remove-libtool-version.patch /home/packager/wiredgiter/main/wiredtiger/ 
RUN set -x;\ 
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories; \
    apk update; \ 
    apk add --update --no-cache --no-progress alpine-sdk build-base sudo; \ 
    adduser -D packager; \ 
    addgroup packager abuild; \ 
    echo 'packager ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/packager; \ 
    chown -R packager:packager /home/packager 
USER packager 
WORKDIR /home/packager/wiredgiter/main/wiredtiger/ 
RUN set -x; \ 
    abuild-keygen -n --append --install ; \ 
    REPODEST=~/packages/3.16 abuild -r 
    
FROM alpine:3.16 as prod 
# 注意apk的位置 
COPY --from=builder /home/packager/.abuild/*.pub /etc/apk/keys/ 
COPY --from=builder /home/packager/packages/3.16/main/x86_64/wiredtiger*.apk /tmp/ 
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories; \ 
    apk add /tmp/wiredtiger-libs-3.0.0.3.6.3-r0.apk; \ 
    apk add /tmp/wiredtiger-3.0.0.3.6.3-r0.apk

注意

Alpine Linux编译package的最终地址整了半天,最终地址为:$REPODEST/$repo,其中REPODEST默认为$HOME/packages,这个默认值在/etc/abuild.conf文件夹中设置

bash 复制代码
repo=${startdir%/*}
repo=${repo##*/}

其中startdirAPKBUILD所在目录,所以repo实际上是APKBUILD上一级文件夹名称,比如APKBUILD位于/home/packager/wiredtiger/main/wiredtiger中,那repo就是main

所以默认情况下地址为:/home/packager/packages/main/,最终还会填上平台文件夹。

附录

abuild编译时中默认环境变量

bash 复制代码
startdir="APKBUILD脚本所在的文件夹" 
srcdir=${srcdir:-"$startdir/src"} 
pkgbasedir=${pkgbasedir:-"$startdir/pkg"} 
repo=${startdir%/*} 
repo=${repo##*/} 
builddir=${builddir:-"$srcdir/$pkgname-$pkgver"}

默认abuild.conf文件

bash 复制代码
export CFLAGS="-Os -fomit-frame-pointer"
export CXXFLAGS="$CFLAGS"
export CPPFLAGS="$CFLAGS"
export LDFLAGS="-Wl,--as-needed,-O1,--sort-common"
export GOFLAGS="-buildmode=pie"
# Do note that these should work with at least GDC and LDC
export DFLAGS="-Os"

export JOBS=$(nproc)
export MAKEFLAGS=-j$JOBS
export SAMUFLAGS=-j$JOBS
export CARGO_BUILD_JOBS=$JOBS

# remove line below to disable colors
USE_COLORS=1

# uncomment line below to enable ccache support.
#USE_CCACHE=1

SRCDEST=/var/cache/distfiles

# uncomment line below to store built packages in other location
# The package will be stored as $REPODEST/$repo/$pkgname-$pkgver-r$pkgrel.apk
# where $repo is the name of the parent directory of $startdir.
REPODEST=$HOME/packages/

# PACKAGER and MAINTAINER are used by newapkbuild when creating new aports for
# the APKBUILD's "Contributor:" and "Maintainer:" comments, respectively.
#PACKAGER="Your Name <your@email.address>"
#MAINTAINER="$PACKAGER"

# what to clean up after a successful build
CLEANUP="srcdir bldroot pkgdir deps"

# what to cleanup after a failed build
ERROR_CLEANUP="bldroot deps"

参考资料

替换国内源
查看Alpine Linux软件
wiredtiger aports APKBUILD脚本
APKBUILD Reference
Alpine编译apk安装包
Alpine Linux支持的平台
本地搭建第三方Alpine repo
create an Alpine package
How to Build an Alpine Linux Package
Building / consuming alpine Linux packages inside containers and images
BUILD ALPINE PACKAGES IN A TEMPORARY CONTAINER
WiredTiger document
all about APK build

相关推荐
想用offer打牌12 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅13 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606113 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX13 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了14 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅14 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅14 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法14 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅14 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment14 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端