Skip to content

Commit a91d9e1

Browse files
authored
Merge pull request rust-lang#405 from GuillaumeGomez/rustify-cargo-sh
Rustify `cargo.sh`
2 parents b2e0cc5 + c122376 commit a91d9e1

File tree

8 files changed

+175
-41
lines changed

8 files changed

+175
-41
lines changed

.github/workflows/stdarch.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,11 @@ jobs:
126126
if: ${{ !matrix.cargo_runner }}
127127
run: |
128128
cd build_sysroot/sysroot_src/library/stdarch/
129-
CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test
129+
CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test
130130
131131
- name: Run stdarch tests
132132
if: ${{ matrix.cargo_runner }}
133133
run: |
134134
cd build_sysroot/sysroot_src/library/stdarch/
135135
# FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro.
136-
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test -- --skip rtm --skip tbm --skip sse4a
136+
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test -- --skip rtm --skip tbm --skip sse4a

Readme.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export CG_GCCJIT_DIR=[the full path to rustc_codegen_gcc]
7979
### Cargo
8080

8181
```bash
82-
$ CHANNEL="release" $CG_GCCJIT_DIR/cargo.sh run
82+
$ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run
8383
```
8484

8585
If you compiled cg_gccjit in debug mode (aka you didn't pass `--release` to `./y.sh test`) you should use `CHANNEL="debug"` instead or omit `CHANNEL="release"` completely.
@@ -230,13 +230,13 @@ Run do the command with `-v -save-temps` and then extract the `lto1` line from t
230230
### How to send arguments to the GCC linker
231231
232232
```
233-
CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../cargo.sh build
233+
CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../y.sh cargo build
234234
```
235235
236236
### How to see the personality functions in the asm dump
237237
238238
```
239-
CG_RUSTFLAGS="-Clink-arg=-save-temps -v -Clink-arg=-dA" ../cargo.sh build
239+
CG_RUSTFLAGS="-Clink-arg=-save-temps -v -Clink-arg=-dA" ../y.sh cargo build
240240
```
241241
242242
### How to see the LLVM IR for a sysroot crate
@@ -324,13 +324,13 @@ generate it in [gimple.md](./doc/gimple.md).
324324
* Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case.
325325
* Set the path to the cross-compiling libgccjit in `gcc_path`.
326326
* Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. Currently, the linker name is hardcoded as being `$TARGET-gcc`. Specify the target when building the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu`.
327-
* Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../cargo.sh build --target m68k-unknown-linux-gnu`.
327+
* Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target m68k-unknown-linux-gnu`.
328328

329329
If the target is not yet supported by the Rust compiler, create a [target specification file](https://docs.rust-embedded.org/embedonomicon/custom-target.html) (note that the `arch` specified in this file must be supported by the rust compiler).
330330
Then, you can use it the following way:
331331

332332
* Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json`
333-
* Build your project by specifying the target specification file: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../cargo.sh build --target path/to/m68k-unknown-linux-gnu.json`.
333+
* Build your project by specifying the target specification file: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target path/to/m68k-unknown-linux-gnu.json`.
334334

335335
If you get the following error:
336336

build_system/src/cargo.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use crate::config::ConfigInfo;
2+
use crate::utils::{
3+
get_toolchain, run_command_with_output_and_env_no_err, rustc_toolchain_version_info,
4+
rustc_version_info,
5+
};
6+
7+
use std::collections::HashMap;
8+
use std::ffi::OsStr;
9+
use std::path::PathBuf;
10+
11+
fn args() -> Result<Option<Vec<String>>, String> {
12+
// We skip the binary and the "cargo" option.
13+
if let Some("--help") = std::env::args().skip(2).next().as_deref() {
14+
usage();
15+
return Ok(None);
16+
}
17+
let args = std::env::args().skip(2).collect::<Vec<_>>();
18+
if args.is_empty() {
19+
return Err(
20+
"Expected at least one argument for `cargo` subcommand, found none".to_string(),
21+
);
22+
}
23+
Ok(Some(args))
24+
}
25+
26+
fn usage() {
27+
println!(
28+
r#"
29+
`cargo` command help:
30+
31+
[args] : Arguments to be passed to the cargo command
32+
--help : Show this help
33+
"#
34+
)
35+
}
36+
37+
pub fn run() -> Result<(), String> {
38+
let args = match args()? {
39+
Some(a) => a,
40+
None => return Ok(()),
41+
};
42+
43+
// We first need to go to the original location to ensure that the config setup will go as
44+
// expected.
45+
let current_dir = std::env::current_dir()
46+
.and_then(|path| path.canonicalize())
47+
.map_err(|error| format!("Failed to get current directory path: {:?}", error))?;
48+
let current_exe = std::env::current_exe()
49+
.and_then(|path| path.canonicalize())
50+
.map_err(|error| format!("Failed to get current exe path: {:?}", error))?;
51+
let mut parent_dir = current_exe
52+
.components()
53+
.map(|comp| comp.as_os_str())
54+
.collect::<Vec<_>>();
55+
// We run this script from "build_system/target/release/y", so we need to remove these elements.
56+
for to_remove in &["y", "release", "target", "build_system"] {
57+
if parent_dir
58+
.last()
59+
.map(|part| part == to_remove)
60+
.unwrap_or(false)
61+
{
62+
parent_dir.pop();
63+
} else {
64+
return Err(format!(
65+
"Build script not executed from `build_system/target/release/y` (in path {})",
66+
current_exe.display(),
67+
));
68+
}
69+
}
70+
let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/")));
71+
std::env::set_current_dir(&parent_dir).map_err(|error| {
72+
format!(
73+
"Failed to go to `{}` folder: {:?}",
74+
parent_dir.display(),
75+
error
76+
)
77+
})?;
78+
79+
let mut env: HashMap<String, String> = std::env::vars().collect();
80+
ConfigInfo::default().setup(&mut env, None)?;
81+
let toolchain = get_toolchain()?;
82+
83+
let toolchain_version = rustc_toolchain_version_info(&toolchain)?;
84+
let default_version = rustc_version_info(None)?;
85+
if toolchain_version != default_version {
86+
println!(
87+
"rustc_codegen_gcc is built for {} but the default rustc version is {}.",
88+
toolchain_version.short, default_version.short,
89+
);
90+
println!("Using {}.", toolchain_version.short);
91+
}
92+
93+
// We go back to the original folder since we now have set up everything we needed.
94+
std::env::set_current_dir(&current_dir).map_err(|error| {
95+
format!(
96+
"Failed to go back to `{}` folder: {:?}",
97+
current_dir.display(),
98+
error
99+
)
100+
})?;
101+
102+
let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default();
103+
env.insert("RUSTDOCFLAGS".to_string(), rustflags);
104+
let toolchain = format!("+{}", toolchain);
105+
let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &toolchain];
106+
for arg in &args {
107+
command.push(arg);
108+
}
109+
if run_command_with_output_and_env_no_err(&command, None, Some(&env)).is_err() {
110+
std::process::exit(1);
111+
}
112+
113+
Ok(())
114+
}

