3 releases
0.1.2 | Nov 21, 2022 |
---|---|
0.1.1 | Aug 23, 2022 |
0.1.0 | Jun 16, 2022 |
#331 in Cargo plugins
68KB
1.5K
SLoC
cargo-acap
A tool to build Rust programs for the AXIS Camera Application Platform.
Example
$ cargo install cargo-acap
…
Installed package `cargo-acap v0.1.0` (executable `cargo-acap`)
$ cargo new --bin your-app
Created binary (application) `your-app` package
$ cd your-app/
$ cargo acap build
cargo-acap: building ACAP package `your-app` using Docker image trunnion/cargo-acap-build:1.60.0
…
Finished release [optimized] target(s) in 0.56s
$ ls target/acap/*.* | cat
target/acap/your-app_0.1.0_aarch64.eap
target/acap/your-app_0.1.0_aarch64.elf
target/acap/your-app_0.1.0_armv5tej.eap
target/acap/your-app_0.1.0_armv5tej.elf
target/acap/your-app_0.1.0_armv6.eap
target/acap/your-app_0.1.0_armv6.elf
target/acap/your-app_0.1.0_armv7.eap
target/acap/your-app_0.1.0_armv7.elf
target/acap/your-app_0.1.0_armv7hf.eap
target/acap/your-app_0.1.0_armv7hf.elf
target/acap/your-app_0.1.0_mips.eap
target/acap/your-app_0.1.0_mips.elf
cargo-acap
builds your application using a Docker image specialized for compiling Rust for AXIS devices. It therefore
requires Docker to be installed and running in order to build.
Application organization
foo/
Cargo.toml Rust project configuration + `[package.metadata.acap]`
data/ Copied to `/usr/local/packages/foo/data/`, i.e. `./data/`
src/
main.rs `fn main()`
target/
acap/
foo_0.1.0_aarch64.eap An ACAP package suitable for AArch64 devices
foo_0.1.0_aarch64.elf The executable inside foo_0.1.0_aarch64.eap prior to stripping symbols
…4 more…
foo_0.1.0_mips.eap An ACAP package suitable for MIPS devices
foo_0.1.0_mips.elf The executable inside foo_0.1.0_mips.eap prior to stripping symbols
Conditional compilation
cargo acap
builds your application with target_vendor = "axis"
, enabling one source tree to support both on- and
off-device usage via conditional compilation.
#[cfg(target_vendor = "axis")]
fn foo() {
// call on-device APIs
}
#[cfg(not(target_vendor = "axis"))]
fn foo() {
// call off-device APIs
}
fn bar() {
if cfg!(target_vendor = "axis") {
// on-device
} else {
// off-device
}
}
#[cfg_attr(target_vendor = "axis", path = "baz_on_device.rs")]
#[cfg_attr(not(target_vendor = "axis"), path = "baz_off_device.rs")]
mod baz;
#[test]
#[cfg_attr(not(target_vendor = "axis"), ignore)]
fn quxx() {
// this test will run everywhere, but will be ignored if not on-device
}
Packaging
cargo acap
builds your application's executable and then packages it into an .eap
application package. The package
contains metadata which is set to sensible defaults but can be overridden via Cargo.toml
.
[package.metadata.acap]
# The machine-friendly name of the package. Used for:
#
# * Installation path: `/usr/local/packages/<app_name>`
# * Executable path: `/usr/local/packages/<app_name>/<app_name>`
# * Generated package names: `<app_name>_1_2_3_arch.eap`
# * Myriad related files
#
# app_name = ""
# A user-friendly package name. The name will be displayed in the Axis product's web pages.
# display_name = ""
# The application name that will be displayed in the web pages' left-hand side menu.
# menu_name = ""
# The name of the vendor that created the application.
# vendor = ""
# The URL of the vendor's home page, to be linked in the product's web pages.
# vendor_homepage_url = ""
# The command line arguments to pass when the application is launched normally.
# launch_arguments = ""
# The command line arguments to pass when the application is executed to perform a custom license check, if using custom
# licensing.
# license_check_arguments = ""
# The Axis-assigned application ID, if using Axis licensing.
# axis_application_id = ""
# The start mode to use for this application.
# (One of: "respawn", "once", "never")
# start_mode = ""
Targets
Different AXIS products use different SoCs which contain different
processors. cargo acap
provides a Docker build environment containing everything needed to build software for various
AXIS devices. These targets are described in cargo acap targets table
:
cargo acap target |
Rust --target |
---|---|
aarch64 |
aarch64-axis-linux-gnu |
armv5tej |
armv5te-axis-linux-gnueabi |
armv6 |
arm-axis-linux-gnueabi |
armv7 |
armv7-axis-linux-gnueabi |
armv7hf |
armv7-axis-linux-gnueabihf |
mips |
mipsel-axis-linux-gnu |
cargo acap
is specialized for AXIS products, so it uses abbreviated target names on the left. The Rust target triples
defined by the cargo-acap-build
environment are presented here for completeness.
These targets correspond to the system-on-chips listed in cargo acap targets soc_table
:
SOC | Year | cargo acap target |
Rust --target |
---|---|---|---|
Axis ARTPEC-1 | 1999 | (unsupported) | (unsupported) |
Axis ARTPEC-2 | 2003 | (unsupported) | (unsupported) |
Axis ARTPEC-3 | 2007 | (unsupported) | (unsupported) |
Ambarella A5S | 2010 | armv6 |
arm-axis-linux-gnueabi |
Axis ARTPEC-4 | 2011 | mips |
mipsel-axis-linux-gnu |
Ambarella S2 | 2012 | armv7 |
armv7-axis-linux-gnueabi |
Ambarella S2E | 2012 | armv7hf |
armv7-axis-linux-gnueabihf |
Ambarella S2L | 2012 | armv7hf |
armv7-axis-linux-gnueabihf |
Axis ARTPEC-5 | 2013 | mips |
mipsel-axis-linux-gnu |
NXP i.MX 8 QP | 2013 | aarch64 |
aarch64-axis-linux-gnu |
Ambarella S3L | 2014 | armv7hf |
armv7-axis-linux-gnueabihf |
Ambarella S5 | 2016 | aarch64 |
aarch64-axis-linux-gnu |
Ambarella S5L | 2016 | aarch64 |
aarch64-axis-linux-gnu |
Hi3516C V300 | 2016 | armv5tej |
armv5te-axis-linux-gnueabi |
Hi3719C V100 | 2016 | armv7hf |
armv7-axis-linux-gnueabihf |
Axis ARTPEC-6 | 2017 | armv7hf |
armv7-axis-linux-gnueabihf |
Axis ARTPEC-7 | 2019 | armv7hf |
armv7-axis-linux-gnueabihf |
The AXIS product interface guide describes
many hardware configurations in detail, though it is incomplete. Check your device's root.Properties.System.Soc
and
.Architecture
parameter to see what your
specific device uses.
cargo acap build
enables every target by default. This can be overridden in Cargo.toml
:
[package.metadata.acap]
targets = ["aarch64", "armv7", "armv7hf"]
Dependencies
~53MB
~1M SLoC