Reputation: 498
I created a new buildroot package which is a Rust application built with cargo.
I followed the buildroot manual for Cargo packages, and my .mk
is quite simple:
MY_RUST_APP_VERSION = 1.1.0
MY_RUST_APP_SITE = $(BR2_EXTERNAL_PATH)/package/my-rust-app
MY_RUST_APP_SUBDIR = my-rust-app
MY_RUST_APP_SITE_METHOD = local
# Release build for smaller size and faster execution
# cargo already builds as --release by default in buildroot
#MY_RUST_APP_CARGO_BUILD_OPTS = --release
$(eval $(cargo-package))
It builds fine when Cargo.toml has no dependencies added.
However, when I add the first external dependency to Cargo.toml
, buildroot fails to download and build it:
[dependencies]
tracing = "0.1.40"
buildroot output:
error: no matching package named `tracing` found
location searched: registry `crates-io`
required by package `my-rust-app v1.1.0`
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.
I see that buildroot by default invokes Cargo with --offline
and --locked
which makes it harder to add new crates to Cargo.toml.
How to remove these default flags? Or maybe the approach to development and building a local Rust package should be different?
make my-rust-app-reconfigure
>>> my-rust-app 1.1.0 Building
[...]
__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS="nightly"
CARGO_UNSTABLE_TARGET_APPLIES_TO_HOST="true" CARGO_TARGET_APPLIES_TO_HOST="false"
CARGO_BUILD_TARGET="armv7-unknown-linux-gnueabihf"
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-buildroot-linux-gnueabihf-gcc
RUSTFLAGS="-Clink-arg=-Wl,--allow-multiple-definition" cargo build --offline --release --manifest-path Cargo.toml --locked
Before posting the question, I also tried purging the build directory in hope it will allow Cargo to build. However even make my-rust-app-dirclean && make my-rust-app-reconfigure
doesn't help. I wanted to remove downloads from buildroot/dl/
but cannot locate anything related to Rust dependencies. At the same time, I can successfully build from my package source directory with cargo build
.
Upvotes: 1
Views: 1102
Reputation: 11
An alternative to changing the original code is defining a post rsync hook in the .mk
file.
As already stated, when MY_RUST_APP_SITE_METHOD
is set to local
no crates are downloaded. That is because MY_RUST_APP_DOWNLOAD_POST_PROCESS
(defined in pkg-cargo.mk
) is only executed when there is downloading source involved.
Instead, it is necessary to define a post rsync hook to explicitly fetch crates:
define MY_RUST_APP_CARGO_FETCH
# Hacky way to fetch deps
cd $(MY_RUST_APP_SRCDIR) && \
PATH=$(HOST_DIR)/bin:$(PATH) $(PKG_CARGO_ENV) cargo fetch
endef
# Fetch after rsync
MY_RUST_APP_POST_RSYNC_HOOKS += MY_RUST_APP_CARGO_FETCH
Upvotes: 1
Reputation: 498
I finally managed to solve the problem. Instead of building a local package, I've placed the Rust code in a repository, and used buildroot's git
method of installation.
.mk
file looks like this:
MY_RUST_APP_VERSION = f799b21347968628fff067742d3a05e4152a1ba9 # git hash
MY_RUST_APP_SITE = [email protected]:org/repo.git
MY_RUST_APP_SITE_METHOD = git
MY_RUST_APP_SUBDIR = "packages/my-rust-app"
# Install steps
define MY_RUST_APP_INSTALL_TARGET_CMDS
$(INSTALL) -D \
$(@D)/target/$(RUSTC_TARGET_NAME)/release/my-rust-app \
$(TARGET_DIR)/usr/bin/
endef
$(eval $(cargo-package))
Installing Rust/Cargo crate from git doesn't suffer from the limitations on local crate (--offline
) and doesn't require additional steps like manually creating the .lock
file and fetching the index.
Upvotes: 1
Reputation: 51
The issue you're facing is due to the --offline
flag that Buildroot uses when invoking Cargo. This flag prevents Cargo from reaching out to the internet to download new crates, which is why you're seeing the error when you add a new dependency.
To solve this issue, you need to download the dependencies before building the package with Buildroot. Here's how you can do it:
First, you need to generate a Cargo.lock
file with all the dependencies. You can do this by running cargo generate-lockfile
in your project directory.
Then, you need to download the dependencies. You can do this by running cargo fetch
in your project directory. This will download all the dependencies and store them in your local Cargo registry.
Now, you need to tell Buildroot to use the local Cargo registry instead of trying to download the crates from the internet. You can do this by setting the CARGO_HOME
environment variable to the path of your local Cargo registry. You can add this line to your .mk
file:
MY_RUST_APP_ENV = CARGO_HOME=$(HOME)/.cargo
Finally, you need to tell Buildroot to use the Cargo.lock
file you generated earlier. You can do this by adding this line to your .mk
file:
MY_RUST_APP_CARGO_ENV = CARGO_LOCKFILE_PATH=$(BR2_EXTERNAL_PATH)/package/my-rust-app/Cargo.lock
Now, when you build your package with Buildroot, it should be able to find all the dependencies in your local Cargo registry and build your package successfully.
Remember to replace $(HOME)/.cargo
and $(BR2_EXTERNAL_PATH)/package/my-rust-app/Cargo.lock
with the actual paths on your system.
Upvotes: 3