Skip to content

Fix to be able to use a target specification JSON file and document the process #364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
23 changes: 16 additions & 7 deletions build_system/src/build.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand Down Expand Up @@ -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)),
}
}
Expand All @@ -80,7 +89,7 @@ impl BuildArg {
fn build_sysroot(
env: &mut HashMap<String, String>,
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))?;
Expand Down Expand Up @@ -143,7 +152,7 @@ fn build_sysroot(
&"cargo",
&"build",
&"--target",
&target_triple,
&config.target,
&"--release",
],
None,
Expand All @@ -156,7 +165,7 @@ fn build_sysroot(
&"cargo",
&"build",
&"--target",
&target_triple,
&config.target,
],
None,
Some(env),
Expand All @@ -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,
)?;
Expand Down Expand Up @@ -216,7 +225,7 @@ fn build_codegen(args: &BuildArg) -> Result<(), String> {
build_sysroot(
&mut env,
args.sysroot_release_channel,
&config.target_triple,
&config,
)?;
Ok(())
}
Expand Down
22 changes: 21 additions & 1 deletion build_system/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
}
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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,
})
}