Skip to content

Commit

Permalink
Switch to config.toml instead of gcc-path
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Feb 9, 2024
1 parent 8235b26 commit 93654ba
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 69 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ tools/llvmint-2
# The `llvm` folder is generated by the `tools/generate_intrinsics.py` script to update intrinsics.
llvm
build_system/target
config.toml
22 changes: 16 additions & 6 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,27 @@ $ make check-jit
$ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=jit.dg/test-asm.cc"
```

**Put the path to your custom build of libgccjit in the file `gcc_path`.**
**Put the path to your custom build of libgccjit in the file `config.toml`.**

If you followed the instructions exactly as written (ie, you have created a `gcc-build` folder
where gcc is built), the only thing you need to do is:

```bash
$ cp config.example.toml config.toml
```

But if you did something different, you also need to set the `gcc-path` value in `config.toml` with
the result of this command:

```bash
$ dirname $(readlink -f `find . -name libgccjit.so`) > gcc_path
$ dirname $(readlink -f `find . -name libgccjit.so`)
```

Then you can run commands like this:

```bash
$ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking
$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) ./y.sh build --release --features master
$ ./y.sh build --release --features master
```

To run the tests:
Expand Down Expand Up @@ -100,7 +110,7 @@ error: failed to copy bitcode to object file: No such file or directory (os erro
> You should prefer using the Cargo method.
```bash
$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs
$ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs
```

## Env vars
Expand Down Expand Up @@ -322,7 +332,7 @@ generate it in [gimple.md](./doc/gimple.md).
#### Configuring rustc_codegen_gcc

* Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case.
* Set the path to the cross-compiling libgccjit in `gcc_path`.
* Set the path to the cross-compiling libgccjit in `gcc-path` (in `config.toml`).
* 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`.
* Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target m68k-unknown-linux-gnu`.

Expand All @@ -338,4 +348,4 @@ If you get the following error:
/usr/bin/ld: unrecognised emulation mode: m68kelf
```

Make sure you set `gcc_path` to the install directory.
Make sure you set `gcc-path` (in `config.toml`) to the install directory.
9 changes: 9 additions & 0 deletions build_system/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions build_system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name = "y"
version = "0.1.0"
edition = "2021"

[dependencies]
boml = "0.3.1"

[[bin]]
name = "y"
path = "src/main.rs"
24 changes: 13 additions & 11 deletions build_system/src/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::{Channel, ConfigInfo};
use crate::utils::{get_gcc_path, run_command, run_command_with_output_and_env, walk_dir};
use crate::utils::{run_command, run_command_with_output_and_env, walk_dir};
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
Expand All @@ -8,17 +8,12 @@ use std::path::Path;
#[derive(Default)]
struct BuildArg {
flags: Vec<String>,
gcc_path: String,
config_info: ConfigInfo,
}

