Skip to content

Add support for windows linker args#1670

Open
n1ght-hunter wants to merge 1 commit intowild-linker:mainfrom
n1ght-hunter:push-mmnvvqsnqxtl
Open

Add support for windows linker args#1670
n1ght-hunter wants to merge 1 commit intowild-linker:mainfrom
n1ght-hunter:push-mmnvvqsnqxtl

Conversation

@n1ght-hunter
Copy link

@n1ght-hunter n1ght-hunter commented Mar 9, 2026

Requires #1629 to be merged before this can.

This pr adds windows style flags to the args parsing.
It also moves linux flags to linux modules.
This introduces target-lexicon as a new dep. for parsing -target which follows the llvm target triple spec.

Questions to be answered.

  • do we want the new sub modules. args/linux and args/windows. i like having the modules.
  • should they be named after the os or the output type. i.e. switch linux to elf and windows to coff or pe
  • the args/consts needs more thought. these mainly apply to elf only so perhaps should move removed and consts moved into either args.rs or linux.rs
  • do we want to use target-lexicon types more heavily. currently they are mapped to local types i.e. target_lexicon::Architecture -> lib_wild::Architecture. these could be removed from lib_wild and just use target-lexicon but that would mean matching on Architecture will have to match for Architecture's not supported by wild

arch: default_target_arch(),
// Infrastructure
should_fork: true,
arch: const { Architecture::from_target_lexicon(target_lexicon::HOST.architecture) },
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default should probably be the build target architecture not the build host

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to have a separate file for consts. We don't do that kind of thing elsewhere. It's a bit like having a module called "traits". It looks like these constants are a mix of ELF-specific constants and constants that should just be in the top-level args module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github is showing the entire file as new, which means we can't see what has changed. I'd say either leave all the linux argument parsing in args.rs, or we could do a PR before this one where we just copy the file and don't edit it.

/// - `-m <emulation>` — overrides format to ELF when present
///
/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only.
pub(crate) fn detect_target(args: &[String]) -> Result<DetectedTarget> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the --target flag might be too much for this PR, especially since it's non-standard. I worry that the discussion might get bogged down. What about splitting that to a later PR and for this one just accepting --flavor gnu or --flavor link as the first argument like LLD does?

.long("APPCONTAINER")
.help("/APPCONTAINER - Specifies whether the app must run within an appcontainer process environment.")
.execute(|_, _| unimplemented_option("/APPCONTAINER"));
// /ARM64XFUNCTIONPADMINX64 - Specifies the minimum number of bytes of padding between x64 functions in ARM64X images. 17.8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments seem to duplicate the help text. Also, they seem to be copied from Microsoft. I suspect for copyright reasons, we need to come up with our own descriptions of each flag. For unimplemented flags, it'd be fine to have the help text just say "unimplemented" and we can fill in our own descriptions as we implement them.

r#"C:\Users\Samuel\AppData\Local\Temp\rustc7RL5Io\symbols.o"#,
"dummy.dummy.6cfbe55db138f4b-cgu.0.rcgu.o",
"dummy.3wxfnlvokcqcl6j45c8xeicgz.rcgu.o",
r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libstd-efa6c7783284bd31.rlib"#,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps edit these lines to make them a bit shorter.

@mati865 mati865 mentioned this pull request Mar 9, 2026
@n1ght-hunter
Copy link
Author

im pretty busy with work stuff but will get to this over the weekend

Copy link
Member

@mati865 mati865 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few things I noticed during a quick skim through this PR.

pub(crate) nx_compat: bool,
pub(crate) terminal_server_aware: bool,
pub(crate) high_entropy_va: bool,
pub(crate) no_default_libs: Vec<String>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like GNU's -nodefaultlibs but works very differently. I'd suggest renaming it to disabled_default_libs or something like that.

/// and PE-specific fields are accessible via `Deref`/`DerefMut`.
#[derive(Debug)]
pub struct PeArgs {
// Windows-specific fields
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't seem useful - looks like it applies to all struct fields.

Comment on lines +173 to +176
if std::env::var(REFERENCE_LINKER_ENV).is_ok() {
args.write_layout = true;
args.write_trace = true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover?

Comment on lines +112 to +123
let files_per_group: Option<u32> = std::env::var(FILES_PER_GROUP_ENV)
.ok()
.map(|s| s.parse())
.transpose()?;

if let Some(x) = files_per_group {
ensure!(
x <= MAX_FILES_PER_GROUP,
"{FILES_PER_GROUP_ENV}={x} but maximum is {MAX_FILES_PER_GROUP}"
);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover?

}

pub(crate) fn setup_windows_argument_parser() -> ArgumentParser<PeArgs> {
// Helper function for unimplemented options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLMs create unnecessary verbose comments for obvious things like this one. They only needlessly make files longer.

use crate::args::InputSpec;
use std::path::Path;

// Example Windows linker flags from Rust compilation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is misleading, Rust doesn't pass --target to the linkers. Using synthetic command line arguments rather than real-world will be easier to deal with.

Comment on lines +1209 to +1210
assert!(args.debug_info); // /DEBUG flag
assert!(args.nx_compat); // /NXCOMPAT flag
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments like that are not useful.

linker-layout = { path = "../linker-layout", version = "0.8.0" }
linker-trace = { path = "../linker-trace", version = "0.8.0" }
linker-utils = { path = "../linker-utils", version = "0.8.0" }
target-lexicon = { workspace = true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move it near to other t.. deps.

leb128 = "0.2.5"
libc = "0.2.171"
libloading = "0.9.0"
target-lexicon = "0.13.5"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

}
}

fn declare(&mut self) -> OptionDeclaration<'_, NoParam> {
#[must_use]
pub fn new_case_insensitive() -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is link.exe variant, not just case-insensitive.

@n1ght-hunter
Copy link
Author

Few things I noticed during a quick skim through this PR.

thanks so much. will should be able to clean it all up tm. i was hoping to have more time but work had some major issues that took up my time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants