好用的 Pbuilder

pbuilder 基本上是自動幫你建一個 root filesystem 之後每次編譯的時候,就幫你chroot過去進行'重新'編譯。

好處就是環境比較乾淨,可以跨不同的debian dists (wheezy, jessie, stretch, sid),還有不同的archs (i386, amd64, armel, armhl)等

真的是滿方便得工具。

比起 docker, 我覺得就是端純比較 build 這件事,真是方便多了!之後可以找找看把 chroot 換成 docker 然後整合更多 Linux distributions 更好 , 例如 rpm...

具體作法就是需要安裝 pbuilder, 先 create, 再 pbuilder build

安裝

sudo apt install pbuilder qemu-user-static

設定 pbuilderrc, /root/pbuilderrc or ~/.pbuilderrc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/bin/sh
set -e

if [ "$OS" == "debian" ]; then
    MIRRORSITE="http://ftp.no.debian.org/debian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}"
        "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg")
    : ${DIST:="wheezy"}
    : ${ARCH:="amd64"}
    if [ "$DIST" == "wheezy" ]; then
        #EXTRAPACKAGES="$EXTRAPACKAGES debian-backports-keyring"
        OTHERMIRROR="$OTHERMIRROR | deb $MIRRORSITE wheezy-backports $COMPONENTS"
    fi
elif [ "$OS" == "raspbian" ]; then
    MIRRORSITE="http://ftp.acc.umu.se/mirror/raspbian/raspbian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}"
        "--keyring=/usr/share/keyrings/raspbian-archive-keyring.gpg")
    : ${DIST:="wheezy"}
    : ${ARCH:="armhf"}
elif [ "$OS" == "ubuntu" ]; then
    MIRRORSITE="http://no.archive.ubuntu.com/ubuntu/"
    COMPONENTS="main restricted universe multiverse"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}"
        "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg")
else
    echo "Unknown OS: $OS"
    exit 1
fi

if [ "$DIST" == "" ]; then
    echo "DIST is not set"
    exit 1
fi

if [ "$ARCH" == "" ]; then
    echo "ARCH is not set"
    exit 1
fi

NAME="$OS-$DIST-$ARCH"

if [ "$ARCH" == "armel" ] && [ "$(dpkg --print-architecture)" != "armel" ]; then
    DEBOOTSTRAP="qemu-debootstrap"
fi
if [ "$ARCH" == "armhf" ] && [ "$(dpkg --print-architecture)" != "armhf" ]; then
    DEBOOTSTRAP="qemu-debootstrap"
fi

DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--arch=$ARCH")
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/$NAME/aptcache/"
BUILDPLACE="/var/cache/pbuilder/build"
HOOKDIR="/var/cache/pbuilder/hook.d/"

執行 pbuilder 的 template 大概會是 OS=XXX DIST=XXX ARCH=XXX pbuilder ....

帶入環境變數之後,先來create base root filesystem 吧

sudo OS=debian DIST=sid ARCH=i386 pbuilder --create
sudo OS=debian DIST=sid ARCH=amd64 pbuilder --create

好了之後可以看看 /var/cache/pbuilder 是不是有 debian-sid-i386-base.tgz debian-sid-amd64-base.tgz 的檔案,這個就是之後會不斷用到的 base filesystem, 也就是用來 chroot 的。 之後可以用 --update 去更新、--login 登入、--clean...等工具可以用

編譯就是 --build, 這邊建議先要有 dsc 檔,也就是你已經編譯過 或是 debuild -S 產生 dsc ,接著送進 pbuilder 進行 binary 的編譯

sudo OS=debian DIST=sid ARCH=i386 pbuilder --build xxx.dsc
sudo OS=debian DIST=sid ARCH=amd64 pbuilder --build xxx.dsc

完成後可以確認一下檔案有沒有產生,位置通常是 /var/cache/pbuilder/{base-folder}/result/,通常建議把result目錄設定為自己的 user ,chown user:user /var/cache/pbuilder/{base-folder}/result/

