Skip to content

Commit 7c29e76

Browse files
authored
v0.4.0: support compile time features and env vars (#3)
* Support features and compile-time env vars * Rename `workspace_dir` -> `WORKSPACE_DIR` * Yes local testing for now * Checkin changes * Add changes to rust-bins * Checkin updates for rust-workspaces * Add determination of Lambda architecture * Update docs * Update stuff * Remove unused imports * Fix typo * Add section on conditional compilation * Fix docs * Update docs * Update docs * Update docs * Update docs * Bump version
1 parent b964cac commit 7c29e76

27 files changed

+11699
-32127
lines changed

CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,33 @@ Possible header types:
1111

1212
## [Unreleased]
1313

14+
## v0.4.0 (2022-03-08)
15+
16+
### Features
17+
18+
- Rename `Settings` parameter `workspace_dir` -> `WORKSPACE_DIR`.
19+
- Add support for Rust [features] and compile-time [environment variables].
20+
- Add parameters to `Settings`:
21+
- `FEATURES`
22+
- `BUILD_ENVIRONMENT`
23+
- `EXTRA_BUILD_ARGS`
24+
- Add parameters to `RustFunctionProps`:
25+
- `features`
26+
- `buildEnvironment`
27+
- `extraBuildArgs`
28+
29+
[features]: https://doc.rust-lang.org/cargo/reference/features.html
30+
[environment variables]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
31+
32+
### Breaking Changes
33+
34+
- Updated default target from `x86_64-unknown-linux-musl` -> `x86_64-unknown-linux-gnu`; technically this is not a _breaking_ change, but it will require the target to be added via `rustup`.
35+
36+
### Bug Fixes
37+
38+
- Ensure that the Lambda architecture is correctly set based on the `target` to cross-compile to.
39+
- Do not pass `--target` when running `cargo check`, as this can result in errors in some cases.
40+
1441
## v0.3.0 (2022-02-23)
1542

1643
### Features

README.md

+71-13
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ The `RustFunction` construct creates a Lambda function with automatic bundling a
4646
$ cargo install cross
4747
```
4848

49-
3. Install the **x86_64-unknown-linux-musl** toolchain with Rustup by running:
49+
3. Install the **x86_64-unknown-linux-gnu** toolchain with Rustup by running:
5050

5151
```shell
52-
$ rustup target add x86_64-unknown-linux-musl
52+
$ rustup target add x86_64-unknown-linux-gnu
5353
```
5454

5555
Finally, ensure you have [Docker] installed and running, as it will be used by `cross` to compile Rust code for deployment.
@@ -108,7 +108,7 @@ When bundling the code, the `RustFunction` runs the following steps in order:
108108
- First it runs `cargo check` to confirm that the Rust code can compile.
109109
Note that this is an optional step, and [can be disabled](#settings) as mentioned below.
110110
111-
- Next it calls `cross build`, and passes in the `--release` and `--target` flags, so it compiles for a Lambda environment - which defaults to the **x86_64-unknown-linux-musl** target, as mentioned above.
111+
- Next it calls `cross build`, and passes in the `--release` and `--target` flags, so it compiles for a Lambda environment - which defaults to the **x86_64-unknown-linux-gnu** target, as mentioned above.
112112
113113
- Finally, it copies the release app binary from the `target/` folder to a file named `bootstrap`, which the Lambda custom runtime environment looks for. It adds this new file under the _build directory_, which defaults to a `.build/` folder under the directory where `cdk` was invoked.
114114
@@ -202,19 +202,74 @@ You can find a more complete project structure in the [rust-workspaces/] CDK sam
202202
[workspaces]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html
203203
[rust-workspaces/]: https://github.com/rnag/rust.aws-cdk-lambda/tree/main/cdk-examples/rust-workspaces
204204
205+
## Conditional Compilation
206+
207+
A common use case is building Rust code with enabled [features], and compile-
208+
time environment variables that can be used with the [`env!`] macro.
209+
210+
For example, we might want to run different logic in our code for _development_ and _production_ environments, or call a different API endpoint depending on which environment we are deploying code to.
211+
212+
For a sample CDK app that demonstrate such usage, check out the [rust-bins/] example.
213+
214+
### Enabling Features
215+
216+
You can achieve conditional compilation by [introducing features](https://stackoverflow.com/a/27634313/10237506) which can later be enabled in Rust code.
217+
218+
In the `Cargo.toml`, create a new `features` section:
219+
220+
```toml
221+
[features]
222+
my-feature = [] # feature has no explicit dependencies
223+
```
224+
225+
In your code, add the line `#[cfg(feature="my-feature")]` before a function declaration, or before a statement to execute.
226+
227+
In your CDK code in the `lib/` folder, add the following line:
228+
229+
```ts
230+
// Enable features at compile or build time.
231+
Settings.FEATURES = ['my-feature'];
232+
```
233+
234+
### Build Environment Variables
235+
236+
You can also introduce environment variables which are resolved at build or compile time. These values can be used in code via the [`env!`] macro in Rust.
237+
238+
In your code, add a call to the `env!()` macro:
239+
240+
```rust
241+
// Retrieve an environment variable set at build (compile) time.
242+
let build_value = env!("MY_BUILD_VAR");
243+
```
244+
245+
In your CDK code in the `lib/` folder, add the following line:
246+
247+
```ts
248+
// Enable environment variables at compile or build time.
249+
Settings.BUILD_ENVIRONMENT = {
250+
MY_BUILD_VAR: 'Hello World! Testing 123.',
251+
};
252+
```
253+
254+
[features]: https://doc.rust-lang.org/cargo/reference/features.html
255+
[`env!`]: https://doc.rust-lang.org/std/macro.env.html
256+
205257
## Rust Function Properties
206258
207259
Below lists some commonly used properties you can pass in to the `RustFunction` construct.
208260
209-
| Name | Description |
210-
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
211-
| `target` | Build target to cross-compile to. Defaults to the target for Linux MUSL, `x86_64-unknown-linux-musl`. |
212-
| `directory` | Entry point where the project's main `Cargo.toml` is located. By default, the construct will use directory where `cdk` was invoked as the directory where Cargo files are located. |
213-
| `buildDir` | Default Build directory, which defaults to a `.build` folder under the project's root directory. |
214-
| `bin` | Executable name to pass to `--bin` |
215-
| `package` | Workspace package name to pass to `--package` |
216-
| `setupLogging` | Determines whether we want to set up [library logging](https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html) - i.e. set the `RUST_LOG` environment variable - for the lambda function.<br><br>The format defaults to `warn,module_name=debug`, which means that the default log level is `warn`, and the executable or library's log level is `debug`. |
217-
| |
261+
| Name | Description |
262+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
263+
| `target` | Build target to cross-compile to. Defaults to the target for the **x86_64** architecture, `x86_64-unknown-linux-gnu`. |
264+
| `directory` | Entry point where the project's main `Cargo.toml` is located. By default, the construct will use directory where `cdk` was invoked as the directory where Cargo files are located. |
265+
| `buildDir` | Default Build directory, which defaults to a `.build` folder under the project's root directory. |
266+
| `bin` | Executable name to pass to `--bin` |
267+
| `package` | Workspace package name to pass to `--package` |
268+
| `setupLogging` | Determines whether we want to set up [library logging](https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html) - i.e. set the `RUST_LOG` environment variable - for the lambda function.<br><br>The format defaults to `warn,module_name=debug`, which means that the default log level is `warn`, and the executable or library's log level is `debug`. |
269+
| |
270+
| `features` | A list of features to activate when compiling Rust code. These must also be added to the `Cargo.toml` file. |
271+
| `buildEnvironment` | Key-value pairs that are passed in at compile time, i.e. to `cargo build` or `cross build`. This differs from `environment`, which determines the environment variables which are set on the AWS Lambda function itself. |
272+
| `extraBuildArgs` | Additional arguments that are passed in at build time to both `cargo check` and `cross build`. For example, [`--all-features`]. |
218273
219274
## Settings
220275
@@ -232,4 +287,7 @@ Below are some useful _global_ defaults which can be set for all Rust Lambda Fun
232287
| `RUN_CARGO_CHECK` | Whether to run `cargo check` to validate Rust code before building it with `cross`. Defaults to _true_. |
233288
| `DEFAULT_LOG_LEVEL` | Log Level for non-module libraries. Note that this value is only used when `RustFunctionProps.setupLogging` is enabled. Defaults to `warn`. |
234289
| `MODULE_LOG_LEVEL` | Log Level for a module (i.e. the executable). Note that this value is only used when `RustFunctionProps.setupLogging` is enabled. Defaults to `debug`. |
235-
| `workspace_dir` | Sets the root workspace directory. By default, the workspace directory is assumed to be the directory where `cdk` was invoked.<br><br>This directory should contain at the minimum a `Cargo.toml` file which defines the workspace members. |
290+
| `WORKSPACE_DIR` | Sets the root workspace directory. By default, the workspace directory is assumed to be the directory where `cdk` was invoked.<br><br>This directory should contain at the minimum a `Cargo.toml` file which defines the workspace members. |
291+
| `FEATURES` | A list of features to activate when compiling Rust code. These must also be added to the `Cargo.toml` file. |
292+
| `BUILD_ENVIRONMENT` | Key-value pairs that are passed in at compile time, i.e. to `cargo build` or `cross build`. This differs from `environment`, which determines the environment variables which are set on the AWS Lambda function itself. |
293+
| `EXTRA_BUILD_ARGS` | Additional arguments that are passed in at build time to both `cargo check` and `cross build`. For example, [`--all-features`]. |

cdk-examples/rust-bins/Cargo.toml

+9
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,12 @@ aws-sdk-s3 = "0.6.0"
2222
# Dependencies for `my_lambda2`
2323
anyhow = "1.0.53"
2424
reqwest = { version = "0.11.9", default-features=false, features = ["rustls-tls", "json", "blocking", "stream", "multipart"] }
25+
26+
[features]
27+
28+
# We could choose to enable any project dependencies marked as `optional = true`
29+
# here, but in this case it simply serves as a config flag that we use in code.
30+
#
31+
# See https://stackoverflow.com/a/27634313/10237506 for more info.
32+
my-dev-feature = []
33+
my-prod-feature = []

cdk-examples/rust-bins/lib/rust-bins-stack.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,31 @@ import { Stack, StackProps } from 'aws-cdk-lib';
22
import * as s3 from 'aws-cdk-lib/aws-s3';
33
import { BlockPublicAccess } from 'aws-cdk-lib/aws-s3';
44
import { Construct } from 'constructs';
5-
import { RustFunction, Settings } from 'rust.aws-cdk-lambda';
5+
// import { RustFunction, Settings } from 'rust.aws-cdk-lambda';
66
// uncomment for local testing
7-
// import { RustFunction, Settings } from '../../../lib';
7+
import { RustFunction, Settings } from '../../../lib';
88

99
export class RustBinsStack extends Stack {
1010
constructor(scope: Construct, id: string, props?: StackProps) {
1111
super(scope, id, props);
1212

13+
// Enable optional features and env variables at build (compile) time.
14+
Settings.FEATURES = [
15+
'my-dev-feature',
16+
// uncomment to see how the lambda output changes!
17+
// 'my-prod-feature'
18+
];
19+
Settings.BUILD_ENVIRONMENT = {
20+
LEARN_RUST_URL: 'https://doc.rust-lang.org',
21+
};
22+
1323
// Uncomment if you want to build (e.g. cross-compile) each target, or
1424
// binary, individually.
1525
// Settings.BUILD_INDIVIDUALLY = true;
1626

27+
// Uncomment to cross-compile Rust code to a different Lambda architecture.
28+
// Settings.TARGET = 'aarch64-unknown-linux-gnu';
29+
1730
const bucket = new s3.Bucket(this, 'RustBinsBucket', {
1831
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
1932
publicReadAccess: false,

0 commit comments

Comments
 (0)