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

相关推荐
蓝染-惣右介19 分钟前
【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)
java·前端·后端·vue·springboot
齐 飞23 分钟前
Java接口和抽象类的区别
java·笔记·后端
打鱼又晒网30 分钟前
你了解system V的ipc底层如何设计的吗?消息队列互相通信的原理是什么呢?是否经常将信号量和信号混淆呢?——问题详解
linux·运维·服务器·后端·操作系统
(⊙o⊙)~哦40 分钟前
spring boot 定时器配置
java·spring boot·后端
我码玄黄1 小时前
HTML翻牌器:用CSS和HTML元素创造动态数字展示
前端·css·html
-草莓星球杯1 小时前
若依VUE项目安全kind-of postcss vite漏洞扫描和修复
前端·javascript·vue.js
LJ小番茄1 小时前
关于wordPress中的用户登录注册等问题
前端·javascript·css·html·wordpress
C—328G1 小时前
flask
后端·python·flask
小郝同学(恩师白云)2 小时前
SpringMVC后续4
java·服务器·前端
优联前端2 小时前
uni-app-通过vue-cli命令行快速上手
开发语言·前端·vue.js·uni-app·优联前端