Skip to content

Commit

Permalink
Implement conditional includes for segments
Browse files Browse the repository at this point in the history
Closes #33
  • Loading branch information
AngheloAlf committed Jul 12, 2024
1 parent ac366f9 commit 9af7dc7
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 36 deletions.
2 changes: 1 addition & 1 deletion docs/file_format/custom_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ combinations:
### Conditional inclusion and exclusion of file entries

Custom options can be used to conditionally include or conditionally exclude
certain files.
certain [files](file.md) or [segments](segments.md).

Check the [`include_if_any`](file.md#include_if_any),
[`include_if_all`](file.md#include_if_all),
Expand Down
2 changes: 1 addition & 1 deletion docs/file_format/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ segments:
dir: lib
include_if_any: [[compiler, modern_gcc]]
files:
- { path: libgcc.a }
- { path: libgcc.{abi}.a }
```
### Valid values
Expand Down
8 changes: 8 additions & 0 deletions docs/file_format/segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Every attribute listed is optional unless explicitly stated.
- [Example](#example-6)
- [Valid values](#valid-values-5)
- [Default value](#default-value-4)
- [`include_if_any`, `include_if_all`, `exclude_if_any` and `exclude_if_all`](#include_if_any-include_if_all-exclude_if_any-and-exclude_if_all)
- [`alloc_sections`](#alloc_sections)
- [Example](#example-7)
- [Valid values](#valid-values-6)
Expand Down Expand Up @@ -237,6 +238,13 @@ Any valid path.

Empty path.

## `include_if_any`, `include_if_all`, `exclude_if_any` and `exclude_if_all`

These fields allow to conditionally include or exclude a given segment depending
on the current [custom options](custom_options.md).

Their syntax is the same as their [`file`](file.md#include_if_any) counterparts.

## `alloc_sections`

List of allocatable sections (the ones that take ROM space) for this specific
Expand Down
38 changes: 38 additions & 0 deletions slinky/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,44 @@ impl Document {

Ok(new_path)
}

pub(crate) fn should_emit_entry(&self, exclude_if_any: &[(String, String)], exclude_if_all: &[(String, String)], include_if_any: &[(String, String)], include_if_all: &[(String, String)]) -> bool {
if exclude_if_any
.iter()
.any(|(key, value)| self.custom_options.get(key) == Some(value))
{
return false;
}

if !exclude_if_all.is_empty()
&& exclude_if_all
.iter()
.all(|(key, value)| self.custom_options.get(key) == Some(value))
{
return false;
}

if !include_if_any.is_empty() || !include_if_all.is_empty() {
// If neither include fields match the options then we do not emit this entry

let mut exit = false;
if !include_if_any.is_empty() {
exit = !include_if_any
.iter()
.any(|(key, value)| self.custom_options.get(key) == Some(value));
}
if (exit || include_if_any.is_empty()) && !include_if_all.is_empty() {
exit = !include_if_all
.iter()
.all(|(key, value)| self.custom_options.get(key) == Some(value));
}
if exit {
return false;
}
}

true
}
}

#[derive(Deserialize, PartialEq, Debug)]
Expand Down
39 changes: 5 additions & 34 deletions slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ impl<'a> LinkerWriter<'a> {
}

pub fn add_segment(&mut self, segment: &Segment) -> Result<(), SlinkyError> {
if !self.d.should_emit_entry(&segment.exclude_if_any, &segment.exclude_if_all, &segment.include_if_any, &segment.include_if_all) {
return Ok(());
}

assert!(!self.single_segment);

let style = &self.d.settings.linker_symbols_style;
Expand Down Expand Up @@ -620,43 +624,10 @@ impl LinkerWriter<'_> {
section: &str,
base_path: &Path,
) -> Result<(), SlinkyError> {
if file
.exclude_if_any
.iter()
.any(|(key, value)| self.d.custom_options.get(key) == Some(value))
{
return Ok(());
}
if !file.exclude_if_all.is_empty()
&& file
.exclude_if_all
.iter()
.all(|(key, value)| self.d.custom_options.get(key) == Some(value))
{
if !self.d.should_emit_entry(&file.exclude_if_any, &file.exclude_if_all, &file.include_if_any, &file.include_if_all) {
return Ok(());
}

if !file.include_if_any.is_empty() || !file.include_if_all.is_empty() {
// If neither include fields match the options then we do not emit this entry

let mut exit = false;
if !file.include_if_any.is_empty() {
exit = !file
.include_if_any
.iter()
.any(|(key, value)| self.d.custom_options.get(key) == Some(value));
}
if (exit || file.include_if_any.is_empty()) && !file.include_if_all.is_empty() {
exit = !file
.include_if_all
.iter()
.all(|(key, value)| self.d.custom_options.get(key) == Some(value));
}
if exit {
return Ok(());
}
}

let style = &self.d.settings.linker_symbols_style;

let wildcard = if segment.wildcard_sections { "*" } else { "" };
Expand Down
31 changes: 31 additions & 0 deletions slinky/src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ pub struct Segment {
/// Used as a prefix for all the files emitted for this Segment.
pub dir: PathBuf,

pub include_if_any: Vec<(String, String)>,
pub include_if_all: Vec<(String, String)>,
pub exclude_if_any: Vec<(String, String)>,
pub exclude_if_all: Vec<(String, String)>,

// The default value of the following members come from Settings
pub alloc_sections: Vec<String>,
pub noload_sections: Vec<String>,
Expand Down Expand Up @@ -72,6 +77,15 @@ pub(crate) struct SegmentSerial {
#[serde(default)]
pub dir: AbsentNullable<PathBuf>,

#[serde(default)]
pub include_if_any: AbsentNullable<Vec<(String, String)>>,
#[serde(default)]
pub include_if_all: AbsentNullable<Vec<(String, String)>>,
#[serde(default)]
pub exclude_if_any: AbsentNullable<Vec<(String, String)>>,
#[serde(default)]
pub exclude_if_all: AbsentNullable<Vec<(String, String)>>,

// The default of the following come from Options
#[serde(default)]
pub alloc_sections: AbsentNullable<Vec<String>>,
Expand Down Expand Up @@ -172,6 +186,19 @@ impl SegmentSerial {

let dir = self.dir.get_non_null("dir", PathBuf::new)?;

let include_if_any = self
.include_if_any
.get_non_null("include_if_any", Vec::new)?;
let include_if_all = self
.include_if_all
.get_non_null("include_if_all", Vec::new)?;
let exclude_if_any = self
.exclude_if_any
.get_non_null("exclude_if_any", Vec::new)?;
let exclude_if_all = self
.exclude_if_all
.get_non_null("exclude_if_all", Vec::new)?;

let alloc_sections = self
.alloc_sections
.get_non_null("alloc_sections", || settings.alloc_sections.clone())?;
Expand Down Expand Up @@ -207,6 +234,10 @@ impl SegmentSerial {
follows_segment,
vram_class,
dir,
include_if_any,
include_if_all,
exclude_if_any,
exclude_if_all,
alloc_sections,
noload_sections,
subalign,
Expand Down
Loading

0 comments on commit 9af7dc7

Please sign in to comment.