]> git.proxmox.com Git - debcargo-conf.git/blob - build.sh
backport cursive update + deps
[debcargo-conf.git] / build.sh
1 #!/bin/bash
2 # Build a packaged crate.
3 #
4 # This script is not run directly, but linked into ./build/ when running one of
5 # the other scripts, so you should do that instead of running this directly.
6 #
7 # Usage: [REALVER=<EXACTVER>] ./build.sh <CRATE> [<SEMVER>] [<EXTRA DEPENDENCY DEB> ...]
8 #
9 # Envvars:
10 # IGNORE_MISSING_BUILD_DEPS=1
11 # Don't abort on missing build deps. You'll need
12 # this when giving extra dependency debs.
13 # SKIP_SIGN=1
14 # Skip signing built packages.
15 # DISTRIBUTION=$suite
16 # Release to something other than unstable, e.g. experimental
17 # CHROOT=$chroot
18 # Build using another schroot than debcargo-unstable-amd64-sbuild
19 # SBUILD_OPTS=
20 # will pass to sbuild; for example SBUILD_OPTS=--arch=i386
21 # EXTRA_DEBS
22 # Include extra dependency debs, e.g. EXTRA_DEBS=librust*.deb.
23 # CHROOT_MODE=unshare
24 # Whether to build with sbuild unshare mode
25 set -e
26
27 SCRIPTDIR="$(dirname $(readlink -f "$0"))"
28
29 abort() { local x=$1; shift; for i in "$@"; do echo >&2 "$0: abort: $i"; done; exit "$x"; }
30 report() { for i in "$@"; do echo >&2 "debcargo-conf builder: $i"; done; }
31
32 if [ "$(basename "$PWD")" != "build" ]; then
33 abort 1 "This script is only meant to be run from the build/ directory."
34 fi
35
36 if [ -n "$DEBCARGO" ]; then
37 true
38 elif type -p debcargo >/dev/null 2>&1; then
39 DEBCARGO=$(type -p debcargo)
40 elif [ -f "$HOME/.cargo/bin/debcargo" ]; then
41 DEBCARGO="$HOME/.cargo/bin/debcargo"
42 else
43 abort 1 "debcargo not found, run \`cargo install debcargo\` or set DEBCARGO to point to it"
44 fi
45
46 CRATE="$1"
47 VER="$2"
48 if test -z "$VER" -o -f "$VER"; then
49 VER=""
50 shift
51 else
52 shift 2
53 fi
54 DISTRIBUTION="${DISTRIBUTION:-unstable}"
55
56 PKGNAME=$($DEBCARGO deb-src-name "$CRATE" $VER || abort 1 "couldn't find crate $CRATE")
57 DEBVER=$(dpkg-parsechangelog -l $PKGNAME/debian/changelog -SVersion)
58 DEBSRC=$(dpkg-parsechangelog -l $PKGNAME/debian/changelog -SSource)
59 DEBDIST=$(dpkg-parsechangelog -l $PKGNAME/debian/changelog -SDistribution)
60 DEB_HOST_ARCH=$(dpkg-architecture -q DEB_HOST_ARCH)
61 SRCNAME="${DEBSRC}_${DEBVER}"
62 BUILDNAME="${DEBSRC}_${DEBVER}_${DEB_HOST_ARCH}"
63
64 if [ -z "$CHROOT" ]; then
65 if [ "$CHROOT_MODE" = "unshare" ]; then
66 CHROOT="$(find ~/.cache/sbuild -iname "debcargo-*" | head -n1)"
67 if [ -z "$CHROOT" ]; then
68 CHROOT="unstable-${DEB_HOST_ARCH}"
69 echo >&2 "Automatically using sbuild tarball unstable-${DEB_HOST_ARCH}; however it's"
70 echo >&2 "strongly recommended to create a separate tarball debcargo-unstable-${DEB_HOST_ARCH}"
71 echo >&2 "so your builds won't have to re-download & re-install cargo, rustc, and llvm every time."
72 echo >&2 "See README.rst section \"Build environment\" for details."
73 fi
74 elif schroot -i -c "debcargo-unstable-${DEB_HOST_ARCH}-sbuild" >/dev/null 2>&1; then
75 CHROOT="debcargo-unstable-${DEB_HOST_ARCH}-sbuild"
76 elif schroot -i -c "unstable-${DEB_HOST_ARCH}-sbuild" >/dev/null 2>&1; then
77 CHROOT="unstable-${DEB_HOST_ARCH}-sbuild"
78 echo >&2 "Automatically using sbuild chroot unstable-${DEB_HOST_ARCH}-sbuild; however it's"
79 echo >&2 "strongly recommended to create a separate chroot debcargo-unstable-${DEB_HOST_ARCH}-sbuild"
80 echo >&2 "so your builds won't have to re-download & re-install cargo, rustc, and llvm every time."
81 echo >&2 "See README.rst section \"Build environment\" for details."
82 sleep 1
83 elif [ "$SOURCEONLY" != 1 ]; then
84 abort 1 "could not automatically find a suitable chroot; set CHROOT"
85 fi
86 fi
87
88 shouldbuild() {
89 local dst="$1"
90 local src="$2"
91 test ! -e "$dst" -o "$src" -nt "$dst"
92 }
93
94 # maintain an apt cache in ./build/aptroot
95 mkdir -p "./aptroot/etc/apt/apt.conf.d" "./aptroot/var/lib/apt/lists/" "./aptroot/etc/apt/preferences.d"
96 cat << END > "./aptroot/apt.conf"
97 Apt::Architecture "$DEB_HOST_ARCH";
98 Apt::Architectures "$DEB_HOST_ARCH";
99 Dir "$PWD/aptroot";
100 Acquire::Languages "none";
101 END
102 {
103 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian/ $DISTRIBUTION main";
104 case $DISTRIBUTION in
105 experimental|rc-buggy)
106 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian/ unstable main"
107 ;;
108 unstable|sid|testing) : ;;
109 *-backports)
110 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian/ ${DISTRIBUTION%-backports} main";
111 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian/ ${DISTRIBUTION%-backports}-updates main";
112 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://security.debian.org/debian-security/ ${DISTRIBUTION%-backports}-security main";
113 ;;
114 *)
115 # assume stable release
116 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian/ $DISTRIBUTION-updates main";
117 echo "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://security.debian.org/debian-security/ $DISTRIBUTION-security main";
118 ;;
119 esac;
120 } > "./aptroot/etc/apt/sources.list"
121 APT_CONFIG="$PWD/aptroot/apt.conf"
122 export APT_CONFIG
123 apt-get update
124
125 if shouldbuild "$SRCNAME.dsc" "$PKGNAME/debian/changelog" ]; then
126 if [ "$REUSE_EXISTING_ORIG_TARBALL" = 1 ]; then
127 UPSVER="${DEBVER%-*}"
128 mv "${DEBSRC}_${UPSVER}.orig.tar.gz" "${DEBSRC}_${UPSVER}.orig.tar.gz.new"
129 apt-get -t unstable source --download-only "${DEBSRC}" # "=${DEBVER}"
130 # check that old tarball contains same contents as new tarball
131 if ! diff -ru \
132 --label "${DEBSRC}_${UPSVER}.orig.tar.gz.new" \
133 <(zcat "${DEBSRC}_${UPSVER}.orig.tar.gz.new" | tar -tvvf-) \
134 --label "${DEBSRC}_${UPSVER}.orig.tar.gz" \
135 <(zcat "${DEBSRC}_${UPSVER}.orig.tar.gz" | tar -tvvf-); then
136 read -p "contents differ, continue with old tarball or abort? [y/N] " x
137 if [ "$x" != "y" ]; then exit 1; fi
138 fi
139 # extract old tarball into new directory, to avoid "modified files" problems with dpkg-source later
140 ( cd "$PKGNAME" && dpkg-source --after-build . && tar --strip-components=1 -xf "../${DEBSRC}_${UPSVER}.orig.tar.gz" )
141 fi
142 ( cd "$PKGNAME" && dpkg-buildpackage -d -S --no-sign )
143 # sign if not UNRELEASED
144 if echo "$DEBDIST" | grep -qv UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO; then
145 if [ "$SKIP_SIGN" != 1 ]; then
146 debsign ${DEBSIGN_KEYID:+-k $DEBSIGN_KEYID} "${SRCNAME}_source.changes"
147 fi
148 fi
149 fi
150
151 # allow tab, comma, space as separators
152 IFS=' , ' read -r -a EXTRA_DEBS <<< "$EXTRA_DEBS"
153 if [ ${#EXTRA_DEBS[@]} -eq 0 ]; then
154 EXTRA_DEBS=( "$@" )
155 fi
156 if [ ${#EXTRA_DEBS[@]} -ne 0 ]; then
157 IGNORE_MISSING_BUILD_DEPS=1
158 echo >&2 "Given non-empty extra debs; defaulting IGNORE_MISSING_BUILD_DEPS=1"
159 fi
160
161 check_build_deps() {
162 mkdir -p dpkg-dummy
163 # Dir::State::Lists is /var/lib/apt/lists by default.
164 # Since apt replaces the files in that directory instead of rewriting
165 # existing inodes, we can rely on the directory mtime.
166 if shouldbuild dpkg-dummy/status "$(eval "$(apt-config shell v Dir::State::Lists/d)"; printf "$v")"; then
167 # pretend dpkg status file that marks all packages as installed
168 # this is because dpkg-checkbuilddeps only works on installed pkgs
169 ( apt-cache dumpavail -o APT::Default-Release=$DISTRIBUTION && \
170 for i in ${EXTRA_DEBS[*]}; do apt-cache show $(echo $i | cut -d_ -f1); done ) | \
171 sed -e 's/Package: .*/\0\nStatus: install ok installed/g' > dpkg-dummy/status.tmp
172 if ! test -s dpkg-dummy/status.tmp; then
173 abort 1 "couldn't generate dpkg-dummy/status, is Debian unstable in your APT sources?"
174 fi
175 mv dpkg-dummy/status{.tmp,}
176 fi
177 ( cd "$PKGNAME" && dpkg-checkbuilddeps --admindir=../dpkg-dummy )
178 }
179
180 if ! check_build_deps; then
181 if [ "$IGNORE_MISSING_BUILD_DEPS" != 1 ]; then
182 abort 1 "Missing build-dependencies, but maybe try '{apt,cargo} update'"
183 fi
184 fi
185
186 if [ "$SOURCEONLY" = 1 ]; then
187 exit
188 fi
189
190 if [ -n "${EXTRA_DEBS[*]}" ]; then
191 EXTRA_DEBS_SBUILD=("${EXTRA_DEBS[@]/#/--extra-package=}")
192 EXTRA_DEBS_REPO_TMP=$(mktemp -d "${SRCNAME}_REPO_XXXXXXXX")
193 # trap cleans up even if user does Ctrl-C
194 # https://stackoverflow.com/a/14812383 inside "trap" avoids running handler twice
195 trap 'excode=$?; rm -rf "'"$EXTRA_DEBS_REPO_TMP"'"; trap - EXIT' EXIT HUP INT QUIT PIPE TERM
196 # symlinks don't work here
197 ln -f "${EXTRA_DEBS[@]}" "$EXTRA_DEBS_REPO_TMP/"
198 ( cd "$EXTRA_DEBS_REPO_TMP"; apt-ftparchive packages . > Packages )
199 EXTRA_DEBS_AUTOPKGTEST_OPTS=([0]=--autopkgtest-opt=--copy="$PWD/$EXTRA_DEBS_REPO_TMP/:/tmp/$EXTRA_DEBS_REPO_TMP/" [1]=--autopkgtest-opt=--add-apt-source="deb [trusted=yes] file:///tmp/$EXTRA_DEBS_REPO_TMP ./")
200 fi
201
202 if [ "$CHROOT_MODE" = "unshare" ]; then
203 AUTOPKGTEST_OPTS=("--run-autopkgtest" "--autopkgtest-root-arg=" "--autopkgtest-opts=--apt-upgrade -- unshare -t ${CHROOT} ${DISTRIBUTION:+-r $DISTRIBUTION}")
204 else
205 AUTOPKGTEST_OPTS=("--run-autopkgtest" "--autopkgtest-root-arg=" "--autopkgtest-opts=-- schroot ${CHROOT}")
206 fi
207
208
209 if [ "$SKIP_AUTOPKGTEST" = 1 ]; then
210 AUTOPKGTEST_OPTS=()
211 EXTRA_DEBS_AUTOPKGTEST_OPTS=()
212 fi
213
214 LINTIAN_OPTS=()
215 if echo "$DEBDIST" | grep -q UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO; then
216 LINTIAN_OPTS=([0]="--lintian-opt=--suppress-tags" [1]="--lintian-opt=bad-distribution-in-changes-file")
217 fi
218
219 SBUILD_CONFIG="$SCRIPTDIR/dev/sbuildrc" sbuild --no-source --arch-any --arch-all \
220 ${CHROOT:+-c $CHROOT} \
221 ${CHROOT_MODE:+--chroot-mode "$CHROOT_MODE"} \
222 ${DISTRIBUTION:+-d $DISTRIBUTION} \
223 "${EXTRA_DEBS_SBUILD[@]}" \
224 "${EXTRA_DEBS_AUTOPKGTEST_OPTS[@]}" \
225 "${AUTOPKGTEST_OPTS[@]}" \
226 "${LINTIAN_OPTS[@]}" \
227 ${SBUILD_OPTS} \
228 "$SRCNAME.dsc"
229 if [ "$SKIP_AUTOPKGTEST" != 1 ]; then
230 report "analyzing autopkgtest log: $BUILDNAME.test.log"
231 # this is a bit of a hack but works OK for now, until sbuild supports %SBUILD_BUILD_DIR in --autopkgtest-opt
232 sed -ne '/autopkgtest .*: testing package .* version .*/,$p' "$BUILDNAME.build" > "$BUILDNAME.test.log"
233 "$SCRIPTDIR/dev/rust-regressions.sh" "$BUILDNAME.test.log"
234 fi
235
236 changestool "$BUILDNAME.changes" adddsc "$SRCNAME.dsc"
237 report "build complete: $BUILDNAME.changes"
238
239 if grep -q "unknown-section FIXME" "$BUILDNAME.build"; then
240 abort 1 "Please fix the SECTION, found FIXME"
241 fi
242
243 # sign if not UNRELEASED
244 if echo "$DEBDIST" | grep -qv UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO; then
245 if [ "$SKIP_SIGN" != 1 ]; then
246 debsign ${DEBSIGN_KEYID:+-k $DEBSIGN_KEYID} --no-re-sign "$BUILDNAME.changes"
247 fi
248 fi