Skip to content

Commit

Permalink
Merge pull request tock#4172 from tock/buildrs-crate
Browse files Browse the repository at this point in the history
Boards: Add a build_scripts crate
  • Loading branch information
hudson-ayers authored Oct 5, 2024
2 parents 65dda58 + 6cc494e commit 772ed33
Show file tree
Hide file tree
Showing 102 changed files with 470 additions and 223 deletions.
3 changes: 3 additions & 0 deletions boards/acd52832/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ capsules-core = { path = "../../capsules/core" }
capsules-extra = { path = "../../capsules/extra" }
capsules-system = { path = "../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../build_scripts" }

[lints]
workspace = true
2 changes: 1 addition & 1 deletion boards/acd52832/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ MEMORY

PAGE_SIZE = 4K;

INCLUDE ../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
3 changes: 3 additions & 0 deletions boards/apollo3/lora_things_plus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ capsules-core = { path = "../../../capsules/core" }
capsules-extra = { path = "../../../capsules/extra" }
capsules-system = { path = "../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../build_scripts" }

[lints]
workspace = true

Expand Down
4 changes: 0 additions & 4 deletions boards/apollo3/lora_things_plus/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ flash-app:
.PHONY: test
test:
mkdir -p $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp ../../kernel_layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release

.PHONY: test-atecc508a
test-atecc508a:
mkdir -p $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp ../../kernel_layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release --features atecc508a
2 changes: 1 addition & 1 deletion boards/apollo3/lora_things_plus/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ _lkv_data = LENGTH(kv_data);

PAGE_SIZE = 8K;

INCLUDE ../../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
3 changes: 3 additions & 0 deletions boards/apollo3/redboard_artemis_atp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ capsules-core = { path = "../../../capsules/core" }
capsules-extra = { path = "../../../capsules/extra" }
capsules-system = { path = "../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../build_scripts" }

[lints]
workspace = true
2 changes: 0 additions & 2 deletions boards/apollo3/redboard_artemis_atp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,4 @@ flash-app:
.PHONY: test
test:
mkdir -p $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp ../../kernel_layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release
2 changes: 1 addition & 1 deletion boards/apollo3/redboard_artemis_atp/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ MEMORY

PAGE_SIZE = 8K;

INCLUDE ../../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
3 changes: 3 additions & 0 deletions boards/apollo3/redboard_artemis_nano/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ capsules-core = { path = "../../../capsules/core" }
capsules-extra = { path = "../../../capsules/extra" }
capsules-system = { path = "../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../build_scripts" }

[lints]
workspace = true
2 changes: 0 additions & 2 deletions boards/apollo3/redboard_artemis_nano/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,4 @@ flash-app:
.PHONY: test
test:
mkdir -p $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/deps/
$(Q)cp ../../kernel_layout.ld $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/
$(Q)OBJCOPY=${OBJCOPY} PORT=$(PORT) $(CARGO) test $(NO_RUN) --bin $(PLATFORM) --release
2 changes: 1 addition & 1 deletion boards/apollo3/redboard_artemis_nano/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ MEMORY

PAGE_SIZE = 8K;

INCLUDE ../../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
3 changes: 3 additions & 0 deletions boards/arty_e21/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ capsules-core = { path = "../../capsules/core" }
capsules-extra = { path = "../../capsules/extra" }
capsules-system = { path = "../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../build_scripts" }

[lints]
workspace = true
2 changes: 1 addition & 1 deletion boards/arty_e21/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ MEMORY
ram (rwx) : ORIGIN = 0x80000000, LENGTH = 64K
}

INCLUDE ../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
66 changes: 3 additions & 63 deletions boards/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,69 +13,9 @@
//! # ...
//! build = "../path/to/build.rs"
//! ```
use std::fs;
use std::path::Path;

