1// -*- mode:doc; -*- 2// vim: set syntax=asciidoc: 3 4=== Integration of Cargo-based packages 5 6Cargo is the package manager for the Rust programming language. It allows the 7user to build programs or libraries written in Rust, but it also downloads and 8manages their dependencies, to ensure repeatable builds. Cargo packages are 9called "crates". 10 11[[cargo-package-tutorial]] 12 13==== Cargo-based package's +Config.in+ file 14 15The +Config.in+ file of Cargo-based package 'foo' should contain: 16 17--------------------------- 1801: config BR2_PACKAGE_FOO 1902: bool "foo" 2003: depends on BR2_PACKAGE_HOST_RUSTC_TARGET_ARCH_SUPPORTS 2104: select BR2_PACKAGE_HOST_RUSTC 2205: help 2306: This is a comment that explains what foo is. 2407: 2508: http://foosoftware.org/foo/ 26--------------------------- 27 28==== Cargo-based package's +.mk+ file 29 30Buildroot does not (yet) provide a dedicated package infrastructure for 31Cargo-based packages. So, we will explain how to write a +.mk+ file for such a 32package. Let's start with an example: 33 34------------------------------ 3501: ################################################################################ 3602: # 3703: # foo 3804: # 3905: ################################################################################ 4006: 4107: FOO_VERSION = 1.0 4208: FOO_SOURCE = foo-$(FOO_VERSION).tar.gz 4309: FOO_SITE = http://www.foosoftware.org/download 4410: FOO_LICENSE = GPL-3.0+ 4511: FOO_LICENSE_FILES = COPYING 4612: 4713: FOO_DEPENDENCIES = host-rustc 4814: 4915: FOO_CARGO_ENV = CARGO_HOME=$(HOST_DIR)/share/cargo 5016: 5117: FOO_BIN_DIR = target/$(RUSTC_TARGET_NAME)/$(FOO_CARGO_MODE) 5218: 5319: FOO_CARGO_OPTS = \ 5420: $(if $(BR2_ENABLE_DEBUG),,--release) \ 5521: --target=$(RUSTC_TARGET_NAME) \ 5622: --manifest-path=$(@D)/Cargo.toml 5723: 5824: define FOO_BUILD_CMDS 5925: $(TARGET_MAKE_ENV) $(FOO_CARGO_ENV) \ 6026: cargo build $(FOO_CARGO_OPTS) 6127: endef 6228: 6329: define FOO_INSTALL_TARGET_CMDS 6430: $(INSTALL) -D -m 0755 $(@D)/$(FOO_BIN_DIR)/foo \ 6531: $(TARGET_DIR)/usr/bin/foo 6632: endef 6733: 6834: $(eval $(generic-package)) 69-------------------------------- 70 71The Makefile starts with the definition of the standard variables for package 72declaration (lines 7 to 11). 73 74As seen in line 34, it is based on the 75xref:generic-package-tutorial[+generic-package+ infrastructure]. So, it defines 76the variables required by this particular infrastructure, where Cargo is 77invoked: 78 79* +FOO_BUILD_CMDS+: Cargo is invoked to perform the build. The options required 80 to configure the cross-compilation of the package are passed via 81 +FOO_CONF_OPTS+. 82 83* +FOO_INSTALL_TARGET_CMDS+: The binary executable generated is installed on 84 the target. 85 86In order to have Cargo available for the build, +FOO_DEPENDENCIES+ needs to 87contain +host-cargo+. 88 89To sum it up, to add a new Cargo-based package, the Makefile example can be 90copied verbatim then edited to replace all occurences of +FOO+ with the 91uppercase name of the new package and update the values of the standard 92variables. 93 94==== About Dependencies Management 95 96A crate can depend on other libraries from crates.io or git repositories, listed 97in its Cargo.toml file. Before starting a build, Cargo usually downloads 98automatically them. This step can also be performed independently, via the 99+cargo fetch+ command. 100 101Cargo maintains a local cache of the registry index and of git checkouts of the 102crates, whose location is given by +$CARGO_HOME+. As seen in the package 103Makefile example at line 15, this environment variable is set to 104+$(HOST_DIR)/share/cargo+. 105 106This dependency download mechanism is not convenient when performing an offline 107build, as Cargo will fail to fetch the dependencies. In that case, it is advised 108to generate a tarball of the dependencies using the +cargo vendor+ and add it to 109+FOO_EXTRA_DOWNLOADS+. 110