rust: various build script fixes
This commit is contained in:
parent
e42315e67a
commit
8c129e33db
12 changed files with 307 additions and 165 deletions
1
lang/rust/helpers/.gitignore
vendored
Normal file
1
lang/rust/helpers/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
7
lang/rust/helpers/Cargo.lock
generated
Normal file
7
lang/rust/helpers/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "helpers"
|
||||
version = "0.1.0"
|
||||
6
lang/rust/helpers/Cargo.toml
Normal file
6
lang/rust/helpers/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "helpers"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
70
lang/rust/helpers/src/bin/buildscript-runner.rs
Normal file
70
lang/rust/helpers/src/bin/buildscript-runner.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
env::{var, var_os},
|
||||
fs::{File, create_dir},
|
||||
io::{Read, Write},
|
||||
os::unix::process::CommandExt,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
fn parse(data: &str) -> HashMap<String, String> {
|
||||
let mut out = HashMap::new();
|
||||
|
||||
let mut parse_one = |key: &str, value: String, fallback| match key {
|
||||
"metadata" => {
|
||||
let (left, right) = value
|
||||
.split_once('=')
|
||||
.expect("missing '=' for cargo::metadata");
|
||||
out.insert(left.to_string(), right.to_string());
|
||||
}
|
||||
|
||||
_ if fallback => {
|
||||
out.insert(key.to_string(), value);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
};
|
||||
|
||||
for line in data.lines() {
|
||||
if let Some(data) = line.strip_prefix("cargo::") {
|
||||
let (key, value) = data.split_once('=').expect("missing '=' on cargo:: line");
|
||||
parse_one(key, value.to_string(), false);
|
||||
} else if let Some(data) = line.strip_prefix("cargo:") {
|
||||
let (key, value) = data.split_once('=').expect("missing '=' on cargo: line");
|
||||
parse_one(key, value.to_string(), true);
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn main() {
|
||||
create_dir(var_os("OUT_DIR").unwrap()).unwrap();
|
||||
|
||||
let mut f = File::create(var_os("out").unwrap()).unwrap();
|
||||
writeln!(&mut f, "zilch: OUT_DIR={:?}", var("OUT_DIR").unwrap()).unwrap();
|
||||
|
||||
let mut cmd = Command::new(var_os("script").unwrap());
|
||||
|
||||
cmd.stdout(f).current_dir(var_os("cwd").unwrap());
|
||||
|
||||
if let Ok(inherit) = var("_zilch_links") {
|
||||
if !inherit.is_empty() {
|
||||
for v in inherit.split('!') {
|
||||
let (path, name) = v.split_once(':').unwrap();
|
||||
let mut file = File::open(path).unwrap();
|
||||
let mut data = String::new();
|
||||
file.read_to_string(&mut data).unwrap();
|
||||
|
||||
let data = parse(&data);
|
||||
for (k, v) in data {
|
||||
let mut name = format!("DEP_{}_{}", name, k);
|
||||
name.make_ascii_uppercase();
|
||||
cmd.env(name.replace('-', "_"), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!("failed to exec: {:?}", cmd.exec())
|
||||
}
|
||||
11
lang/rust/helpers/src/bin/cfg-reader.rs
Normal file
11
lang/rust/helpers/src/bin/cfg-reader.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
use std::{env::var_os, fs::File, os::unix::process::CommandExt, process::Command};
|
||||
|
||||
fn main() {
|
||||
panic!(
|
||||
"{:?}",
|
||||
Command::new(var_os("rustc").unwrap())
|
||||
.arg("--print=cfg")
|
||||
.stdout(File::create(var_os("out").unwrap()).unwrap())
|
||||
.exec()
|
||||
);
|
||||
}
|
||||
122
lang/rust/helpers/src/bin/rustc-wrapper.rs
Normal file
122
lang/rust/helpers/src/bin/rustc-wrapper.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
env::{args, var_os},
|
||||
io::Read,
|
||||
os::unix::process::CommandExt,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct Data {
|
||||
// Only available if this is the current crate.
|
||||
pub env: Vec<String>,
|
||||
pub cfg: Vec<String>,
|
||||
pub check_cfg: Vec<String>,
|
||||
|
||||
// Only used for final linking phase. (TODO: check)
|
||||
pub flags: Vec<String>,
|
||||
|
||||
pub link_arg: Vec<String>,
|
||||
pub link_arg_bin: HashMap<Option<String>, Vec<String>>,
|
||||
pub link_lib: Vec<String>,
|
||||
pub link_search: Vec<String>,
|
||||
|
||||
// Propagates to _dependent_ packages.
|
||||
pub metadata: HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn parse(data: &str) -> Data {
|
||||
let mut out = Data::default();
|
||||
|
||||
let mut parse_one = |key, value, fallback| match key {
|
||||
"rerun-if-changed" => {}
|
||||
"rerun-if-env-changed" => {}
|
||||
|
||||
"rustc-env" => out.env.push(value),
|
||||
"rustc-cfg" => out.cfg.push(value),
|
||||
"rustc-check-cfg" => out.check_cfg.push(value),
|
||||
|
||||
"rustc-flags" => out.flags.push(value),
|
||||
"rustc-link-arg" => out.link_arg.push(value),
|
||||
"rustc-link-arg-bins" => out
|
||||
.link_arg_bin
|
||||
.entry(None)
|
||||
.or_default()
|
||||
.push(value.to_string()),
|
||||
"rustc-link-arg-bin" => {
|
||||
let (left, right) = value
|
||||
.split_once('=')
|
||||
.expect("missing '=' for cargo::rustc-link-arg-bin");
|
||||
out.link_arg_bin
|
||||
.entry(Some(left.to_string()))
|
||||
.or_default()
|
||||
.push(right.to_string());
|
||||
}
|
||||
"rustc-link-lib" => out.link_lib.push(value),
|
||||
"rustc-link-search" => out.link_search.push(value),
|
||||
"metadata" => {
|
||||
let (left, right) = value
|
||||
.split_once('=')
|
||||
.expect("missing '=' for cargo::metadata");
|
||||
out.metadata.insert(left.to_string(), right.to_string());
|
||||
}
|
||||
|
||||
_ if fallback => {
|
||||
out.metadata.insert(key.to_string(), value);
|
||||
}
|
||||
|
||||
_ => {
|
||||
panic!(
|
||||
"unknown key-value pair cargo::{:?}={:?} and no fallback to cargo::metadata allowed",
|
||||
key, value
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
for line in data.lines() {
|
||||
if let Some(data) = line.strip_prefix("cargo::") {
|
||||
let (key, value) = data.split_once('=').expect("missing '=' on cargo:: line");
|
||||
parse_one(key, value.to_string(), false);
|
||||
} else if let Some(data) = line.strip_prefix("cargo:") {
|
||||
let (key, value) = data.split_once('=').expect("missing '=' on cargo: line");
|
||||
parse_one(key, value.to_string(), true);
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut cmd = Command::new(var_os("_zilch_rustc").unwrap());
|
||||
if let Some(proc) = var_os("_zilch_proc") {
|
||||
if !proc.is_empty() {
|
||||
let mut file = std::fs::File::open(proc).unwrap();
|
||||
let mut data = String::new();
|
||||
file.read_to_string(&mut data).unwrap();
|
||||
let data = parse(&data);
|
||||
for item in data.env {
|
||||
let (l, r) = item.split_once('=').unwrap();
|
||||
cmd.env(l, r);
|
||||
}
|
||||
for item in data.check_cfg {
|
||||
cmd.arg("--check-cfg").arg(item);
|
||||
}
|
||||
for item in data.cfg {
|
||||
cmd.arg("--cfg").arg(item);
|
||||
}
|
||||
for item in data.link_search {
|
||||
cmd.arg("-L").arg(item);
|
||||
}
|
||||
for item in data.link_arg {
|
||||
cmd.arg("-C").arg(format!("link-arg={}", item));
|
||||
}
|
||||
for item in data.link_lib {
|
||||
cmd.arg("-l").arg(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd.args(args().skip(1));
|
||||
|
||||
panic!("failed to exec: {:?}", cmd.exec())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue