Skip to content

Commit

Permalink
Handle both *_gnu and *_gnullvm import libraries from the same command
Browse files Browse the repository at this point in the history
  • Loading branch information
glandium committed Sep 10, 2022
1 parent 6828538 commit 3fb985d
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 179 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Expand Up @@ -187,7 +187,6 @@ jobs:
cargo clippy -p test_window_long &&
cargo clippy -p test_winrt &&
cargo clippy -p tool_gnu &&
cargo clippy -p tool_gnullvm &&
cargo clippy -p tool_ilrs &&
cargo clippy -p tool_lib &&
cargo clippy -p tool_msvc &&
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Expand Up @@ -171,7 +171,6 @@ jobs:
cargo test --target ${{ matrix.target }} -p test_window_long &&
cargo test --target ${{ matrix.target }} -p test_winrt &&
cargo test --target ${{ matrix.target }} -p tool_gnu &&
cargo test --target ${{ matrix.target }} -p tool_gnullvm &&
cargo test --target ${{ matrix.target }} -p tool_ilrs &&
cargo test --target ${{ matrix.target }} -p tool_lib &&
cargo test --target ${{ matrix.target }} -p tool_msvc &&
Expand Down
9 changes: 5 additions & 4 deletions crates/tools/gnu/readme.md
@@ -1,8 +1,9 @@
The Windows umbrella lib (targeting GNU tooling) is generated using the following steps:
The Windows umbrella lib (targeting GNU and LLVM tooling) is generated using the following steps:

0. Ensure MSYS2 MinGW environment is installed (https://www.mingw-w64.org/downloads/)
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 -- all`
3. Execute: `pacman --needed -S mingw-w64-x86_64-llvm`
4. Repeat step 1 if needed
5. Navigate to crate root
6. Execute: `PATH=$USERPROFILE/.cargo/bin:$PATH cargo run -p tool_gnu -- all`
108 changes: 57 additions & 51 deletions crates/tools/gnu/src/main.rs
Expand Up @@ -2,14 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::io::prelude::*;

fn main() {
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"];
const ALL_PLATFORMS: [&str; 4] = ["x86_64_gnu", "i686_gnu", "x86_64_gnullvm", "aarch64_gnullvm"];
let mut platforms = BTreeSet::new();
for platform in std::env::args().skip(1) {
if ALL_PLATFORMS.contains(&&*platform) {
Expand All @@ -27,11 +20,19 @@ fn main() {
};

for platform in platforms {
build_platform(&platform);
let tools = if platform.ends_with("_gnu") { &["dlltool", "ar", "objcopy"][..] } else { &["llvm-dlltool", "llvm-ar"][..] };
for tool in tools {
if which::which(tool).is_err() {
eprintln!("Could not find {}. Is it in your $PATH?", tool);
return;
}
}

build_platform(&platform, tools[0], tools[1]);
}
}

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

let libraries = lib::libraries();
Expand All @@ -40,17 +41,17 @@ fn build_platform(platform: &str) {
std::fs::create_dir_all(&output).unwrap();

for (library, functions) in &libraries {
build_library(&output, library, functions, platform);
build_library(&output, dlltool, library, functions, platform);
}

build_mri(&output, &libraries);
build_mri(&output, ar, &libraries);

for library in libraries.keys() {
std::fs::remove_file(output.join(format!("lib{}.a", library))).unwrap();
}
}

fn build_library(output: &std::path::Path, library: &str, functions: &BTreeMap<String, lib::CallingConvention>, platform: &str) {
fn build_library(output: &std::path::Path, dlltool: &str, library: &str, functions: &BTreeMap<String, lib::CallingConvention>, platform: &str) {
println!("{}", library);

// Note that we don't use set_extension as it confuses PathBuf when the library name includes a period.
Expand Down Expand Up @@ -79,7 +80,7 @@ EXPORTS

drop(def);

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

if platform.eq("i686_gnu") {
Expand All @@ -93,50 +94,55 @@ EXPORTS
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",
"x86_64_gnu" | "x86_64_gnullvm" => "i386:x86-64",
"aarch64_gnullvm" => "arm64",
_ => unreachable!(),
});
// Ensure consistency in the prefixes used by dlltool.
cmd.arg("-t");
if library.contains('.') {
cmd.arg(format!("{}_", library).replace('.', "_").replace('-', "_"));
} else {
cmd.arg(format!("{}_dll_", library).replace('-', "_"));
if dlltool == "dlltool" {
// 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('.') {
cmd.arg(format!("{}_", library).replace('.', "_").replace('-', "_"));
} else {
cmd.arg(format!("{}_dll_", library).replace('-', "_"));
}
}
cmd.output().unwrap();

// 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");
cmd.current_dir(output);
cmd.arg("--remove-section=.bss");
cmd.arg("--remove-section=.data");
cmd.arg("--strip-unneeded-symbol=fthunk");
cmd.arg("--strip-unneeded-symbol=hname");
cmd.arg("--strip-unneeded-symbol=.file");
cmd.arg("--strip-unneeded-symbol=.text");
cmd.arg("--strip-unneeded-symbol=.data");
cmd.arg("--strip-unneeded-symbol=.bss");
cmd.arg("--strip-unneeded-symbol=.idata$7");
cmd.arg("--strip-unneeded-symbol=.idata$5");
cmd.arg("--strip-unneeded-symbol=.idata$4");
cmd.arg("tmp.a");
cmd.arg(format!("lib{}.a", library));
cmd.output().unwrap();

std::fs::remove_file(output.join("tmp.a")).unwrap();
if dlltool == "dlltool" {
// 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");
cmd.current_dir(output);
cmd.arg("--remove-section=.bss");
cmd.arg("--remove-section=.data");
cmd.arg("--strip-unneeded-symbol=fthunk");
cmd.arg("--strip-unneeded-symbol=hname");
cmd.arg("--strip-unneeded-symbol=.file");
cmd.arg("--strip-unneeded-symbol=.text");
cmd.arg("--strip-unneeded-symbol=.data");
cmd.arg("--strip-unneeded-symbol=.bss");
cmd.arg("--strip-unneeded-symbol=.idata$7");
cmd.arg("--strip-unneeded-symbol=.idata$5");
cmd.arg("--strip-unneeded-symbol=.idata$4");
cmd.arg("tmp.a");
cmd.arg(format!("lib{}.a", library));
cmd.output().unwrap();

std::fs::remove_file(output.join("tmp.a")).unwrap();
}
std::fs::remove_file(output.join(format!("{}.def", library))).unwrap();
}

fn build_mri(output: &std::path::Path, libraries: &BTreeMap<String, BTreeMap<String, lib::CallingConvention>>) {
fn build_mri(output: &std::path::Path, ar: &str, libraries: &BTreeMap<String, BTreeMap<String, lib::CallingConvention>>) {
let mri_path = output.join("unified.mri");
let mut mri = std::fs::File::create(&mri_path).unwrap();
println!("Generating {}", mri_path.to_string_lossy());
Expand All @@ -149,7 +155,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 = std::process::Command::new(ar);
cmd.current_dir(output);
cmd.arg("-M");
cmd.stdin(std::fs::File::open(&mri_path).unwrap());
Expand Down
8 changes: 0 additions & 8 deletions crates/tools/gnullvm/Cargo.toml

This file was deleted.

8 changes: 0 additions & 8 deletions crates/tools/gnullvm/readme.md

This file was deleted.

106 changes: 0 additions & 106 deletions crates/tools/gnullvm/src/main.rs

This file was deleted.

0 comments on commit 3fb985d

Please sign in to comment.