@debian:~$ ls /var/cache/pbuilder/*/result
/var/cache/pbuilder/debian-jessie-amd64/result:
partclone_0.2.85-1_amd64.changes  partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1_amd64.deb      partclone_0.2.85-1.dsc            partclone-dbg_0.2.85-1_amd64.deb

/var/cache/pbuilder/debian-jessie-i386/result:
partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85-1_i386.changes  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1.dsc            partclone_0.2.85-1_i386.deb      partclone-dbg_0.2.85-1_i386.deb

/var/cache/pbuilder/debian-sid-amd64/result:
partclone_0.2.85-1_amd64.changes  partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1_amd64.deb      partclone_0.2.85-1.dsc            partclone-dbg_0.2.85-1_amd64.deb

/var/cache/pbuilder/debian-sid-i386/result:
partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85-1_i386.changes  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1.dsc            partclone_0.2.85-1_i386.deb      partclone-dbg_0.2.85-1_i386.deb

/var/cache/pbuilder/debian-stretch-amd64/result:
partclone_0.2.85-1_amd64.changes  partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1_amd64.deb      partclone_0.2.85-1.dsc            partclone-dbg_0.2.85-1_amd64.deb

/var/cache/pbuilder/debian-stretch-i386/result:
partclone_0.2.85-1.debian.tar.xz  partclone_0.2.85-1_i386.changes  partclone_0.2.85.orig.tar.gz
partclone_0.2.85-1.dsc            partclone_0.2.85-1_i386.deb      partclone-dbg_0.2.85-1_i386.deb

接下來,可以用 debsign 把 changes, dsc 等等通通 sign 好,然後丟出去了

其中有些常用的小技巧,最主要就是 hook, 網路上常看到的就是自動添加 apt respoitory, 還有就是編譯錯誤的debug shell

hook 目錄之前設定為 /var/cache/pbuilder/hook.d

自動加上 repository 的作法就是, 以下是我寫的自動加上 debl 的 repository

vi /var/cache/pbuilder/hook.d/D10add-apt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash
cat << EOF | apt-key add -
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.1 (GNU/Linux)

mQGiBETG4dYRBACuwb66BBd3STvK/7JxDkcp75VnsAgA6Yje1j2CCFIQCZrjyRO5
n4rva9jEOw5qEAy+2npk7RsuKjaXTWU2l+27uIKF9m/A4NgUgFl8YzAKgHV0dNQX
/o2AbUgyeIyZHTBeozCzWuP05ahv7EASva1011QZNLeeF72cuHWpEE0D1wCgtVVg
kHCketrsTe8171qCrL+I6KUEAI+wTZus0W+aycUvoapseRO5+OvSKGyRJtEjgZwX
THQueBZQDfazhWTI2KAxHVF31wpshjh6N1iOCFvS8XH6Lm2DDH6MzI11JrazEElc
X4R/0FfBt/ml14rGcIxx5TRERVA6Krbvf1nAhRi1bnNOcnv8BgDrPaE3w+r7BaPt
jGtZA/9Uf/4POfGjS5XvzNPQXt+qKii/3PF3F7/HnZxZ6CnF4d90KyUrd1qjjU7o
IiP2SOxy9w7m2HmCdSet/ZmxKirDepYIXxJWMfbhBSrcmTSf4d/X8DSXNinYgJn6
91QpoOcik8YA68mDdUXvqXH0LYqSQUVtlhpbTHtLBhg+A2SaMrQ/RFJCTCBQcm9q
ZWN0IChEaXNrbGVzcyBSZW1vdGUgQm9vdCBpbiBMaW51eCkgPGRyYmxAbmNoYy5v
cmcudHc+iFkEExECABkFAkTG4dYECwcDAgMVAgMDFgIBAh4BAheAAAoJEEAAlRHX
6N86dogAnijZRwr8SbtmyAIjcFzkcTJb72DVAJ0QuTt+u8nJXjMMcDof6DFETvTH
R7kBDQRExuHXEAQA2/Wsn+kZ8KN2HvlU1EHBcnZbmOtIIxjo7XcSeJzeDKZlhqFo
q7+Cx5Y1duVD5seyQNU1iCwuz7ox7JL/0qis13wa5h+3DluXnj6jb/f7ec+wGRBe
3PZLam57spCkaALmtX3HZvWFkmcbP8tiSgPNiiBToqwC0F4sevdg0e6x4ssAAwUE
AKW+dFt0eRHzHjbNGHXgWJHlotfJQhjGqogso1w8cbpTr7/WfqDSm1M5K715b4TG
LUAujP6f9PPiljTMhHTz++3pSNGvGcaQ6B4QfhK7fERXJLn/43vB5gqJtQpB0Ang
pGG7kfZ2SZ2ZT6lnbo7CR8MMomz3i8/3RTmqB5ov8ObhiEYEGBECAAYFAkTG4dcA
CgkQQACVEdfo3zoZMgCfSDywpr/ElmqskEmFNyoz2LZazfEAmQFTt6KfrIFPG4/c
wAWnl0QzXWsZ
=385O
-----END PGP PUBLIC KEY BLOCK-----
EOF

echo "deb http://free.nchc.org.tw/drbl-core drbl stable testing unstable dev" >> /etc/apt/sources.list
echo "deb-src http://free.nchc.org.tw/drbl-core drbl stable testing unstable dev" >> /etc/apt/sources.list
apt-get update

另一個 好用的 hook 就是 debug shell, 讓你再編譯錯誤的時候,可以進行debug

vi /var/cache/pbuilder/hook.d/C10shell

1
2
3
4
5
6
#!/bin/sh
# invoke shell if build fails.

apt-get install -y --force-yes vim less bash
cd /tmp/buildd/*/debian/..
/bin/bash < /dev/tty > /dev/tty 2> /dev/tty

hook 裡的檔案要設定為可執行!

reference:

  • http://jodal.no/2015/03/08/building-arm-debs-with-pbuilder/
  • https://www.debian.org/doc/manuals/maint-guide/build.en.html
  • https://wiki.ubuntu.com/PbuilderHowto#Signing_Source_Files

Comments