Alpine Package
- Creating an Alpine package
- https://wiki.alpinelinux.org/wiki/APKBUILD_Reference
- Apkindex format
- Abuild and Helpers
- 镜像状态 https://mirrors.alpinelinux.org/status.json
- 镜像列表 http://nl.alpinelinux.org/alpine/MIRRORS.txt
- Golang
- aports How to contribute
- 提交新的包
- fork aports
- 添加新的包
- 提交 PR
- 新的包只能添加到
testing/
, 在结果一段时间测试后才会移动到main/
或community/
- 提交的信息格式
${repo}/${pkgname}: new aport
${repo}/${pkgname}: move from testing
${repo}/${pkgname}: upgrade to 3.1.0
- 确保 ABUILD 使用 Tab 而不是 空格
- 参考
- alpinelinux/abuild - abuild 源码
- build.alpinelinux.org 构建状态
- apk-audit
- 移除了 non-free https://gitlab.alpinelinux.org/alpine/aports/-/commit/f7fff70bb1f1a2b9756ec19318dfc4c9cc3c5f1c
- 3dm2
- b43-firmware
- bcwc_pcie-src
- chromium-widevine
- cockroach
- compcert
- facetimehd-firmware
- mongodb
- mspdebugstack
- netperf
- postgresql-timescaledb-tsl
- py-flask-mongoengine
- py-flask-pymongo
- py-flask-views
- unifi
- unrar
- urbanterror-data
- urbanterror
- vlmcsd
- yed
# 准备
mkdir build && cd build
git clone --depth 50 https://gitlab.alpinelinux.org/alpine/aports
# 启动环境
# 配置缓存
# HOME=/build
docker run --rm -it \
-v $PWD:/build \
-v $PWD/distfiles:/var/cache/distfiles \
-v $PWD/cache:/etc/apk/cache \
--name builder wener/base:builder
sudo apk upgrade -a # 更新
cd aports # 进入 aports
git pull # 更新 aports
# git 用户配置
git config --global user.name "Your Full Name"
git config --global user.email "[email protected]"
# 个人信息
[ -e ~/.abuild/abuild.conf ] || {
mkdir -p ~/.abuild
echo "PACKAGER=\"$(git config --global user.name) <$(git config --global user.email)>\"" > ~/.abuild/abuild.conf
}
# 生成密钥
grep PACKAGER_PRIVKEY ~/.abuild/abuild.conf || abuild-keygen -ani
# 打包
# community/grpc
cd aports/community/grpc
# 编译构建到 ~/packages
# -K 保留 src 和 pkg - 用于开发调试
# -r 安装依赖
abuild -Kr
# /var/cache/distfiles
abuild checksum
abuild -r
# 位于 $HOME/packages/main/x86_64
abuild -Kf
# 针对单个包操作
abuild package dev
# 移除所有构建时安装的依赖
# 直接编辑 /etc/apk/world 然后 apk fix 也可以
apk del '.makedepends-*'
rsync -avz --no-perms --no-owner --no-group --exclude='src,pkg' mnt/wener abuild/
abuild
# 默认环境
startdir="${APKBUILD%/*}"
srcdir=${srcdir:-"$startdir/src"}
pkgbasedir=${pkgbasedir:-"$startdir/pkg"}
repo=${startdir%/*}
repo=${repo##*/}
builddir=${builddir:-"$srcdir/$pkgname-$pkgver"}
abuild.conf
export CFLAGS="-Os -fomit-frame-pointer"
export CXXFLAGS="$CFLAGS"
export CPPFLAGS="$CFLAGS"
export LDFLAGS="-Wl,--as-needed"
export GOFLAGS="-buildmode=pie"
# Do note that these should work with at least GDC and LDC
export DFLAGS="-Os"
export JOBS=2
export MAKEFLAGS=-j$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 <[email protected]>"
#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"
生成和使用 Patch
cd src/dahdi-linux-3.1.0/
cp include/kernel.h include/kernel.h.new
nano include/kernel.h.new
diff -u include/kernel.h include/kernel.h.new > ../../kernel-compact-5.4.patch
# 添加 patch
nano APKBUILD
abuild checksum
# 验证 patch 正确性
rm -rf src
abuild unpack prepare
# 构建
abuild -r
新增
# -c 添加 init.d 和 conf.d
newapkbuild -n frp \
-d 'A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.' \
-l 'Apache-2.0' \
-u https://github.com/fatedier/frp \
-c \
https://github.com/fatedier/frp/archive/v0.35.1.tar.gz
APKBUILD
install="$pkgname.pre-install $pkgname.post-install"
# cmake check
check() {
CTEST_OUTPUT_ON_FAILURE=1 make -C build check
}
# 测试打包脚本
rm -rf pkg && abuild rootpkg
pre.install
#!/bin/sh
addgroup -S nebula 2> /dev/null
adduser -S -D -H -s /bin/false -G nebula -g nebula nebula 2> /dev/null
exit 0
init tips
# 支持多 init
[ "${RC_SVCNAME}" != "${RC_SVCNAME##*.}" ] && INSTANCE=${RC_SVCNAME##*.}
# 检查包内内容
tar -tvf ~/packages/testing/x86_64/frp-openrc-*.apk
#!/sbin/openrc-run
name="Nebula Networking"
description="Scalable overlay networking tool"
instance=${RC_SVCNAME##*.}
cfgfile="/etc/nebula/${instance:-config}.yml"
command="/usr/sbin/nebula"
command_args="-config $cfgfile"
command_user="nebula"
supervisor="supervise-daemon"
output_log="/var/log/${RC_SVCNAME}.log"
error_log="/var/log/${RC_SVCNAME}.log"
depend() {
need net
use logger dns
after firewall
}
start_pre() {
$command -config $cfgfile -test
checkpath -f -m 0644 -o "$command_user" "$output_log" "$error_log"
checkpath -f -m 0640 -o "$command_user" "$cfgfile"
}
开发
Usage: newapkbuild [-n PKGNAME] [-d PKGDESC] [-l LICENSE] [-u URL]
[-a | -C | -m | -p | -y | -r] [-s] [-c] [-f] [-h]
PKGNAME[-PKGVER] | SRCURL
Options:
-n Set package name to PKGNAME (only use with SRCURL)
-d Set package description to PKGDESC
-l Set package license to LICENSE, use identifiers from:
<https://spdx.org/licenses/>
-u Set package URL
-a Create autotools package (use ./configure ...)
-C Create CMake package (Assume cmake/ is there)
-m Create meson package (Assume meson.build is there)
-p Create perl package (Assume Makefile.PL is there)
-y Create python package (Assume setup.py is there)
-r Crate rust package (Assume Cargo.toml is there)
-s Use sourceforge source URL
-c Copy a sample init.d, conf.d, and install script
-f Force even if directory already exists
-h Show this help
usage: abuild [options] [-P REPODEST] [-s SRCDEST] [-D DESCRIPTION] [cmd] ...
abuild [-c] -n PKGNAME[-PKGVER]
Options:
-A Print CARCH and exit
-c Enable colored output
-d Disable dependency checking
-D Set APKINDEX description (default: $repo $(git describe))
-f Force specified cmd (skip checks: apk up to date, arch)
-F Force run as root
-h Show this help
-k Keep built packages, even if APKBUILD or sources are newer
-K Keep buildtime temp dirs and files (srcdir/pkgdir/deps)
-m Disable colors (monochrome)
-P Set REPODEST as the repository location for created packages
-q Quiet
-r Install missing dependencies from system repository (using $SUDO_APK)
-s Set source package destination directory
-v Verbose: show every command as it is run (very noisy)
Commands:
build Compile and install package into $pkgdir
check Run any defined tests concerning the package
checksum Generate checksum to be included in APKBUILD
clean Remove temp build and install dirs
cleancache Remove downloaded files from $SRCDEST
cleanoldpkg Remove binary packages except current version
cleanpkg Remove already built binary and source package
deps Install packages listed in makedepends and depends
fetch Fetch sources to $SRCDEST (consider: 'abuild fetch verify')
index Regenerate indexes in $REPODEST
listpkg List target packages
package Install project into $pkgdir
prepare Apply patches
rootbld Build package in clean chroot
rootpkg Run 'package', the split functions and create apks as fakeroot
sanitycheck Basic sanity check of APKBUILD
snapshot Create a $giturl snapshot and upload to $disturl
sourcecheck Check if remote source package exists upstream
srcpkg Make a source package
undeps Uninstall packages listed in makedepends and depends
unpack Unpack sources to $srcdir
up2date Compare target and sources dates
verify Verify checksums
To activate cross compilation specify in environment:
CHOST Arch or hostspec of machine to generate packages for
CTARGET Arch or hostspec of machine to generate compiler for
virtual
- 相当于一个临时的 /etc/apk/world
apk add --virtual .my-temp-proj foo bar
FAQ
Invalid configuration x86_64-alpine-linux-musl
: machine x86_64-alpine-linux
not recognized
- 可以将
--build
和--host
设置为x86_64-alpine-linux
- 因为部分项目构建是无法将
musl
识别为gnu
升级包也需要升级依赖
apk add lua-aports
# 在 aports 仓库下运行 - 每个仓库都要
# ap revdep grpc-dev
# check affected
echo -n main,community,testing | tr ',' '\n' | xargs -I {} sh -c 'cd {}; ap revdep grpc-dev | xargs -rI % echo {}/%'
# bump pkgrel
echo -n main,community,testing | tr ',' '\n' | xargs -I {} sh -c 'cd {}; ap revdep grpc-dev | xargs -rI % echo {}/%' \
| xargs -I {} sed -ri 's/(pkgrel=)([0-9]+)/echo "\1$((\2+1))"/e' {}/APKBUILD
# verify
git diff --color=always | tee
git add -u
git commit -m '*: rebuild for libgrpc'
maintain
# subshell - 避免污染环境
pkgver=$(. APKBUILD && echo $pkgver)
git add -u
git commit -m "$(pwd | egrep -o '([^/]*/[^/]*)$'): upgrade to $(. APKBUILD && echo $pkgver)"
# rebuild against PKG VER
# rebuild for PKG
gh=$(egrep -o 'github.com(/[^/"]+){2}' APKBUILD | head -1 | egrep -o '[^/]+/[^/]+$')
latest=$(curl -sf https://data.jsdelivr.com/v1/package/resolve/gh/$gh@latest | jq .version -r)
sed -ri "s/(pkgver=)(.+)/\1$latest/" APKBUILD
git add APKBUILD
# 不 add 则 --cached
git diff --quiet --exit-code APKBUILD && echo Changed
# if changed
sed -ri "s/(pkgrel)=(.+)/\1=0/" APKBUILD
abuild checksum
git add -u
builder
export PATH=$HOME/n/bin:$PATH
export N_PREFIX=$HOME/n
# export https_proxy=
cd /build/aports
pnpm tsx src/aports/upgrade.ts --cwd $PWD community/frp
git push gl
git switch master
grep 'github.com' community/*/APKBUILD -l | sort -u | cut -f 2 -d '/'
# rclone frp grpc seaweedfs postgresql-timescaledb grpc-java
pnpm tsx src/aports/upgrade.ts --cwd $PWD seaweedfs