]> git.proxmox.com Git - dh-cargo.git/blame - dh-cargo-built-using
Remove constraints unnecessary since stretch
[dh-cargo.git] / dh-cargo-built-using
CommitLineData
36790ab7
XL
1#!/bin/sh
2# Generates Built-Using after a successful cargo build.
3# Run this in the package top-level directory where debian/ is.
4
5set -e
6
7DEB_HOST_RUST_TYPE="${DEB_HOST_RUST_TYPE:-$(printf "include /usr/share/rustc/architecture.mk\nall:\n\techo \$(DEB_HOST_RUST_TYPE)\n" | make --no-print-directory -sf -)}"
8CARGO_REGISTRY="${CARGO_REGISTRY:-debian/cargo_registry}"
9CARGO_CHANNEL="${CARGO_CHANNEL:-release}"
10# useful for testing:
11# CARGO_REGISTRY="$HOME/.cargo/registry/src/github.com-1ecc6299db9ec823" DEB_HOST_RUST_TYPE="." CARGO_CHANNEL=debug
12
13CARGO_TARGET_DIR="target/$DEB_HOST_RUST_TYPE/$CARGO_CHANNEL"
14CARGO_TARGET_DIR_ABS="$(readlink -f "$CARGO_TARGET_DIR")"
15
16CPRIGHT_FORMAT="https://www.debian.org/doc/packaging-manuals/copyright-format/1.0"
17SRCLEFT_LICENSES="$(echo GPL LGPL AGPL GFDL MPL CDDL CPL Artistic Perl QPL | tr ' ' '\n')"
18pkg_has_srcleft_license() {
19 local pkg="$1"
20 local ver="$2"
21 local f="/usr/share/doc/$pkg/copyright"
22 if ! sed -nre 's ^Format: (.*) \1 gp' "$f" | grep -qiw "$CPRIGHT_FORMAT"; then
23 echo >&2 "$0: abort: Not in machine-readable format: $f"
24 echo 2
25 elif sed -nre 's ^X-Binary-Requires-Source: (.*) \1 gp' "$f" | grep -qiw yes; then
26 echo 1
27 elif sed -nre 's ^License: (.*) \1 gp' "$f" | grep -qiwF "$SRCLEFT_LICENSES"; then
28 echo 1
29 else
30 echo 0
31 fi
32}
33
1c8ba851
XL
34dep_files_to_pkgs() {
35 xargs -r dpkg -S \
36790ab7
XL
36 | sed -nre 's (.*): .* \1 gp' \
37 | xargs -r dpkg-query --show \
38 | while read pkg ver; do echo "$pkg $ver $(pkg_has_srcleft_license "${pkg%:*}" "$ver")"; done
39 # pkg_has_srcleft_license should be accurate for all rust crates, no need to give a $containing_crate
40 # this is due to nature of crate copyright info, and the debian rust packaging policy
41}
42
1c8ba851
XL
43rust_dep_files() {
44 cat "$CARGO_TARGET_DIR/deps"/*.d \
45 | sed -nre 's ^\S*/('"$CARGO_REGISTRY"'/[^/]*)/.* '"$(readlink -f "$PWD")/"'\1 gp' \
46 | sort -u \
47 | xargs -r readlink -f
48}
49
50rust_libs() {
51 { which rustc; rust_dep_files; } | dep_files_to_pkgs
52}
53
36790ab7
XL
54gcc_default_searchdirs() {
55 gcc -print-search-dirs \
56 | sed -nre 's ^libraries: (.*) \1 gp' \
57 | tr ':' '\n' \
58 | sed -e 's ^= '"$(gcc -print-sysroot)"' g' \
59 | xargs readlink -m 2>/dev/null # suppress errors caused by early pipe closure
60}
61
62rust_search_lib() {
63 local lib="$1"
64 {
65 cat
66 # rust does not actually search normal paths when linking static libs
67 # - see https://github.com/rust-lang/rust/issues/43118
68 # - see also `fn link_rlib` in back/link.rs which calls
69 # `pub fn find_library` in back/archive.rs which generates the error message
70 #gcc_default_searchdirs
71 } | while read searchdir; do
72 #echo >&2 "searching $searchdir for static lib $lib"
73 local f="$(readlink -m "$searchdir/lib${lib}.a")"
74 if test -f "$f"; then
75 printf "%s\n" "$f"
76 break
77 fi
78 done
79}
80
81native_libs() {
82 ls -1d "$CARGO_TARGET_DIR/build"/*/output 2>/dev/null | while read output; do
8e983617
XL
83 sed -nre 's ^cargo:rustc-link-lib=static=(.*) \1 '"$output"' gp' "$output"
84 done | while read lib output; do
36790ab7 85 local containing_crate="$(basename "$(dirname "$output")")"
36790ab7 86 test -n "$lib" || continue
8e983617 87 local libfile="$(sed -nre 's ^cargo:rustc-link-search=native=(.*) \1 gp' "$output" | rust_search_lib "$lib")"
36790ab7
XL
88 local srcleft=""
89 test -n "$libfile" || { echo >&2 "$0: abort: could not find static lib '$lib'; rustc should have failed already?"; exit 1; }
eecce01b 90 echo >&2 "$0: found static lib $lib at $libfile"
36790ab7
XL
91 if [ "${libfile#$CARGO_TARGET_DIR_ABS/}" != "$libfile" ]; then
92 # static library source code embedded in crate
93 local srcstat="$(sed -nre 's ^dh-cargo:deb-built-using='"$lib"'=([01]=.*) \1 gp' "$output")"
94 case "$srcstat" in
95 0=*|1=*)
96 srcleft="${srcstat%%=*}"
97 libfile="${srcstat#*=}"
eecce01b 98 if [ "$(readlink -f "$libfile")" = "$(readlink -f "$PWD")" ]; then
daf51491
XL
99 # Note that this exception only applies in the case that where you are building
100 # the Debian package for $containing_crate itself. In the case where you are
101 # building a Debian package for crate X depending on $containing_crate, the
102 # latter still has to output the dh-cargo:deb-built-using in their build.rs so
103 # that the Debian package for crate X can correctly set Built-Using themselves.
36790ab7
XL
104 echo >&2 "$0: static library derived from $libfile which is the top-level crate being built, no need to add Built-Using"
105 continue
106 fi
107 ;;
108 *)
109 echo >&2 "$0: abort: could not determine source-distribution conditions of ${libfile#$CARGO_TARGET_DIR_ABS/}."
110 echo >&2 "You must patch build.rs of ${containing_crate%-*} to output 'println!(\"dh-cargo:deb-built-using=$lib=\$s={}\", env::var(\"CARGO_MANIFEST_DIR\").unwrap());' where:"
111 echo >&2 "- \$s is 1 if the license(s) of the included static libs require source distribution alongside binaries, otherwise 0"
112 exit 1
113 ;;
114 esac
115 fi
325e0652 116 local wpkg="$(dpkg -S "$(readlink -f "$libfile")")"
36790ab7
XL
117 test -n "$wpkg" || { echo >&2 "$0: abort: could not find Debian package for file $libfile"; exit 1; }
118 local pkgstat="$(echo "$wpkg" | sed -nre 's (.*): .* \1 gp' | xargs -r dpkg-query --show)"
119 local pkg="$(echo "$pkgstat" | cut -f1)"
120 local ver="$(echo "$pkgstat" | cut -f2)"
121 # static library source code embedded in crate (from earlier)
122 if [ -n "$srcleft" ]; then
123 echo "$pkg $ver $srcleft"
124 # static libraries from another Debian package
125 elif sed -nre 's ^dh-cargo:deb-built-using='"$lib"'=0~=(.*) \1 gp' "$output" | { echo "${pkg%:*} $ver" | grep -qExf /dev/fd/3; } 3<&0; then
126 echo "$pkg $ver 0"
127 elif sed -nre 's ^dh-cargo:deb-built-using='"$lib"'=1~=(.*) \1 gp' "$output" | { echo "${pkg%:*} $ver" | grep -qExf /dev/fd/3; } 3<&0; then
128 echo "$pkg $ver 1"
129 else
130 # guess the conditions based on the whole d/copyright file
131 # this loses granularity, e.g. gcc is mostly distributed as GPL-3 but the libbacktrace portion is BSD-3
132 # to retain granularity the crate package maintainer should patch build.rs as suggested
133 echo >&2 "$0: warning: guessing source-distribution conditions of $libfile, this may be inaccurate."
134 echo >&2 "$0: warning: patch build.rs to suppress the above warning"
135 srcleft="$(pkg_has_srcleft_license "${pkg%:*}" "$ver")"
136 if [ "$srcleft" -gt 1 ]; then
137 echo >&2 "You must patch build.rs of ${containing_crate%-*} to output 'dh-cargo:deb-built-using=$lib=\$s~=\$PAT' where:"
138 echo >&2 "- \$s is 1 if the license(s) of the included static libs require source distribution alongside binaries, otherwise 0"
139 echo >&2 "- \$PAT is an egrep pattern matching the \"\$pkg \$ver\" combinations that satisfy \$s"
140 echo >&2 " for example '$pkg .*' matches the currently-relevant package, $pkg $ver"
141 exit 1
142 fi
143 echo "$pkg $ver $srcleft"
144 fi
145 done
146}
147
148output() {
149 local binpkg="$1"
150 if [ -z "$binpkg" ]; then
151 cat
152 else
153 local built_using=""
154 local built_using_x=""
dd7e39ec 155 while read pkg ver srcleft; do
8bb17ec6 156 local src="$(dpkg-query -f '${source:Package}' --show "$pkg")"
6645cc59 157 local srcver="$(dpkg-query -f '${source:Version}' --show "$pkg")"
36790ab7
XL
158 case "$srcleft" in
159 2) exit 1;;
6645cc59 160 1) built_using="${built_using}$src (= $srcver), ";;
36790ab7 161 esac
6645cc59 162 built_using_x="${built_using_x}$src (= $srcver), "
36790ab7
XL
163 done
164 echo "cargo:Built-Using=${built_using%, }" >> "debian/$binpkg.substvars"
165 echo "cargo:X-Cargo-Built-Using=${built_using_x%, }" >> "debian/$binpkg.substvars"
166 fi
167}
168
169native_libs="$(native_libs)" # capture output outside of pipe so set -e works
170{
171rust_libs
172test -z "$native_libs" || echo "$native_libs"
dd7e39ec 173} | LC_COLLATE=C.utf-8 sort -u | output "$@"