const LINKER_SCRIPT: &str = "layout.ld";
//!
//! Out-of-tree boards are recommended to copy this file into their board crate.
fn main() {
if !Path::new(LINKER_SCRIPT).exists() {
panic!("Boards must provide a `layout.ld` link script file");
}

// The `RUSTFLAGS` that the Tock config files set can be easily overridden
// by command line flags. The build will still succeed but the resulting
// binary may be invalid as it was not built with the intended flags. This
// check seeks to prevent that. Our approach is we set a sentinel flag in
// our configuration file and then check that it is set here. If it isn't,
// the flags were overwritten and the build will be invalid.
//
// We only do this check if we are actually building for an embedded target
// (i.e., the TARGET is not the same as the HOST). This avoids a false
// positive when running tools like `cargo clippy`.
//
// If you are intentionally not using the standard Tock config files, set
// `cfg-tock-buildflagssentinel` in your cargo config to prevent this
// error.
if std::env::var("HOST") != std::env::var("TARGET") {
let rust_flags = std::env::var("CARGO_ENCODED_RUSTFLAGS");
if !rust_flags
.iter()
.any(|f| f.contains("cfg_tock_buildflagssentinel"))
{
panic!(
"Incorrect build configuration. Verify you are using unstable cargo and have not unintentionally set the RUSTFLAGS environment variable."
);
}
}

// Include the folder where the board's Cargo.toml is in the linker file
// search path.
println!("cargo:rustc-link-arg=-L{}", std::env!("CARGO_MANIFEST_DIR"));
// `-Tlayout.ld`: Use the linker script `layout.ld` all boards must provide.
println!("cargo:rustc-link-arg=-T{}", LINKER_SCRIPT);

track_linker_script(LINKER_SCRIPT);
}

/// Track the given linker script and all of its `INCLUDE`s so that the build
/// is rerun when any of them change.
fn track_linker_script<P: AsRef<Path>>(path: P) {
let path = path.as_ref();

assert!(path.is_file(), "expected path {path:?} to be a file");

println!("cargo:rerun-if-changed={}", path.display());

// Find all the `INCLUDE <relative path>` lines in the linker script.
let link_script = fs::read_to_string(path).expect("failed to read {path:?}");
let includes = link_script
.lines()
.filter_map(|line| line.strip_prefix("INCLUDE").map(str::trim));

// Recursively track included linker scripts.
for include in includes {
track_linker_script(include);
}
tock_build_scripts::default_linker_script();
}
10 changes: 10 additions & 0 deletions boards/build_scripts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2024.

[package]
name = "tock_build_scripts"
description = """Helper functions for compiling Tock boards."""
version.workspace = true
authors.workspace = true
edition.workspace = true
43 changes: 43 additions & 0 deletions boards/build_scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Tock Build Scripts Support Crate
================================

This crate provides helpers for building Tock boards.

