Skip to content

Commit

Permalink
Don't require two different MinGW environments to build the *_gnu imp…
Browse files Browse the repository at this point in the history
…ort libraries

And at the same time, allow to use MinGW tools on any OS.
  • Loading branch information
glandium committed Sep 11, 2022
1 parent 1591b8c commit de76f27
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 36 deletions.
17 changes: 2 additions & 15 deletions crates/tools/gnu/readme.md
@@ -1,21 +1,8 @@
The Windows umbrella lib (targeting GNU tooling) is generated using the following steps:

0. Ensure MSYS2 MinGW environment is installed (https://www.mingw-w64.org/downloads/)
1. Ensure `~\.cargo\config` has the following blocks to override toolchain defaults (customize paths as needed):

```toml
[target.i686-pc-windows-gnu]
linker = "C:\\msys64\\mingw32\\bin\\i686-w64-mingw32-gcc.exe"
ar = "C:\\msys64\\mingw32\\bin\\ar.exe"

[target.x86_64-pc-windows-gnu]
linker = "C:\\msys64\\mingw64\\bin\\x86_64-w64-mingw32-gcc.exe"
ar = "C:\\msys64\\mingw64\\bin\\ar.exe"
```

1. Open `MSYS2 MinGW 32-bit`
1. Open `MSYS2 MinGW 64-bit`
2. Execute: `pacman -Syuu --noconfirm` (repeat until no further updates available)
3. Repeat step 1 if needed
4. Navigate to crate root
5. Execute: `PATH=$USERPROFILE/.cargo/bin:$PATH cargo run -p tool_gnu --target i686-pc-windows-gnu`
6. Repeat steps 1-5, using the `MSYS MinGW 64-bit` environment and `x86_64-pc-windows-gnu` target
5. Execute: `PATH=$USERPROFILE/.cargo/bin:$PATH cargo run -p tool_gnu -- all`
65 changes: 44 additions & 21 deletions crates/tools/gnu/src/main.rs
@@ -1,28 +1,38 @@
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet};
use std::process::{Command, Stdio};
use std::io::prelude::*;

fn main() {
let mut cmd = std::process::Command::new("where");
cmd.arg("dlltool.exe");

let output = cmd.output().unwrap();

if !output.status.success() {
println!("dlltool.exe not found");
return;
for cmd in ["dlltool", "ar", "objcopy"] {
if Command::new(cmd).stdout(Stdio::null()).stderr(Stdio::null()).spawn().is_err() {
eprintln!("Could not find {}. Is it in your $PATH?", cmd);
return;
}
}

const ALL_PLATFORMS: [&str; 2] = ["x86_64_gnu", "i686_gnu"];
let mut platforms = BTreeSet::new();
for platform in std::env::args().skip(1) {
if ALL_PLATFORMS.contains(&&*platform) {
platforms.insert(platform);
} else if platform == "all" {
platforms.extend(ALL_PLATFORMS.iter().map(|s| s.to_string()));
} else {
eprintln!("Unknown platform: {}", platform);
return;
}
}

let output = unsafe { core::str::from_utf8_unchecked(&output.stdout) };

let platform = if output.contains("mingw64") {
"x86_64_gnu"
} else if output.contains("mingw32") {
"i686_gnu"
} else {
println!("mingw not found");
if platforms.is_empty() {
eprintln!("Please specify at least one platform or use 'all' argument");
return;
};

for platform in platforms {
build_platform(&platform);
}
}

fn build_platform(platform: &str) {
println!("Platform: {}", platform);

let libraries = lib::libraries();
Expand Down Expand Up @@ -70,7 +80,7 @@ EXPORTS

drop(def);

let mut cmd = std::process::Command::new("dlltool");
let mut cmd = Command::new("dlltool");
cmd.current_dir(output);

if platform.eq("i686_gnu") {
Expand All @@ -81,6 +91,19 @@ EXPORTS
cmd.arg(format!("{}.def", library));
cmd.arg("-l");
cmd.arg(format!("lib{}.a", library));
cmd.arg("-m");
cmd.arg(match platform {
"i686_gnu" => "i386",
"x86_64_gnu" => "i386:x86-64",
_ => unreachable!(),
});
// Work around https://sourceware.org/bugzilla/show_bug.cgi?id=29497
cmd.arg("-f");
cmd.arg(match platform {
"i686_gnu" => "--32",
"x86_64_gnu" => "--64",
_ => unreachable!(),
});
// Ensure consistency in the prefixes used by dlltool.
cmd.arg("-t");
if library.contains('.') {
Expand All @@ -93,7 +116,7 @@ EXPORTS
// Work around lack of determinism in dlltool output, and at the same time remove
// unnecessary sections and symbols.
std::fs::rename(output.join(format!("lib{}.a", library)), output.join("tmp.a")).unwrap();
let mut cmd = std::process::Command::new("objcopy");
let mut cmd = Command::new("objcopy");
cmd.current_dir(output);
cmd.arg("--remove-section=.bss");
cmd.arg("--remove-section=.data");
Expand Down Expand Up @@ -127,7 +150,7 @@ fn build_mri(output: &std::path::Path, libraries: &BTreeMap<String, BTreeMap<Str

mri.write_all(b"SAVE\nEND\n").unwrap();

let mut cmd = std::process::Command::new("ar");
let mut cmd = Command::new("ar");
cmd.current_dir(output);
cmd.arg("-M");
cmd.stdin(std::fs::File::open(&mri_path).unwrap());
Expand Down

0 comments on commit de76f27

Please sign in to comment.