about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Readme.md8
-rw-r--r--build_system/src/cargo.rs97
-rw-r--r--build_system/src/main.rs8
-rw-r--r--build_system/src/rust_tools.rs125
4 files changed, 138 insertions, 100 deletions
diff --git a/Readme.md b/Readme.md
index da6e91587fd..92916079959 100644
--- a/Readme.md
+++ b/Readme.md
@@ -118,7 +118,13 @@ error: failed to copy bitcode to object file: No such file or directory (os erro
 
 ### Rustc
 
-> You should prefer using the Cargo method.
+If you want to run `rustc` directly, you can do so with:
+
+```bash
+$ ./y.sh rustc my_crate.rs
+```
+
+You can do the same manually (although we don't recommend it):
 
 ```bash
 $ 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
diff --git a/build_system/src/cargo.rs b/build_system/src/cargo.rs
deleted file mode 100644
index e4ea79b06f2..00000000000
--- a/build_system/src/cargo.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use crate::config::ConfigInfo;
-use crate::utils::{
-    get_toolchain, run_command_with_output_and_env_no_err, rustc_toolchain_version_info,
-    rustc_version_info,
-};
-
-use std::collections::HashMap;
-use std::ffi::OsStr;
-use std::path::PathBuf;
-
-fn args() -> Result<Option<Vec<String>>, String> {
-    // We skip the binary and the "cargo" option.
-    if let Some("--help") = std::env::args().skip(2).next().as_deref() {
-        usage();
-        return Ok(None);
-    }
-    let args = std::env::args().skip(2).collect::<Vec<_>>();
-    if args.is_empty() {
-        return Err("Expected at least one argument for `cargo` subcommand, found none".to_string());
-    }
-    Ok(Some(args))
-}
-
-fn usage() {
-    println!(
-        r#"
-`cargo` command help:
-
-    [args]     : Arguments to be passed to the cargo command
-    --help     : Show this help
-"#
-    )
-}
-
-pub fn run() -> Result<(), String> {
-    let args = match args()? {
-        Some(a) => a,
-        None => return Ok(()),
-    };
-
-    // We first need to go to the original location to ensure that the config setup will go as
-    // expected.
-    let current_dir = std::env::current_dir()
-        .and_then(|path| path.canonicalize())
-        .map_err(|error| format!("Failed to get current directory path: {:?}", error))?;
-    let current_exe = std::env::current_exe()
-        .and_then(|path| path.canonicalize())
-        .map_err(|error| format!("Failed to get current exe path: {:?}", error))?;
-    let mut parent_dir = current_exe.components().map(|comp| comp.as_os_str()).collect::<Vec<_>>();
-    // We run this script from "build_system/target/release/y", so we need to remove these elements.
-    for to_remove in &["y", "release", "target", "build_system"] {
-        if parent_dir.last().map(|part| part == to_remove).unwrap_or(false) {
-            parent_dir.pop();
-        } else {
-            return Err(format!(
-                "Build script not executed from `build_system/target/release/y` (in path {})",
-                current_exe.display(),
-            ));
-        }
-    }
-    let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/")));
-    std::env::set_current_dir(&parent_dir).map_err(|error| {
-        format!("Failed to go to `{}` folder: {:?}", parent_dir.display(), error)
-    })?;
-
-    let mut env: HashMap<String, String> = std::env::vars().collect();
-    ConfigInfo::default().setup(&mut env, false)?;
-    let toolchain = get_toolchain()?;
-
-    let toolchain_version = rustc_toolchain_version_info(&toolchain)?;
-    let default_version = rustc_version_info(None)?;
-    if toolchain_version != default_version {
-        println!(
-            "rustc_codegen_gcc is built for {} but the default rustc version is {}.",
-            toolchain_version.short, default_version.short,
-        );
-        println!("Using {}.", toolchain_version.short);
-    }
-
-    // We go back to the original folder since we now have set up everything we needed.
-    std::env::set_current_dir(&current_dir).map_err(|error| {
-        format!("Failed to go back to `{}` folder: {:?}", current_dir.display(), error)
-    })?;
-
-    let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default();
-    env.insert("RUSTDOCFLAGS".to_string(), rustflags);
-    let toolchain = format!("+{}", toolchain);
-    let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &toolchain];
-    for arg in &args {
-        command.push(arg);
-    }
-    if run_command_with_output_and_env_no_err(&command, None, Some(&env)).is_err() {
-        std::process::exit(1);
-    }
-
-    Ok(())
-}
diff --git a/build_system/src/main.rs b/build_system/src/main.rs
index 48ffbc7a907..1bfba0f9828 100644
--- a/build_system/src/main.rs
+++ b/build_system/src/main.rs
@@ -2,12 +2,12 @@ use std::env;
 use std::process;
 
 mod build;
-mod cargo;
 mod clean;
 mod clone_gcc;
 mod config;
 mod info;
 mod prepare;
+mod rust_tools;
 mod rustc_info;
 mod test;
 mod utils;
@@ -29,6 +29,7 @@ fn usage() {
 Available commands for build_system:
 
     cargo     : Run cargo command
+    rustc     : Run rustc command
     clean     : Run clean command
     prepare   : Run prepare command
     build     : Run build command
@@ -45,6 +46,7 @@ pub enum Command {
     CloneGcc,
     Prepare,
     Build,
+    Rustc,
     Test,
     Info,
 }
@@ -56,6 +58,7 @@ fn main() {
 
     let command = match env::args().nth(1).as_deref() {
         Some("cargo") => Command::Cargo,
+        Some("rustc") => Command::Rustc,
         Some("clean") => Command::Clean,
         Some("prepare") => Command::Prepare,
         Some("build") => Command::Build,
@@ -75,7 +78,8 @@ fn main() {
     };
 
     if let Err(e) = match command {
-        Command::Cargo => cargo::run(),
+        Command::Cargo => rust_tools::run_cargo(),
+        Command::Rustc => rust_tools::run_rustc(),
         Command::Clean => clean::run(),
         Command::Prepare => prepare::run(),
         Command::Build => build::run(),
diff --git a/build_system/src/rust_tools.rs b/build_system/src/rust_tools.rs
new file mode 100644
index 00000000000..242fa7ef949
--- /dev/null
+++ b/build_system/src/rust_tools.rs
@@ -0,0 +1,125 @@
+use crate::config::ConfigInfo;
+use crate::utils::{
+    get_toolchain, run_command_with_output_and_env_no_err, rustc_toolchain_version_info,
+    rustc_version_info,
+};
+
+use std::collections::HashMap;
+use std::ffi::OsStr;
+use std::path::PathBuf;
+
+fn args(command: &str) -> Result<Option<Vec<String>>, String> {
+    // We skip the binary and the "cargo"/"rustc" option.
+    if let Some("--help") = std::env::args().skip(2).next().as_deref() {
+        usage(command);
+        return Ok(None);
+    }
+    let args = std::env::args().skip(2).collect::<Vec<_>>();
+    if args.is_empty() {
+        return Err(format!(
+            "Expected at least one argument for `{}` subcommand, found none",
+            command
+        ));
+    }
+    Ok(Some(args))
+}
+
+fn usage(command: &str) {
+    println!(
+        r#"
+`{}` command help:
+
+    [args]     : Arguments to be passed to the cargo command
+    --help     : Show this help
+"#,
+        command,
+    )
+}
+
+struct RustcTools {
+    env: HashMap<String, String>,
+    args: Vec<String>,
+    toolchain: String,
+    config: ConfigInfo,
+}
+
+impl RustcTools {
+    fn new(command: &str) -> Result<Option<Self>, String> {
+        let Some(args) = args(command)? else { return Ok(None) };
+
+        // We first need to go to the original location to ensure that the config setup will go as
+        // expected.
+        let current_dir = std::env::current_dir()
+            .and_then(|path| path.canonicalize())
+            .map_err(|error| format!("Failed to get current directory path: {:?}", error))?;
+        let current_exe = std::env::current_exe()
+            .and_then(|path| path.canonicalize())
+            .map_err(|error| format!("Failed to get current exe path: {:?}", error))?;
+        let mut parent_dir =
+            current_exe.components().map(|comp| comp.as_os_str()).collect::<Vec<_>>();
+        // We run this script from "build_system/target/release/y", so we need to remove these elements.
+        for to_remove in &["y", "release", "target", "build_system"] {
+            if parent_dir.last().map(|part| part == to_remove).unwrap_or(false) {
+                parent_dir.pop();
+            } else {
+                return Err(format!(
+                    "Build script not executed from `build_system/target/release/y` (in path {})",
+                    current_exe.display(),
+                ));
+            }
+        }
+        let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/")));
+        std::env::set_current_dir(&parent_dir).map_err(|error| {
+            format!("Failed to go to `{}` folder: {:?}", parent_dir.display(), error)
+        })?;
+
+        let mut env: HashMap<String, String> = std::env::vars().collect();
+        let mut config = ConfigInfo::default();
+        config.setup(&mut env, false)?;
+        let toolchain = get_toolchain()?;
+
+        let toolchain_version = rustc_toolchain_version_info(&toolchain)?;
+        let default_version = rustc_version_info(None)?;
+        if toolchain_version != default_version {
+            println!(
+                "rustc_codegen_gcc is built for {} but the default rustc version is {}.",
+                toolchain_version.short, default_version.short,
+            );
+            println!("Using {}.", toolchain_version.short);
+        }
+
+        // We go back to the original folder since we now have set up everything we needed.
+        std::env::set_current_dir(&current_dir).map_err(|error| {
+            format!("Failed to go back to `{}` folder: {:?}", current_dir.display(), error)
+        })?;
+        let toolchain = format!("+{}", toolchain);
+        Ok(Some(Self { toolchain, args, env, config }))
+    }
+}
+
+pub fn run_cargo() -> Result<(), String> {
+    let Some(mut tools) = RustcTools::new("cargo")? else { return Ok(()) };
+    let rustflags = tools.env.get("RUSTFLAGS").cloned().unwrap_or_default();
+    tools.env.insert("RUSTDOCFLAGS".to_string(), rustflags);
+    let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &tools.toolchain];
+    for arg in &tools.args {
+        command.push(arg);
+    }
+    if run_command_with_output_and_env_no_err(&command, None, Some(&tools.env)).is_err() {
+        std::process::exit(1);
+    }
+
+    Ok(())
+}
+
+pub fn run_rustc() -> Result<(), String> {
+    let Some(tools) = RustcTools::new("rustc")? else { return Ok(()) };
+    let mut command = tools.config.rustc_command_vec();
+    for arg in &tools.args {
+        command.push(arg);
+    }
+    if run_command_with_output_and_env_no_err(&command, None, Some(&tools.env)).is_err() {
+        std::process::exit(1);
+    }
+    Ok(())
+}