]> git.proxmox.com Git - debcargo-conf.git/blame - rust_hacks.md
inout: repack with debcargo 2.6.0
[debcargo-conf.git] / rust_hacks.md
CommitLineData
5e77e1e0
MG
1# Scope of this document
2
bcdeeada 3This document aims to document some nice "hacks" and tricks to employ when packaging crates.
5e77e1e0 4
345563f3
MG
5## Getting an overview of missing crates
6
7A nice tool to generate a graphical overview of a rust projects' dependency tree is `cargo debstatus`. Install it like that:
8`cargo install cargo-debstatus`. Then download either a release or clone the git project and `cd` into there. Run `cargo debstatus` to get a nice graph about dependencies and reverse dependencies.
5e77e1e0
MG
9
10## Patching crates
345563f3 11If a crate needs a) a newer dependency or b) an older dependency than the one in the archive you need to patch the crate. This is relatively common. You can also use this to patch out features in Cargo.toml or make changes to the source code.
5e77e1e0 12
345563f3 13Since the source is pulled from crates.io and not from github/lab, patching requires downloading the source from there. There are two ways to achieve this:
5e77e1e0 14
345563f3
MG
151) Install `cargo-download`: `cargo install cargo-download`
161.1) Download the source: `cargo download foocrate version > foocrate.tar.gz`
171.2) Extract the crate: `tar -xf foocrate.tar.gz`
181.3) `cd foocrate-version && git init && git add . && git commit -m "d"`
191.4) Edit e.g. Cargo.toml to relax the dependencies: Instead of version 0.4 of a crate bump it to 0.5 ( if that is the corresponding debian version) or down to 0.3 (if that is the debian version)
201.5) Generate a patch with your changes: `git diff -p >> relax-deps.diff`
211.6) `cp relax-deps.diff debcargo-conf/src/foocrate/debian`
221.7) `cd debcargo-conf/src/foocrate/debian && mkdir patches`
231.8) `mv relax-deps.diff patches/ && cd patches && echo relax-deps.diff >> series`
241.9) `cd ../../../../`
251.10) run `./update.sh foocrate` again. The patch should get applied and allow you to build against an older/newer dependency / with features disabled.
261.11) Document your patches in d/changelog
272) `wget http://crates.io/api/v1/crates/foocrate/version/download -O foocrate-version.tar.gz`
28Then follow 1.1)
29
72463ab8
BN
30Alternatively you can do it directly in the build directory with
31[quilt](https://wiki.debian.org/UsingQuilt):
32
331. In the root directory of `debcargo-conf`, `cd build/foo`
342. `quilt series` to check existing patches, `quilt push -a` to test apply all
35 of them, and `quilt pop -a` to unapply them
363. `quilt new patch-name.patch` to create a new patch, `quilt edit
37path/to/file` to edit a file with changes saved in current patch, `quilt
38header -e --dep3` to add a DEP-3 patch header
394. `quilt refresh` to update current patch and prevent fuzz (we don't allow
40fuzzes when building)
415. `cp -r debian/patches ../../src/foo/debian/` to copy updated patches over
426. In root directory, run `./update.sh foo` to update the build directory
43
44Note that `update.sh` deletes and re-creates `build/foo`, so an open terminal
45in it needs to go up and down into the new directory.
46
345563f3
MG
47capitol did a nice writeup which can be read here:
48https://blog.hackeriet.no/packaging-rust-part-II/
49
9fe459d1
MG
50## built-using-dh-cargo
51
52If you get an error like this:
53```
54You must patch build.rs of CRATE to output 'println!(\"dh-cargo:deb-built-using=$lib=\$s={}\", env::var(\"CARGO_MANIFEST_DIR\").unwrap());'
55where: $s is 1 if the license(s) of the included static libs require source distribution alongside binaries, otherwise 0"
56```
57when building a FFi rust library you need to patch build.rs like stated above. $s is 0 for BSD-like licenses such as MIT and 1 for copyleft licenses like GPL.
345563f3
MG
58
59## Skipping tests / special d/rules overrides
60
61Sometimes you get broken tests that can't be excluded or patched away. For instance if a test would require direct access to the RAM which isn't possible with `sbuild`. Then it is reasonable to skip those in `d/rules`.
62
631) `cd src/foocrate/debian && touch rules`
642) `cd ../../../ && ./update.sh foocrate`. This will generate a `rules.debcargo.hint` file you can use as template, similar to d/copyright
653) `cd src/foocrate/debian && cp rules.debcargo.hint rules`
664) use your favorite editor to edit the rules file to your needs. For skipping tests you can do the following:
67
68```
69override_dh_auto_test:
70 dh_auto_test -- test -- --skip tests::broken_test --skip tests::second_broken_test
71```
72
73if those are the broken tests. Then `cd` in the top-level directory and run `./update.sh` again. You might also need to skip the same tests in the autopkgtest runner. To do that, create a `tests/control` file in the `debian/` folder.
5e77e1e0 74
5e77e1e0
MG
75
76## Packaging binary crates
77
78TODO
79
80## debcargo.toml tweaks
81
82### Excluding files
83In case you need to exclude certain files from `debcargo.toml`, there is an easy way to do that.
84Just add `excludes = ["foo/bar.rs", ""bar/non-dfsg-file"]` in debcargo.toml. This has the following usecases:
85
86- Exclude non-dfsg/unnecessary files form the orig tarball (Example: svg-metadata)
87 This is also **required** for some sys-crates to exclude vendored copies of the C library already in debian
88- Exclude broken tests that do not run (when in doubt, ask on #debian-rust) (Example: cxx )
89
90### Passing external packages to the buildsystem
91
92If the crate needs external packages (such as -dev libraries) you can also pass those conveniently via `debcargo.toml` :
93` depends = ["libfoo-dev"] `. This is essentially needed for all -sys crates which provide rust bindings to C developement libraries such as GTK, for instance.
94
95### Passing runtime test dependencies to autopkgtest
96
97In rare cases the autopkgtest can fail on the official runners compared to the local one because it has a slightly different setup.
98You can do this like that: `test_depends = ["foo"]`. That happens very rarely, see `cxx` for an example.
99
100### Whitelisting files
101
102Sometimes debcargo marks files as suspicious, most of the time those are tests written in C for -sys crates. Whitelist them like that:
103`whitelist = [tests/foo.c"]` . (Example: lidadwaita-sys)
104
105### Allowing alpha/beta dependencies
106
107Some crates depend on a crate with an alpha/beta version strings. debcargo will emit an error if that is the case. To allow those deps, pass the following:
108`allow_prerelease_deps = true`. Do this only if you are sure this will work !
109
5e77e1e0 110
bcdeeada
MG
111### Collapsing features
112If a crate has features, `collapse_features = true` **should** be set in `debcargo.toml`. This is strongly recommended. See issue #17 in the debcargo repo for the reasoning.
113
114
115### Marking feature tests as broken
116
5e77e1e0
MG
117Let's assume you are building a package and get the following output at the end:
118
119```
120
121autopkgtest [22:45:42]: test librust-foo-dev:: -----------------------]
122autopkgtest [22:45:42]: test librust-foo-dev:: - - - - - - - - - - results - - - - - - - - - -
123librust-foo-dev: PASS
124autopkgtest [22:45:42]: @@@@@@@@@@@@@@@@@@@@ summary
125rust-foo:@ FAIL non-zero exit status 101
126librust-foo-dev:default PASS
127librust-foo-dev: PASS
128librust-foo-dev:serde: FAIL non-zero exit status 101
129
130```
131As we can see, the `serde` and `@` feature fail. Since the other features (and the package itself) passes, we need to mark those test as flaky so the package can migrate to testing.
132Do it like that:
133```
134#serde and @ feature fail the autopkgtest
135[packages.lib]
136test_is_broken = false
137[packages."lib+@"]
138test_is_broken = true
139[packages."lib+serde"]
140test_is_broken = true
141```
142Examples: cxx, hashbrown, uom, ...
143
144Do this only if *some* features fail. If all feature tests fail, read the test logs and look at the upstream test system. Make sure that some tests pass or that the tests aren't meant to be run. Some upstream projects run all test in a specific container or use specific setup. Also some crates are only tested with their default features enabled by upstream. If that's the case mark all test as broken:
145
146```
147# tests need a postgres container to run
148[packages.lib]
149test_is_broken = true
150
151```
152Examples: tokio-postgres, ...
153
154Sometime you need to combine some tricks to run at least some tests: Exclude a faulty test, patch dependencies away and mark tests as broken.
155
345563f3
MG
156### More resources
157For a full documentation of all keywords available in `debcargo.toml` refer to debcargo.toml.example in the debcargo repo.
5e77e1e0
MG
158
159
160## Arch-specific failures
161
162It can rarely happen that tests (read: autopkgtest) fail on specific arches because how bytes are addressed on that arch. The best course of action is to investigate first if it indeed is an arch-specific failure.
163If that's the case you need to write a patch that skips those faulty tests (on that arch) so the package can enter testing. Because arch names are different in rust, here is a handy table comparing them:
164
165
166| Debian arch name | rust arch name (target_arch) |
345563f3 167|----------------------|---------------------------|
bcdeeada 168| Arches autopkgtest runs on (needed for testing migration) | |
5e77e1e0
MG
169| amd64 | x86-64 |
170| i386 | x86 |
171| arm64 | aarch64 |
172| armel | arm |
173| armhf | arm |
174| ppc64el | powerpc64 |
175| s390x | powerpc64? |
345563f3 176| **Other official arches¹** | |
5e77e1e0
MG
177| mipsel | mips? |
178| mips64el | mips64 |
345563f3 179| **Unoffical ports with rustc/cargo (not really relevant)** | |
5e77e1e0
MG
180| powerpc | powerpc? |
181| ppc64 | powerpc? |
182| riscv64 | riscv64 |
183| sparc64 | sparc64? |
184| x32 | ? |
185
186Arches without rustc/cargo:
187- sh4²
188- alpha
189- arc
190- hppa
191- hurd-i386
192- ia64
193- kfreebsd-amd64
194- kfreebsd-i386
195- m68k
196
197Only the first seven are really relevant, I included the rest for completeness's sake.
198If you encounter a test failure e.g. on `armel`, add this macro before the `#[test]` macro:
199 ` #[cfg(not(target_arch = "arm"))] `.
345563f3
MG
200 Then generate a patch with the changes and include it in the usual way. Also notify upstream that this arch is broken and send them your patch.
201Footnotes: [1] https://wiki.debian.org/SupportedArchitectures
5e77e1e0 202 [2] sh4 has only one test failure for cargo
5e77e1e0
MG
203
204