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 10, 2022
1 parent 25a1fd2 commit 6828538
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 33 deletions.
1 change: 1 addition & 0 deletions crates/tools/gnu/Cargo.toml
Expand Up @@ -6,3 +6,4 @@ publish = false

[dependencies]
lib = { package = "tool_lib", path = "../lib" }
which = "4"
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`
58 changes: 40 additions & 18 deletions crates/tools/gnu/src/main.rs
@@ -1,28 +1,37 @@
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet};
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 which::which(cmd).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 @@ -81,6 +90,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 Down

0 comments on commit 6828538

Please sign in to comment.