Cargo Lambda Build
Within a Rust project that includes a Cargo.toml
file, run the cargo lambda build
command to natively cross-compile your Lambda functions in the project to Linux. The resulting artifacts such as binaries or zips, will be placed in the target/lambda
directory. This is an example of the output produced by this command:
❯ tree target/lambda
target/lambda
├── delete-product
│ └── bootstrap
├── dynamodb-streams
│ └── bootstrap
├── get-product
│ └── bootstrap
├── get-products
│ └── bootstrap
└── put-product
└── bootstrap
5 directories, 5 files
❯ tree target/lambda
target/lambda
├── delete-product
│ └── bootstrap
├── dynamodb-streams
│ └── bootstrap
├── get-product
│ └── bootstrap
├── get-products
│ └── bootstrap
└── put-product
└── bootstrap
5 directories, 5 files
The following video shows you how to use this subcommand:
If you want to learn more abour cross-compiling Rust Lambda functions, checkout the Cross Compiling Guide.
Output Format
By default, cargo-lambda produces a binary artifact for each Lambda functions in the project. However, you can configure cargo-lambda to produce a ready to upload zip artifact.
The --output-format
parameter controls the output format, the two current options are zip
and binary
with binary
being the default.
Example usage to create a zip.
cargo lambda build --output-format zip
cargo lambda build --output-format zip
Architectures
By default, cargo-lambda compiles the code for Linux X86-64 architectures, you can compile for Linux ARM architectures by providing the right target:
cargo lambda build --target aarch64-unknown-linux-gnu
cargo lambda build --target aarch64-unknown-linux-gnu
ℹ️ Starting in version 0.6.2, you can use the shortcut --arm64
to compile your functions for Linux ARM architectures:
cargo lambda build --arm64
cargo lambda build --arm64
Compilation Profiles
By default, cargo-lambda compiles the code in debug
mode. If you want to change the profile to compile in release
mode, you can provide the right flag.
cargo lambda build --release
cargo lambda build --release
When you compile your code in release mode, cargo-lambda will apply some optimizations to make the binary size smaller. Check out the Release Optimizations guide for more details.
Extensions
cargo-lambda can also build Lambda Extensions written in Rust. If you want to build a extension, use the flag --extension
to put the output under target/lambda/extensions
, so you don't mix extensions and functions.
cargo lambda build --release --extension
cargo lambda build --release --extension
If you want to create a zip file with the structure that AWS Lambda expects to find extensions in, add the --output-format
flag to the previous command, and cargo-lambda will zip the extensions directory with your extension inside.
cargo lambda build --release --extension --output-format zip
cargo lambda build --release --extension --output-format zip
If you're building an internal extension, add the --internal
flag to the build command. You can skip this flag if you use cargo lambda deploy
to deploy the extension later.
cargo lambda build --release --extension --internal --output-format zip
cargo lambda build --release --extension --internal --output-format zip
Compiler backends
Cargo Lambda has an internal abstraction to work with different ways to compile functions.
The default compiler is cargo-zigbuild
. This compiler uses Zig to cross compile any Rust project to a Linux target on your own OS, without the need to a virtual machine or a Linux container. If Zig is not installed in your host machine, the first time that your run Cargo Lambda, it will guide you through some installation options. If you run Cargo Lambda in a non-interactive shell, the build process will fail until you install that dependency.
Cargo Lambda also supports building Rust projects without Zig as the target linker. This compiler is identifed as just cargo
. A disadvantage of this is that it's up to you to guarantee that the binary works on Linux. An advantage is that if you always build functions on Linux, you don't need to install Zig to use Cargo Lambda.
Cargo Lambda supports building Rust projects with cross as well. Read the Cross Compiling reference to learn more abour using cross as the Lambda compiler.
Adding Zig to PATH on Windows/WSL
If you installed Zig using Pip3 and still encounter issues with Cargo Lambda not finding Zig, it might be because the Zig binary is not in your system’s $PATH
.
To resolve this, you need to manually add the Zig installation path to your environment variables.
Steps:
First, locate where Zig is installed. If you installed it via Pip3, the directory might look like this:
/c/Users/your-username/appdata/local/continuum/anaconda3/lib/site-packages/ziglang/
/c/Users/your-username/appdata/local/continuum/anaconda3/lib/site-packages/ziglang/
or
/home/your-username/.local/lib/python3.9/site-packages/ziglang/
/home/your-username/.local/lib/python3.9/site-packages/ziglang/
To ensure the path persists across terminal sessions, append the following command to your
~/.bashrc
(or~/.zshrc
for Zsh users):bashecho 'export PATH="/path/to/zig:$PATH"' >> ~/.bashrc
echo 'export PATH="/path/to/zig:$PATH"' >> ~/.bashrc
Apply the changes by running:
bashsource ~/.bashrc
source ~/.bashrc
Finally, verify that Zig is in the PATH by running:
bashwhich zig
which zig
After doing this, the cargo lambda build
command should now be able to find Zig and compile your project correctly.
Switching compilers
To switch compilers, you can use the flag --compiler
with the name of the compiler to use when you run cargo lambda build
. For example:
cargo lambda build --compiler cargo
cargo lambda build --compiler cargo
You can also use an environment variable to select the compiler:
export CARGO_LAMBDA_COMPILER=cargo
cargo lambda build
export CARGO_LAMBDA_COMPILER=cargo
cargo lambda build
Additionally, you can also add this option in your project's Cargo.toml
metadata. Add the snippet below if you want to use Cargo without Zig as linker in your project:
[package.metadata.lambda.build.compiler]
type = "cargo"
[package.metadata.lambda.build.compiler]
type = "cargo"
Additional compilers
The concept of compilers on Cargo Lambda is an abstraction on top of different shell commands. If you want to add an additional compiler, you need to implement Compiler trait. The command to execute needs to follow Rust compilations' convenctions, for example, if the user wants to build an Arm64 binary with the release
profile, Cargo Lambda will expect that the resulting binary is in target/aarch64-unknown-linux-gnu/release/
.
Build configuration in Cargo's Metadata
You can keep some build configuration options in your project's Cargo.toml
file. This give you a more "configuration as code" approach since you can store that configuration alongside your project. The following example shows the options that you can specify in the metadata, all of them are optional:
[package.metadata.lambda.build]
include = [ "README.md" ] # Extra list of files to add to the zip bundle
[package.metadata.lambda.build]
include = [ "README.md" ] # Extra list of files to add to the zip bundle
Adding extra files to the zip file
In some situations, you might want to add extra files inside the zip file built. You can use the option --include
to add extra files or directories to the zip file. For example, if you have a directory with configuration files, you can add it to the zip file using the command below:
cargo lambda build --output-format zip --include config
cargo lambda build --output-format zip --include config