impl BuildArg {
fn new() -> Result<Option<Self>, String> {
let gcc_path = get_gcc_path()?;
let mut build_arg = Self {
gcc_path,
..Default::default()
};
let mut build_arg = Self::default();
// We skip binary name and the `build` command.
let mut args = std::env::args().skip(2);

Expand Down Expand Up @@ -169,7 +164,8 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
fs::create_dir_all(&sysroot_src_path).map_err(|error| {
format!(
"Failed to create directory `{}`: {:?}",
sysroot_src_path.display(), error
sysroot_src_path.display(),
error
)
})?;
run_command(
Expand All @@ -188,8 +184,14 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
fn build_codegen(args: &mut BuildArg) -> Result<(), String> {
let mut env = HashMap::new();

env.insert("LD_LIBRARY_PATH".to_string(), args.gcc_path.clone());
env.insert("LIBRARY_PATH".to_string(), args.gcc_path.clone());
env.insert(
"LD_LIBRARY_PATH".to_string(),
args.config_info.gcc_path.clone(),
);
env.insert(
"LIBRARY_PATH".to_string(),
args.config_info.gcc_path.clone(),
);

let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"rustc"];
if args.config_info.channel == Channel::Release {
Expand All @@ -205,7 +207,7 @@ fn build_codegen(args: &mut BuildArg) -> Result<(), String> {
}
run_command_with_output_and_env(&command, None, Some(&env))?;

args.config_info.setup(&mut env, Some(&args.gcc_path))?;
args.config_info.setup(&mut env, None)?;

// We voluntarily ignore the error.
let _ = fs::remove_dir_all("target/out");
Expand Down
100 changes: 94 additions & 6 deletions build_system/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::utils::{get_gcc_path, get_os_name, rustc_version_info, split_args};
use crate::utils::{get_os_name, rustc_version_info, split_args};
use std::collections::HashMap;
use std::env as std_env;
use std::ffi::OsStr;
use std::fs;
use std::path::Path;

use boml::{types::TomlValue, Toml};

#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
pub enum Channel {
Expand All @@ -19,6 +23,70 @@ impl Channel {
}
}

fn failed_config_parsing(err: &str) -> Result<(), String> {
Err(format!(
"Failed to parse `{}`: {}",
ConfigFile::CONFIG_FILE,
err
))
}

#[derive(Default)]
pub struct ConfigFile {
gcc_path: Option<String>,
download_gccjit: Option<bool>,
}

impl ConfigFile {
pub const CONFIG_FILE: &'static str = "config.toml";

pub fn new() -> Result<Self, String> {
let content = fs::read_to_string(Self::CONFIG_FILE).map_err(|_| {
format!(
"Failed to read `{}`. Take a look at `Readme.md` to see how to set up the project",
Self::CONFIG_FILE,
)
})?;
let toml = Toml::parse(&content).map_err(|err| {
format!(
"Error occurred around `{}`: {:?}",
&content[err.start..=err.end],
err.kind
)
})?;
let mut config = Self::default();
for (key, value) in toml.iter() {
match (key, value) {
("gcc-path", TomlValue::String(value)) => {
config.gcc_path = Some(value.as_str().to_string())
}
("gcc-path", _) => failed_config_parsing("Expected a string for `gcc-path`")?,
("download-gccjit", TomlValue::Boolean(value)) => {
config.download_gccjit = Some(*value)
}
("download-gccjit", _) => {
failed_config_parsing("Expected a boolean for `download-gccjit`")?
}
_ => failed_config_parsing(&format!("Unknown key `{}`", key))?,
}
}
if config.gcc_path.is_none() && config.download_gccjit.is_none() {
failed_config_parsing(
"At least one of `gcc-path` or `download-gccjit` value must be set",
)?;
}
if let Some(gcc_path) = config.gcc_path.as_mut() {
let path = Path::new(gcc_path);
*gcc_path = path
.canonicalize()
.map_err(|err| format!("Failed to get absolute path of `{}`: {:?}", gcc_path, err))?
.display()
.to_string();
}
Ok(config)
}
}

#[derive(Default, Debug)]
pub struct ConfigInfo {
pub target: String,
Expand All @@ -33,6 +101,7 @@ pub struct ConfigInfo {
pub sysroot_panic_abort: bool,
pub cg_backend_path: String,
pub sysroot_path: String,
pub gcc_path: String,
}

impl ConfigInfo {
Expand Down Expand Up @@ -83,15 +152,33 @@ impl ConfigInfo {
pub fn setup(
&mut self,
env: &mut HashMap<String, String>,
gcc_path: Option<&str>,
override_gcc_path: Option<&str>,
) -> Result<(), String> {
env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string());

let gcc_path = match gcc_path {
Some(path) => path.to_string(),
None => get_gcc_path()?,
let ConfigFile { gcc_path, .. } = ConfigFile::new()?;

self.gcc_path = match override_gcc_path {
Some(path) => {
if gcc_path.is_some() {
println!("overriding setting from `{}`", ConfigFile::CONFIG_FILE);
}
path.to_string()
}
None => {
match gcc_path {
Some(path) => path,
// FIXME: Once we support "download", rewrite this.
None => {
return Err(format!(
"missing `gcc-path` value from `{}`",
ConfigFile::CONFIG_FILE
))
}
}
}
};
env.insert("GCC_PATH".to_string(), gcc_path.clone());
env.insert("GCC_PATH".to_string(), self.gcc_path.clone());

if self.cargo_target_dir.is_empty() {
match env.get("CARGO_TARGET_DIR").filter(|dir| !dir.is_empty()) {
Expand Down Expand Up @@ -225,6 +312,7 @@ impl ConfigInfo {
// line option to change it.
target = current_dir.join("target/out").display(),
sysroot = sysroot.display(),
gcc_path = self.gcc_path,
);
env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path);
Expand Down
29 changes: 15 additions & 14 deletions build_system/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::build;
use crate::config::{Channel, ConfigInfo};
use crate::utils::{
get_gcc_path, get_toolchain, remove_file, run_command, run_command_with_env,
run_command_with_output_and_env, rustc_version_info, split_args, walk_dir,
get_toolchain, remove_file, run_command, run_command_with_env, run_command_with_output_and_env,
rustc_version_info, split_args, walk_dir,
};

use std::collections::{BTreeSet, HashMap};
Expand Down Expand Up @@ -108,7 +108,7 @@ fn show_usage() {
struct TestArg {
no_default_features: bool,
build_only: bool,
gcc_path: String,
gcc_path: Option<String>,
runners: BTreeSet<String>,
flags: Vec<String>,
backend: Option<String>,
Expand Down Expand Up @@ -180,12 +180,10 @@ impl TestArg {
}
}

test_arg.gcc_path = if use_system_gcc {
if use_system_gcc {
println!("Using system GCC");
"gcc".to_string()
} else {
get_gcc_path()?
};
test_arg.gcc_path = Some("gcc".to_string());
}
}
match (test_arg.current_part, test_arg.nb_parts) {
(Some(_), Some(_)) | (None, None) => {}
Expand Down Expand Up @@ -487,7 +485,8 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
}

fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<(), String> {
let toolchain = format!("+{channel}-{host}",
let toolchain = format!(
"+{channel}-{host}",
channel = get_toolchain()?, // May also include date
host = args.config_info.host_triple
);
Expand Down Expand Up @@ -526,7 +525,12 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<(), String> {
}
})?;
let rustc = String::from_utf8(
run_command_with_env(&[&"rustup", &toolchain, &"which", &"rustc"], rust_dir, Some(env))?.stdout,
run_command_with_env(
&[&"rustup", &toolchain, &"which", &"rustc"],
rust_dir,
Some(env),
)?
.stdout,
)
.map_err(|error| format!("Failed to retrieve rustc path: {:?}", error))
.and_then(|rustc| {
Expand Down Expand Up @@ -1110,17 +1114,14 @@ pub fn run() -> Result<(), String> {
};
let mut env: HashMap<String, String> = std::env::vars().collect();

env.insert("LD_LIBRARY_PATH".to_string(), args.gcc_path.clone());
env.insert("LIBRARY_PATH".to_string(), args.gcc_path.clone());
args.config_info.setup(&mut env, args.gcc_path.as_deref())?;

build_if_no_backend(&env, &args)?;
if args.build_only {
println!("Since it's build only, exiting...");
return Ok(());
}

args.config_info.setup(&mut env, Some(&args.gcc_path))?;

if args.runners.is_empty() {
run_all(&env, &args)?;
} else {
Expand Down
Loading

0 comments on commit 93654ba

Please sign in to comment.