1*4882a593Smuzhiyun// -*- mode:doc; -*- 2*4882a593Smuzhiyun// vim: set syntax=asciidoc: 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun=== Integration of Cargo-based packages 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunCargo is the package manager for the Rust programming language. It allows the 7*4882a593Smuzhiyunuser to build programs or libraries written in Rust, but it also downloads and 8*4882a593Smuzhiyunmanages their dependencies, to ensure repeatable builds. Cargo packages are 9*4882a593Smuzhiyuncalled "crates". 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun[[cargo-package-tutorial]] 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun==== Cargo-based package's +Config.in+ file 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunThe +Config.in+ file of Cargo-based package 'foo' should contain: 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun--------------------------- 18*4882a593Smuzhiyun01: config BR2_PACKAGE_FOO 19*4882a593Smuzhiyun02: bool "foo" 20*4882a593Smuzhiyun03: depends on BR2_PACKAGE_HOST_RUSTC_TARGET_ARCH_SUPPORTS 21*4882a593Smuzhiyun04: select BR2_PACKAGE_HOST_RUSTC 22*4882a593Smuzhiyun05: help 23*4882a593Smuzhiyun06: This is a comment that explains what foo is. 24*4882a593Smuzhiyun07: 25*4882a593Smuzhiyun08: http://foosoftware.org/foo/ 26*4882a593Smuzhiyun--------------------------- 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun==== Cargo-based package's +.mk+ file 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunBuildroot does not (yet) provide a dedicated package infrastructure for 31*4882a593SmuzhiyunCargo-based packages. So, we will explain how to write a +.mk+ file for such a 32*4882a593Smuzhiyunpackage. Let's start with an example: 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun------------------------------ 35*4882a593Smuzhiyun01: ################################################################################ 36*4882a593Smuzhiyun02: # 37*4882a593Smuzhiyun03: # foo 38*4882a593Smuzhiyun04: # 39*4882a593Smuzhiyun05: ################################################################################ 40*4882a593Smuzhiyun06: 41*4882a593Smuzhiyun07: FOO_VERSION = 1.0 42*4882a593Smuzhiyun08: FOO_SOURCE = foo-$(FOO_VERSION).tar.gz 43*4882a593Smuzhiyun09: FOO_SITE = http://www.foosoftware.org/download 44*4882a593Smuzhiyun10: FOO_LICENSE = GPL-3.0+ 45*4882a593Smuzhiyun11: FOO_LICENSE_FILES = COPYING 46*4882a593Smuzhiyun12: 47*4882a593Smuzhiyun13: FOO_DEPENDENCIES = host-rustc 48*4882a593Smuzhiyun14: 49*4882a593Smuzhiyun15: FOO_CARGO_ENV = CARGO_HOME=$(HOST_DIR)/share/cargo 50*4882a593Smuzhiyun16: 51*4882a593Smuzhiyun17: FOO_BIN_DIR = target/$(RUSTC_TARGET_NAME)/$(FOO_CARGO_MODE) 52*4882a593Smuzhiyun18: 53*4882a593Smuzhiyun19: FOO_CARGO_OPTS = \ 54*4882a593Smuzhiyun20: $(if $(BR2_ENABLE_DEBUG),,--release) \ 55*4882a593Smuzhiyun21: --target=$(RUSTC_TARGET_NAME) \ 56*4882a593Smuzhiyun22: --manifest-path=$(@D)/Cargo.toml 57*4882a593Smuzhiyun23: 58*4882a593Smuzhiyun24: define FOO_BUILD_CMDS 59*4882a593Smuzhiyun25: $(TARGET_MAKE_ENV) $(FOO_CARGO_ENV) \ 60*4882a593Smuzhiyun26: cargo build $(FOO_CARGO_OPTS) 61*4882a593Smuzhiyun27: endef 62*4882a593Smuzhiyun28: 63*4882a593Smuzhiyun29: define FOO_INSTALL_TARGET_CMDS 64*4882a593Smuzhiyun30: $(INSTALL) -D -m 0755 $(@D)/$(FOO_BIN_DIR)/foo \ 65*4882a593Smuzhiyun31: $(TARGET_DIR)/usr/bin/foo 66*4882a593Smuzhiyun32: endef 67*4882a593Smuzhiyun33: 68*4882a593Smuzhiyun34: $(eval $(generic-package)) 69*4882a593Smuzhiyun-------------------------------- 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunThe Makefile starts with the definition of the standard variables for package 72*4882a593Smuzhiyundeclaration (lines 7 to 11). 73*4882a593Smuzhiyun 74*4882a593SmuzhiyunAs seen in line 34, it is based on the 75*4882a593Smuzhiyunxref:generic-package-tutorial[+generic-package+ infrastructure]. So, it defines 76*4882a593Smuzhiyunthe variables required by this particular infrastructure, where Cargo is 77*4882a593Smuzhiyuninvoked: 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun* +FOO_BUILD_CMDS+: Cargo is invoked to perform the build. The options required 80*4882a593Smuzhiyun to configure the cross-compilation of the package are passed via 81*4882a593Smuzhiyun +FOO_CONF_OPTS+. 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun* +FOO_INSTALL_TARGET_CMDS+: The binary executable generated is installed on 84*4882a593Smuzhiyun the target. 85*4882a593Smuzhiyun 86*4882a593SmuzhiyunIn order to have Cargo available for the build, +FOO_DEPENDENCIES+ needs to 87*4882a593Smuzhiyuncontain +host-cargo+. 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunTo sum it up, to add a new Cargo-based package, the Makefile example can be 90*4882a593Smuzhiyuncopied verbatim then edited to replace all occurences of +FOO+ with the 91*4882a593Smuzhiyunuppercase name of the new package and update the values of the standard 92*4882a593Smuzhiyunvariables. 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun==== About Dependencies Management 95*4882a593Smuzhiyun 96*4882a593SmuzhiyunA crate can depend on other libraries from crates.io or git repositories, listed 97*4882a593Smuzhiyunin its Cargo.toml file. Before starting a build, Cargo usually downloads 98*4882a593Smuzhiyunautomatically them. This step can also be performed independently, via the 99*4882a593Smuzhiyun+cargo fetch+ command. 100*4882a593Smuzhiyun 101*4882a593SmuzhiyunCargo maintains a local cache of the registry index and of git checkouts of the 102*4882a593Smuzhiyuncrates, whose location is given by +$CARGO_HOME+. As seen in the package 103*4882a593SmuzhiyunMakefile example at line 15, this environment variable is set to 104*4882a593Smuzhiyun+$(HOST_DIR)/share/cargo+. 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunThis dependency download mechanism is not convenient when performing an offline 107*4882a593Smuzhiyunbuild, as Cargo will fail to fetch the dependencies. In that case, it is advised 108*4882a593Smuzhiyunto generate a tarball of the dependencies using the +cargo vendor+ and add it to 109*4882a593Smuzhiyun+FOO_EXTRA_DOWNLOADS+. 110