docs/manual/cargo: document the cargo-package infrastructure

The Buildroot manual was already providing some details on how to
integrate Cargo packages, and those details now need to be updated
with a proper documentation for the cargo-package infrastructure, as
well as updates related to vendoring support, which affects how
dependencies are handled.

In addition, now that we have vendoring support for Cargo packages,
let's rewrite the dependency management section in a more accurate
way.

We drop the part about the local cache of the registry, because
+CARGO_HOME+ in Buildroot points to $(HOST_DIR)/share/cargo, which is
not shared between builds nor preserved accross builds, so its effect
as a cache is limited.

Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
[Thomas: numerous updates and extensions.]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
This commit is contained in:
Patrick Havelange
2020-12-19 16:35:21 +01:00
committed by Thomas Petazzoni
parent 301a8eae0c
commit 9d5749d2de

View File

@@ -1,7 +1,7 @@
// -*- mode:doc; -*- // -*- mode:doc; -*-
// vim: set syntax=asciidoc: // vim: set syntax=asciidoc:
=== Integration of Cargo-based packages === Infrastructure for Cargo-based packages
Cargo is the package manager for the Rust programming language. It allows the Cargo is the package manager for the Rust programming language. It allows the
user to build programs or libraries written in Rust, but it also downloads and user to build programs or libraries written in Rust, but it also downloads and
@@ -10,7 +10,7 @@ called "crates".
[[cargo-package-tutorial]] [[cargo-package-tutorial]]
==== Cargo-based package's +Config.in+ file ==== +cargo-package+ tutorial
The +Config.in+ file of Cargo-based package 'foo' should contain: The +Config.in+ file of Cargo-based package 'foo' should contain:
@@ -25,11 +25,7 @@ The +Config.in+ file of Cargo-based package 'foo' should contain:
08: http://foosoftware.org/foo/ 08: http://foosoftware.org/foo/
--------------------------- ---------------------------
==== Cargo-based package's +.mk+ file And the +.mk+ file for this package should contain:
Buildroot does not (yet) provide a dedicated package infrastructure for
Cargo-based packages. So, we will explain how to write a +.mk+ file for such a
package. Let's start with an example:
------------------------------ ------------------------------
01: ################################################################################ 01: ################################################################################
@@ -44,66 +40,56 @@ package. Let's start with an example:
10: FOO_LICENSE = GPL-3.0+ 10: FOO_LICENSE = GPL-3.0+
11: FOO_LICENSE_FILES = COPYING 11: FOO_LICENSE_FILES = COPYING
12: 12:
13: FOO_DEPENDENCIES = host-rustc 13: $(eval $(cargo-package))
14:
15: FOO_CARGO_ENV = CARGO_HOME=$(HOST_DIR)/share/cargo
16:
17: FOO_BIN_DIR = target/$(RUSTC_TARGET_NAME)/$(FOO_CARGO_MODE)
18:
19: FOO_CARGO_OPTS = \
20: $(if $(BR2_ENABLE_DEBUG),,--release) \
21: --target=$(RUSTC_TARGET_NAME) \
22: --manifest-path=$(@D)/Cargo.toml
23:
24: define FOO_BUILD_CMDS
25: $(TARGET_MAKE_ENV) $(FOO_CARGO_ENV) \
26: cargo build $(FOO_CARGO_OPTS)
27: endef
28:
29: define FOO_INSTALL_TARGET_CMDS
30: $(INSTALL) -D -m 0755 $(@D)/$(FOO_BIN_DIR)/foo \
31: $(TARGET_DIR)/usr/bin/foo
32: endef
33:
34: $(eval $(generic-package))
-------------------------------- --------------------------------
The Makefile starts with the definition of the standard variables for package The Makefile starts with the definition of the standard variables for
declaration (lines 7 to 11). package declaration (lines 7 to 11).
As seen in line 34, it is based on the As seen in line 13, it is based on the +cargo-package+
xref:generic-package-tutorial[+generic-package+ infrastructure]. So, it defines infrastructure. Cargo will be invoked automatically by this
the variables required by this particular infrastructure, where Cargo is infrastructure to build and install the package.
invoked:
* +FOO_BUILD_CMDS+: Cargo is invoked to perform the build. The options required It is still possible to define custom build commands or install
to configure the cross-compilation of the package are passed via commands (i.e. with FOO_BUILD_CMDS and FOO_INSTALL_TARGET_CMDS).
+FOO_CONF_OPTS+. Those will then replace the commands from the cargo infrastructure.
* +FOO_INSTALL_TARGET_CMDS+: The binary executable generated is installed on ==== +cargo-package+ reference
the target.
In order to have Cargo available for the build, +FOO_DEPENDENCIES+ needs to The main macros for the Cargo package infrastructure are
contain +host-cargo+. +cargo-package+ for target packages and +host-cargo-package+ for host
packages.
To sum it up, to add a new Cargo-based package, the Makefile example can be Just like the generic infrastructure, the Cargo infrastructure works
copied verbatim then edited to replace all occurences of +FOO+ with the by defining a number of variables before calling the +cargo-package+
uppercase name of the new package and update the values of the standard or +host-cargo-package+ macros.
variables.
==== About Dependencies Management First, all the package metadata information variables that exist in
the generic infrastructure also exist in the Cargo infrastructure:
+FOO_VERSION+, +FOO_SOURCE+, +FOO_PATCH+, +FOO_SITE+,
+FOO_DEPENDENCIES+, +FOO_LICENSE+, +FOO_LICENSE_FILES+, etc.
A crate can depend on other libraries from crates.io or git repositories, listed A few additional variables, specific to the Cargo infrastructure, can
in its Cargo.toml file. Before starting a build, Cargo usually downloads also be defined. Many of them are only useful in very specific cases,
automatically them. This step can also be performed independently, via the typical packages will therefore only use a few of them.
+cargo fetch+ command.
Cargo maintains a local cache of the registry index and of git checkouts of the * +FOO_CARGO_ENV+ can be used to pass additional variables in the
crates, whose location is given by +$CARGO_HOME+. As seen in the package environment of +cargo+ invocations. It used at both build and
Makefile example at line 15, this environment variable is set to installation time
+$(HOST_DIR)/share/cargo+.
This dependency download mechanism is not convenient when performing an offline * +FOO_CARGO_BUILD_OPTS+ can be used to pass additional options to
build, as Cargo will fail to fetch the dependencies. In that case, it is advised +cargo+ at build time.
to generate a tarball of the dependencies using the +cargo vendor+ and add it to
+FOO_EXTRA_DOWNLOADS+. * +FOO_CARGO_INSTALL_OPTS+ can be used to pass additional options to
+cargo+ at install time.
A crate can depend on other libraries from crates.io or git
repositories, listed in its +Cargo.toml+ file. Buildroot automatically
takes care of downloading such dependencies as part of the download
step of packages that use the +cargo-package+ infrastructure. Such
dependencies are then kept together with the package source code in
the tarball cached in Buildroot's +DL_DIR+, and therefore the hash of
the package's tarball includes such dependencies.
This mechanism ensures that any change in the dependencies will be
detected, and allows the build to be performed completely offline.