diff --git a/Readme.md b/Readme.md index 2207bd35edb..1bad1e71137 100644 --- a/Readme.md +++ b/Readme.md @@ -322,7 +322,12 @@ generate it in [gimple.md](./doc/gimple.md). * Set the path to the cross-compiling libgccjit in `gcc_path`. * 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 ../cargo.sh build --target m68k-unknown-linux-gnu`. - * 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). + +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). +Then, you can use it the following way: + + * 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` + * 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`. If you get the following error: diff --git a/build_system/src/build.rs b/build_system/src/build.rs index b013ca80705..c71954e4d11 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,4 +1,4 @@ -use crate::config::set_config; +use crate::config::{set_config, ConfigInfo}; use crate::utils::{ get_gcc_path, run_command, run_command_with_output_and_env, walk_dir, }; @@ -55,6 +55,15 @@ impl BuildArg { ); } } + "--target" => { + if args.next().is_some() { + // Handled in config.rs. + } else { + return Err( + "Expected a value after `--target`, found nothing".to_string() + ); + } + } arg => return Err(format!("Unknown argument `{}`", arg)), } } @@ -80,7 +89,7 @@ impl BuildArg { fn build_sysroot( env: &mut HashMap, release_mode: bool, - target_triple: &str, + config: &ConfigInfo, ) -> Result<(), String> { std::env::set_current_dir("build_sysroot") .map_err(|error| format!("Failed to go to `build_sysroot` directory: {:?}", error))?; @@ -143,7 +152,7 @@ fn build_sysroot( &"cargo", &"build", &"--target", - &target_triple, + &config.target, &"--release", ], None, @@ -156,7 +165,7 @@ fn build_sysroot( &"cargo", &"build", &"--target", - &target_triple, + &config.target, ], None, Some(env), @@ -165,14 +174,14 @@ fn build_sysroot( }; // Copy files to sysroot - let sysroot_path = format!("sysroot/lib/rustlib/{}/lib/", target_triple); + let sysroot_path = format!("sysroot/lib/rustlib/{}/lib/", config.target_triple); fs::create_dir_all(&sysroot_path) .map_err(|error| format!("Failed to create directory `{}`: {:?}", sysroot_path, error))?; let copier = |dir_to_copy: &Path| { run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ()) }; walk_dir( - &format!("target/{}/{}/deps", target_triple, channel), + &format!("target/{}/{}/deps", config.target_triple, channel), copier, copier, )?; @@ -216,7 +225,7 @@ fn build_codegen(args: &BuildArg) -> Result<(), String> { build_sysroot( &mut env, args.sysroot_release_channel, - &config.target_triple, + &config, )?; Ok(()) } diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 0f77943476f..64d9bd73e01 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::env as std_env; pub struct ConfigInfo { + pub target: String, pub target_triple: String, pub rustc_command: Vec, } @@ -30,25 +31,43 @@ pub fn set_config( let host_triple = get_rustc_host_triple()?; let mut linker = None; let mut target_triple = host_triple.clone(); + let mut target = target_triple.clone(); // We skip binary name and the command. let mut args = std::env::args().skip(2); + let mut set_target_triple = false; + let mut set_target = false; while let Some(arg) = args.next() { match arg.as_str() { "--target-triple" => { if let Some(arg) = args.next() { target_triple = arg; + set_target_triple = true; } else { return Err( "Expected a value after `--target-triple`, found nothing".to_string() ); } }, + "--target" => { + if let Some(arg) = args.next() { + target = arg; + set_target = true; + } else { + return Err( + "Expected a value after `--target`, found nothing".to_string() + ); + } + }, _ => (), } } + if set_target_triple && !set_target { + target = target_triple.clone(); + } + if host_triple != target_triple { linker = Some(format!("-Clinker={}-gcc", target_triple)); } @@ -123,7 +142,8 @@ pub fn set_config( "target/out".to_string(), ]); Ok(ConfigInfo { - target_triple: target_triple.to_string(), + target, + target_triple, rustc_command, }) }