Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`SOURCE_DATE_EPOCH` changes the behavior of tools well beyond ours (gzip,
tar, python bytecode) and hooks should not inherit that unasked. `ext image`
continues to export `0`.
- **A runtime package's `compile:` section now counts as active.** Only
`kernel.compile` and extension packages were scanned, so a section reached
through `runtimes.<name>.packages.<pkg>.compile` was treated as unused: no
target-dev sysroot was provisioned and the section's own `packages:` were
dropped without a word. The build then failed much later on missing target
headers or libraries, with nothing pointing back at the cause.

That scan is also scoped to the current target now, the way the sibling
extension scan already was. It previously read every runtime in the file
regardless of `runtimes.<name>.target`, which in a multi-target config
provisioned target-dev for runtimes the user had not asked to build. The scan
reads the merged runtime config, so a `compile:` reference declared inside a
`target-<t>:` override block counts too — selecting runtimes from resolved
config while scanning unresolved config meant no target-dev sysroot was
installed for such a section, yet `runtime build` still ran its compile
script.
- **A runtime that names its `target:` only inside a `target-<t>:` block is no
longer treated as targeting everything.** Override resolution strips the
non-matching blocks before target selection reads the runtime, so such a
runtime arrived with no `target:` key at all and matched the
"no target declared, applies to every target" branch. `avocado sdk install
--target qemux86-64` would install a raspberrypi4-only runtime's compile
packages into the x86-64 target sysroot. A `target-<t>:` block for the target
being built still keeps a runtime in scope even when it declares no `target:`
of its own. This also scopes the extension and runtime steps of `avocado
install`, which shared the selection logic through a duplicate that has been
collapsed onto the fixed one.
- **Rootfs and initramfs no longer reinstall on every run.** `avocado sdk
install` wiped and rebuilt both sysroots from scratch on every invocation,
even with nothing changed. Removal detection compared the lockfile against
Expand Down
66 changes: 14 additions & 52 deletions src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,64 +490,26 @@ impl InstallCommand {
Ok(extensions)
}

/// Find runtimes that are relevant for the specified target
/// Find runtimes that are relevant for the specified target.
///
/// Delegates to the shared helper rather than keeping a second copy of the
/// selection logic: this one had drifted into an independently maintained
/// duplicate, and the target-override handling the shared version grew would
/// otherwise apply to the SDK step of an install but not to its extension
/// and runtime steps.
fn find_target_relevant_runtimes(
&self,
config: &Config,
parsed: &serde_yaml::Value,
target: &str,
) -> Result<Vec<String>> {
let mut relevant_runtimes = Vec::new();

if let Some(runtime_section) = parsed.get("runtimes").and_then(|r| r.as_mapping()) {
for runtime_name_val in runtime_section.keys() {
if let Some(runtime_name) = runtime_name_val.as_str() {
// If a specific runtime is requested, only check that one
if let Some(ref requested_runtime) = self.runtime {
if runtime_name != requested_runtime {
continue;
}
}

// Check if this runtime is relevant for the target
let merged_runtime = config.get_merged_runtime_config(
runtime_name,
target,
&self.config_path,
)?;
if let Some(merged_value) = merged_runtime {
if let Some(runtime_target) =
merged_value.get("target").and_then(|t| t.as_str())
{
// Runtime has explicit target - only include if it matches
if runtime_target == target {
relevant_runtimes.push(runtime_name.to_string());
}
} else {
// Runtime has no target specified - include for all targets
relevant_runtimes.push(runtime_name.to_string());
}
} else {
// If there's no merged config, check the base runtime config
if let Some(runtime_config) = runtime_section.get(runtime_name_val) {
if let Some(runtime_target) =
runtime_config.get("target").and_then(|t| t.as_str())
{
// Runtime has explicit target - only include if it matches
if runtime_target == target {
relevant_runtimes.push(runtime_name.to_string());
}
} else {
// Runtime has no target specified - include for all targets
relevant_runtimes.push(runtime_name.to_string());
}
}
}
}
}
}

Ok(relevant_runtimes)
crate::utils::config::find_target_relevant_runtimes(
config,
parsed,
target,
&self.config_path,
self.runtime.as_deref(),
)
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/commands/sdk/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,14 @@ impl SdkInstallCommand {
// Discover whether target-dev sysroot is needed (compile sections from
// fetched external extensions). Prepare the command BEFORE launching
// the parallel sysroot installs so all four can run concurrently.
let active_compile_sections =
find_active_compile_sections(&composed.merged_value, active_extensions);
let active_compile_sections = find_active_compile_sections(
config,
&composed.merged_value,
active_extensions,
target,
&composed.config_path,
None,
)?;
// An extension declaring device-tree overlays needs the delivery
// hook in the target-sysroot, so provision the target-sysroot even when
// there is no compile section (a no-#include overlay needs no kernel-devsrc).
Expand Down
Loading
Loading