Out-of-tree Tock kernel configurations (i.e., Tock boards) can optionally
include this crate as a dependency to use the
[build.rs](https://doc.rust-lang.org/cargo/reference/build-scripts.html)
functionality provided by the kernel.

This crate also packages the default `tock_kernel_layout.ld` linker script.

Usage
-----

There are three general steps to use this crate.

1. This crate should be included as a build dependency in the boards's
Cargo.toml file:

```toml
# Cargo.toml

# ...Existing Cargo.toml contents...

[build-dependencies]
tock_build_scripts = { git = "https://github.com/tock/tock"}
```

This will ensure the crate and the build scripts are available for the board
build.

2. This crate provides a helper function which can used from the board's
build.rs file. In the common case, you just call the provided function from
the build.rs file in your crate's root:

```rs
// build.rs

fn main() {
tock_build_scripts::default_linker_script();
}
```
104 changes: 104 additions & 0 deletions boards/build_scripts/src/default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2024.

//! Provide helpers for building Tock boards that match the default conventions.
use std::fs;
use std::path::Path;

const LINKER_SCRIPT: &str = "layout.ld";

/// Setup the Tock board to build with a board-provided linker script called
/// `layout.ld`.
///
/// The board linker script (i.e., `layout.ld`) should end with the command:
///
/// ```
/// INCLUDE tock_kernel_layout.ld
/// ```
///
/// This function will ensure that the linker's search path is configured to
/// find `tock_kernel_layout.ld`.
pub fn default_linker_script() {
if !Path::new(LINKER_SCRIPT).exists() {
panic!("Boards must provide a `layout.ld` link script file");
}

// The `RUSTFLAGS` that the Tock config files set can be easily overridden
// by command line flags. The build will still succeed but the resulting
// binary may be invalid as it was not built with the intended flags. This
// check seeks to prevent that. Our approach is we set a sentinel flag in
// our configuration file and then check that it is set here. If it isn't,
// the flags were overwritten and the build will be invalid.
//
// We only do this check if we are actually building for an embedded target
// (i.e., the TARGET is not the same as the HOST). This avoids a false
// positive when running tools like `cargo clippy`.
//
// If you are intentionally not using the standard Tock config files, set
// `cfg-tock-buildflagssentinel` in your cargo config to prevent this
// error.
if std::env::var("HOST") != std::env::var("TARGET") {
let rust_flags = std::env::var("CARGO_ENCODED_RUSTFLAGS");
if !rust_flags
.iter()
.any(|f| f.contains("cfg_tock_buildflagssentinel"))
{
panic!(
"Incorrect build configuration. Verify you are using unstable cargo and have not unintentionally set the RUSTFLAGS environment variable."
);
}
}

// Include the folder where this build_script crate's Cargo.toml is in the
// linker file search path for `tock_kernel_layout.ld`.
println!("cargo:rustc-link-arg=-L{}", std::env!("CARGO_MANIFEST_DIR"));
// Directive to rebuild if the linker script in this crate is changed.
println!(
"cargo:rerun-if-changed={}",
Path::new(std::env!("CARGO_MANIFEST_DIR"))
.join("tock_kernel_layout.ld")
.to_string_lossy()
);

// Include the folder where the board's Cargo.toml is in the linker file
// search path.
println!(
"cargo:rustc-link-arg=-L{}",
std::env::var("CARGO_MANIFEST_DIR").unwrap()
);
// `-Tlayout.ld`: Use the linker script `layout.ld` all boards must provide.
println!("cargo:rustc-link-arg=-T{}", LINKER_SCRIPT);

track_linker_script(LINKER_SCRIPT);
}

/// Track the given linker script and all of its `INCLUDE`s so that the build
/// is rerun when any of them change.
fn track_linker_script<P: AsRef<Path>>(path: P) {
let path = path.as_ref();

// Skip the default Tock linker script as we have manually added the
// containing directory to the linker search path and we do not know the
// path to add the rerun directive here. Instead, we add the rerun directory
// for the default Tock linker script manually before calling this function.
if path.to_str() == Some("tock_kernel_layout.ld") {
return;
}

assert!(path.is_file(), "expected path {path:?} to be a file");

println!("cargo:rerun-if-changed={}", path.display());

// Find all the `INCLUDE <relative path>` lines in the linker script.
let link_script = fs::read_to_string(path).expect("failed to read {path:?}");
let includes = link_script
.lines()
.filter_map(|line| line.strip_prefix("INCLUDE").map(str::trim));

// Recursively track included linker scripts.
for include in includes {
track_linker_script(include);
}
}
7 changes: 7 additions & 0 deletions boards/build_scripts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2024.

mod default;

pub use default::default_linker_script;
File renamed without changes.
3 changes: 3 additions & 0 deletions boards/clue_nrf52840/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ capsules-core = { path = "../../capsules/core" }
capsules-extra = { path = "../../capsules/extra" }
capsules-system = { path = "../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../build_scripts" }

[lints]
workspace = true
2 changes: 1 addition & 1 deletion boards/clue_nrf52840/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ MEMORY

PAGE_SIZE = 4K;

INCLUDE ../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ capsules-core = { path = "../../../../capsules/core" }
capsules-extra = { path = "../../../../capsules/extra" }
capsules-system = { path = "../../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../../build_scripts" }

[lints]
workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
/* Copyright Tock Contributors 2023. */

INCLUDE ../../../nordic/nrf52840_chip_layout.ld
INCLUDE ../../../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ capsules-core = { path = "../../../../capsules/core" }
capsules-extra = { path = "../../../../capsules/extra" }
capsules-system = { path = "../../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../../build_scripts" }

[lints]
workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
/* Copyright Tock Contributors 2023. */

INCLUDE ../../../nordic/nrf52840_chip_layout.ld
INCLUDE ../../../kernel_layout.ld
INCLUDE tock_kernel_layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ capsules-core = { path = "../../../../capsules/core" }
capsules-extra = { path = "../../../../capsules/extra" }
capsules-system = { path = "../../../../capsules/system" }

[build-dependencies]
tock_build_scripts = { path = "../../../build_scripts" }

[lints]
workspace = true
Loading

0 comments on commit 772ed33

Please sign in to comment.