Skip to content

Commit

Permalink
Merge pull request #96 from great-houk/@file-args
Browse files Browse the repository at this point in the history
Add support for @file args
  • Loading branch information
Urhengulas authored Aug 14, 2024
2 parents 92afdde + 07f16e3 commit dcd8e10
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

- [#96] Add support for @file args
- [#94] Refactor tests
- [#93] Remove TryInto import (in prelude since 2021 edition)
- [#92] Recommend `target.'cfg(..)'.linker` for recent Cargo versions
- [#90] Configure release-plz
- [#88] Setup release-plz

[#96]: https://github.com/knurling-rs/flip-link/pull/96
[#94]: https://github.com/knurling-rs/flip-link/pull/94
[#93]: https://github.com/knurling-rs/flip-link/pull/93
[#92]: https://github.com/knurling-rs/flip-link/pull/92
Expand Down
40 changes: 39 additions & 1 deletion src/argument_parser.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use std::{borrow::Cow, path::PathBuf};
use std::{
borrow::Cow,
fs::File,
io::{BufRead, BufReader},
path::PathBuf,
};

/// Get `output_path`, specified by `-o`
pub fn get_output_path(args: &[String]) -> crate::Result<&String> {
Expand All @@ -22,3 +27,36 @@ pub fn get_search_targets(args: &[String]) -> Vec<Cow<str>> {
.filter_map(|arg| arg.strip_prefix("-T").map(Cow::Borrowed))
.collect()
}

/// Exapnds @file arguments into the file's contents
pub fn expand_files(args: &[String]) -> Vec<String> {
let mut expanded = Vec::with_capacity(args.len());

for arg in args {
if let Some(arg) = arg.strip_prefix('@') {
// The normal linker was able to open the file, so this *should* never panic
let file = File::open(arg).unwrap_or_else(|e| {
panic!("Unable to open {arg}, this should never happen and should be reported: {e}")
});
let reader = BufReader::new(file);
for line in reader.lines() {
// Same as above, normal linker succeeded so we should too
let line = line.unwrap_or_else(|e| {
panic!(
"Invalid file {arg}, this should never happen and should be reported: {e}"
)
});
// Remove quotes if they exist
if line.starts_with('"') && line.ends_with('"') {
expanded.push(line[1..line.len() - 1].to_owned());
} else {
expanded.push(line.to_owned());
}
}
} else {
expanded.push(arg.clone());
}
}

expanded
}
13 changes: 7 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,23 @@ fn notmain() -> Result<i32> {
env_logger::init();

// NOTE `skip` the name/path of the binary (first argument)
let args = env::args().skip(1).collect::<Vec<_>>();
let raw_args = env::args().skip(1).collect::<Vec<_>>();

{
let exit_status = linking::link_normally(&args)?;
let exit_status = linking::link_normally(&raw_args)?;
if !exit_status.success() {
eprintln!(
"\nflip-link: the native linker failed to link the program normally; \
please check your project configuration and linker scripts"
please check your project configuration and linker scripts"
);
return Ok(exit_status.code().unwrap_or(EXIT_CODE_FAILURE));
}
// if linking succeeds then linker scripts are well-formed; we'll rely on that in the parser
}

let expanded_args = argument_parser::expand_files(&raw_args);
let current_dir = env::current_dir()?;
let linker_scripts = get_linker_scripts(&args, &current_dir)?;
let linker_scripts = get_linker_scripts(&expanded_args, &current_dir)?;

// here we assume that we'll end with the same linker script as LLD
// I'm unsure about how LLD picks a linker script when there are multiple candidates in the
Expand All @@ -59,7 +60,7 @@ fn notmain() -> Result<i32> {
let (ram_linker_script, ram_entry) =
ram_path_entry.ok_or("MEMORY.RAM not found after scanning linker scripts")?;

let output_path = argument_parser::get_output_path(&args)?;
let output_path = argument_parser::get_output_path(&expanded_args)?;
let elf = fs::read(output_path)?;
let object = object::File::parse(elf.as_slice())?;

Expand Down Expand Up @@ -99,7 +100,7 @@ fn notmain() -> Result<i32> {
}
new_linker_script.flush()?;

let exit_status = linking::link_modified(&args, &current_dir, tempdir, new_origin)?;
let exit_status = linking::link_modified(&raw_args, &current_dir, tempdir, new_origin)?;
Ok(exit_status)
})?;

Expand Down

0 comments on commit dcd8e10

Please sign in to comment.