build_system/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::env;
22
use std::process;
33

44
mod build;
5+
mod cargo;
56
mod clean;
67
mod config;
78
mod prepare;
@@ -23,6 +24,7 @@ fn usage() {
2324
"\
2425
Available commands for build_system:
2526
27+
cargo : Run cargo command
2628
clean : Run clean command
2729
prepare : Run prepare command
2830
build : Run build command
@@ -32,6 +34,7 @@ Available commands for build_system:
3234
}
3335

3436
pub enum Command {
37+
Cargo,
3538
Clean,
3639
Prepare,
3740
Build,
@@ -44,6 +47,7 @@ fn main() {
4447
}
4548

4649
let command = match env::args().nth(1).as_deref() {
50+
Some("cargo") => Command::Cargo,
4751
Some("clean") => Command::Clean,
4852
Some("prepare") => Command::Prepare,
4953
Some("build") => Command::Build,
@@ -61,6 +65,7 @@ fn main() {
6165
};
6266

6367
if let Err(e) = match command {
68+
Command::Cargo => cargo::run(),
6469
Command::Clean => clean::run(),
6570
Command::Prepare => prepare::run(),
6671
Command::Build => build::run(),

build_system/src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> {
796796
// echo "[BENCH COMPILE] ebobby/simple-raytracer"
797797
// hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \
798798
// "RUSTC=rustc RUSTFLAGS='' cargo build" \
799-
// "../cargo.sh build"
799+
// "../y.sh cargo build"
800800

801801
// echo "[BENCH RUN] ebobby/simple-raytracer"
802802
// cp ./target/debug/main ./raytracer_cg_gcc

build_system/src/utils.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn check_exit_status(
3030
cwd: Option<&Path>,
3131
exit_status: ExitStatus,
3232
output: Option<&Output>,
33+
show_err: bool,
3334
) -> Result<(), String> {
3435
if exit_status.success() {
3536
return Ok(());
@@ -46,7 +47,9 @@ fn check_exit_status(
4647
exit_status.code()
4748
);
4849
let input = input.iter().map(|i| i.as_ref()).collect::<Vec<&OsStr>>();
49-
eprintln!("Command `{:?}` failed", input);
50+
if show_err {
51+
eprintln!("Command `{:?}` failed", input);
52+
}
5053
if let Some(output) = output {
5154
let stdout = String::from_utf8_lossy(&output.stdout);
5255
if !stdout.is_empty() {
@@ -88,7 +91,7 @@ pub fn run_command_with_env(
8891
let output = get_command_inner(input, cwd, env)
8992
.output()
9093
.map_err(|e| command_error(input, &cwd, e))?;
91-
check_exit_status(input, cwd, output.status, Some(&output))?;
94+
check_exit_status(input, cwd, output.status, Some(&output), true)?;
9295
Ok(output)
9396
}
9497

@@ -101,7 +104,7 @@ pub fn run_command_with_output(
101104
.map_err(|e| command_error(input, &cwd, e))?
102105
.wait()
103106
.map_err(|e| command_error(input, &cwd, e))?;
104-
check_exit_status(input, cwd, exit_status, None)?;
107+
check_exit_status(input, cwd, exit_status, None, true)?;
105108
Ok(())
106109
}
107110

@@ -115,7 +118,21 @@ pub fn run_command_with_output_and_env(
115118
.map_err(|e| command_error(input, &cwd, e))?
116119
.wait()
117120
.map_err(|e| command_error(input, &cwd, e))?;
118-
check_exit_status(input, cwd, exit_status, None)?;
121+
check_exit_status(input, cwd, exit_status, None, true)?;
122+
Ok(())
123+
}
124+
125+
pub fn run_command_with_output_and_env_no_err(
126+
input: &[&dyn AsRef<OsStr>],
127+
cwd: Option<&Path>,
128+
env: Option<&HashMap<String, String>>,
129+
) -> Result<(), String> {
130+
let exit_status = get_command_inner(input, cwd, env)
131+
.spawn()
132+
.map_err(|e| command_error(input, &cwd, e))?
133+
.wait()
134+
.map_err(|e| command_error(input, &cwd, e))?;
135+
check_exit_status(input, cwd, exit_status, None, false)?;
119136
Ok(())
120137
}
121138

@@ -158,21 +175,42 @@ pub fn get_os_name() -> Result<String, String> {
158175
}
159176
}
160177

161-
#[derive(Default)]
178+
#[derive(Default, PartialEq)]
162179
pub struct RustcVersionInfo {
180+
pub short: String,
163181
pub version: String,
164182
pub host: Option<String>,
165183
pub commit_hash: Option<String>,
166184
pub commit_date: Option<String>,
167185
}
168186

187+
pub fn rustc_toolchain_version_info(toolchain: &str) -> Result<RustcVersionInfo, String> {
188+
rustc_version_info_inner(None, Some(toolchain))
189+
}
190+
169191
pub fn rustc_version_info(rustc: Option<&str>) -> Result<RustcVersionInfo, String> {
170-
let output = run_command(&[&rustc.unwrap_or("rustc"), &"-vV"], None)?;
192+
rustc_version_info_inner(rustc, None)
193+
}
194+
195+
fn rustc_version_info_inner(
196+
rustc: Option<&str>,
197+
toolchain: Option<&str>,
198+
) -> Result<RustcVersionInfo, String> {
199+
let output = if let Some(toolchain) = toolchain {
200+
run_command(&[&rustc.unwrap_or("rustc"), &toolchain, &"-vV"], None)
201+
} else {
202+
run_command(&[&rustc.unwrap_or("rustc"), &"-vV"], None)
203+
}?;
171204
let content = std::str::from_utf8(&output.stdout).unwrap_or("");
172205

173206
let mut info = RustcVersionInfo::default();
207+
let mut lines = content.split('\n');
208+
info.short = match lines.next() {
209+
Some(s) => s.to_string(),
210+
None => return Err("failed to retrieve rustc version".to_string()),
211+
};
174212

175-
for line in content.split('\n').map(|line| line.trim()) {
213+
for line in lines.map(|line| line.trim()) {
176214
match line.split_once(':') {
177215
Some(("host", data)) => info.host = Some(data.trim().to_string()),
178216
Some(("release", data)) => info.version = data.trim().to_string(),

cargo.sh

Lines changed: 0 additions & 23 deletions
This file was deleted.

y.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -e
44
echo "[BUILD] build system" 1>&2
5-
cd build_system
5+
pushd $(dirname "$0")/build_system > /dev/null
66
cargo build --release
7-
cd ..
8-
./build_system/target/release/y $@
7+
popd > /dev/null
8+
$(dirname "$0")/build_system/target/release/y $@

0 commit comments

Comments
 (0)