Switch to config.toml
instead of gcc-path
This commit is contained in:
parent
357cae82ad
commit
2640b316e2
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
Readme.md
22
Readme.md
@ -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
|
||||
$ dirname $(readlink -f `find . -name libgccjit.so`) > gcc_path
|
||||
$ 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`)
|
||||
```
|
||||
|
||||
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:
|
||||
@ -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
|
||||
@ -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`.
|
||||
|
||||
@ -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
build_system/Cargo.lock
generated
9
build_system/Cargo.lock
generated
@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "boml"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85fdb93f04c73bff54305fa437ffea5449c41edcaadfe882f35836206b166ac5"
|
||||
|
||||
[[package]]
|
||||
name = "y"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"boml",
|
||||
]
|
||||
|
@ -3,6 +3,9 @@ name = "y"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
boml = "0.3.1"
|
||||
|
||||
[[bin]]
|
||||
name = "y"
|
||||
path = "src/main.rs"
|
||||
|
@ -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;
|
||||
@ -8,17 +8,12 @@
|
||||
#[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);
|
||||
|
||||
@ -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(
|
||||
@ -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 {
|
||||
@ -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");
|
||||
@ -227,6 +229,7 @@ pub fn run() -> Result<(), String> {
|
||||
Some(args) => args,
|
||||
None => return Ok(()),
|
||||
};
|
||||
args.config_info.setup_gcc_path(None)?;
|
||||
build_codegen(&mut args)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -19,6 +23,72 @@ pub fn as_str(self) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn failed_config_parsing(err: &str) -> Result<ConfigFile, 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", _) => {
|
||||
return failed_config_parsing("Expected a string for `gcc-path`")
|
||||
}
|
||||
("download-gccjit", TomlValue::Boolean(value)) => {
|
||||
config.download_gccjit = Some(*value)
|
||||
}
|
||||
("download-gccjit", _) => {
|
||||
return failed_config_parsing("Expected a boolean for `download-gccjit`")
|
||||
}
|
||||
_ => return failed_config_parsing(&format!("Unknown key `{}`", key)),
|
||||
}
|
||||
}
|
||||
if config.gcc_path.is_none() && config.download_gccjit.is_none() {
|
||||
return 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,
|
||||
@ -33,6 +103,7 @@ pub struct ConfigInfo {
|
||||
pub sysroot_panic_abort: bool,
|
||||
pub cg_backend_path: String,
|
||||
pub sysroot_path: String,
|
||||
pub gcc_path: String,
|
||||
}
|
||||
|
||||
impl ConfigInfo {
|
||||
@ -80,18 +151,43 @@ pub fn rustc_command_vec(&self) -> Vec<&dyn AsRef<OsStr>> {
|
||||
command
|
||||
}
|
||||
|
||||
pub fn setup_gcc_path(&mut self, override_gcc_path: Option<&str>) -> Result<(), String> {
|
||||
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
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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()?,
|
||||
};
|
||||
env.insert("GCC_PATH".to_string(), gcc_path.clone());
|
||||
if self.gcc_path.is_empty() || override_gcc_path.is_some() {
|
||||
self.setup_gcc_path(override_gcc_path)?;
|
||||
}
|
||||
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()) {
|
||||
@ -225,7 +321,9 @@ pub fn setup(
|
||||
// line option to change it.
|
||||
target = current_dir.join("target/out").display(),
|
||||
sysroot = sysroot.display(),
|
||||
gcc_path = self.gcc_path,
|
||||
);
|
||||
env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone());
|
||||
env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone());
|
||||
env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::build;
|
||||
use crate::config::{Channel, ConfigInfo};
|
||||
use crate::utils::{
|
||||
get_gcc_path, get_toolchain, git_clone, remove_file, run_command, run_command_with_env,
|
||||
get_toolchain, git_clone, remove_file, run_command, run_command_with_env,
|
||||
run_command_with_output_and_env, rustc_version_info, split_args, walk_dir,
|
||||
};
|
||||
|
||||
@ -109,7 +109,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>,
|
||||
@ -181,12 +181,10 @@ fn new() -> Result<Option<Self>, String> {
|
||||
}
|
||||
}
|
||||
|
||||
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) => {}
|
||||
@ -488,7 +486,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
|
||||
);
|
||||
@ -527,7 +526,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| {
|
||||
@ -1162,8 +1166,15 @@ 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_gcc_path(None)?;
|
||||
env.insert(
|
||||
"LIBRARY_PATH".to_string(),
|
||||
args.config_info.gcc_path.clone(),
|
||||
);
|
||||
env.insert(
|
||||
"LD_LIBRARY_PATH".to_string(),
|
||||
args.config_info.gcc_path.clone(),
|
||||
);
|
||||
|
||||
build_if_no_backend(&env, &args)?;
|
||||
if args.build_only {
|
||||
@ -1171,7 +1182,7 @@ pub fn run() -> Result<(), String> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
args.config_info.setup(&mut env, Some(&args.gcc_path))?;
|
||||
args.config_info.setup(&mut env, args.gcc_path.as_deref())?;
|
||||
|
||||
if args.runners.is_empty() {
|
||||
run_all(&env, &args)?;
|
||||
|
@ -248,38 +248,6 @@ pub fn get_toolchain() -> Result<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_gcc_path() -> Result<String, String> {
|
||||
let content = match fs::read_to_string("gcc_path") {
|
||||
Ok(content) => content,
|
||||
Err(_) => {
|
||||
return Err(
|
||||
"Please put the path to your custom build of libgccjit in the file \
|
||||
`gcc_path`, see Readme.md for details"
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
match content
|
||||
.split('\n')
|
||||
.map(|line| line.trim())
|
||||
.filter(|line| !line.is_empty())
|
||||
.next()
|
||||
{
|
||||
Some(gcc_path) => {
|
||||
let path = Path::new(gcc_path);
|
||||
if !path.exists() {
|
||||
Err(format!(
|
||||
"Path `{}` contained in the `gcc_path` file doesn't exist",
|
||||
gcc_path,
|
||||
))
|
||||
} else {
|
||||
Ok(gcc_path.into())
|
||||
}
|
||||
}
|
||||
None => Err("No path found in `gcc_path` file".into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CloneResult {
|
||||
pub ran_clone: bool,
|
||||
pub repo_name: String,
|
||||
|
2
config.example.toml
Normal file
2
config.example.toml
Normal file
@ -0,0 +1,2 @@
|
||||
gcc-path = "gcc-build/gcc"
|
||||
# download-gccjit = true
|
Loading…
Reference in New Issue
Block a user