Add a command to build a Fuchsia targeting rustc
Change-Id: I838e5e30edf2ce4d75bffae1dfae3787a8ed4500
Testing: manual
diff --git a/src/build_rustc.rs b/src/build_rustc.rs
new file mode 100644
index 0000000..76b6f93
--- /dev/null
+++ b/src/build_rustc.rs
@@ -0,0 +1,124 @@
+use crate::sdk::{clang_base_path, clang_resource_dir, shared_libraries_path, sysroot_path, TargetOptions};
+use crate::X64;
+use crate::{get_target_triple, get_triple_cpu};
+
+use failure::Error;
+use std::fs::create_dir_all;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+use std::process::Command;
+
+pub fn build_rustc(rust_root: &Path, target_options: &TargetOptions<'_, '_>) -> Result<(), Error> {
+ let target_triple = get_target_triple(target_options);
+ let triple_cpu = get_triple_cpu(target_options);
+ let targets_name = if target_options.config.fuchsia_arch == X64 {
+ "X86"
+ } else {
+ "AArch64"
+ };
+ let clang_base_path = clang_base_path()?;
+ let clang_bin_path = clang_base_path.join("bin");
+ let staging = rust_root.join("fuchsia_staging");
+ create_dir_all(&staging)?;
+ let build = staging.join("build");
+ create_dir_all(&build)?;
+ let config_path = staging.join("config.toml");
+
+ let mut config = File::create(&config_path)?;
+ writeln!(
+ config,
+ r#"
+[llvm]
+optimize = true
+static-libstdcpp = true
+ninja = true
+targets = "{targets}"
+
+[build]
+target = ["{target}-fuchsia"]
+docs = false
+extended = true
+cargo-native-static = true
+
+[install]
+prefix = "{prefix}"
+sysconfdir = "etc"
+
+[rust]
+optimize = true
+channel = "nightly"
+lld = true
+
+[target.{target}-fuchsia]
+cc = "{cc}"
+cxx = "{cxx}"
+ar = "{ar}"
+linker = "{linker}"
+
+[dist]
+ "#,
+ prefix = staging.to_string_lossy(),
+ cc = clang_bin_path.join("clang").to_string_lossy(),
+ cxx = clang_bin_path.join("clang++").to_string_lossy(),
+ ar = clang_bin_path.join("llvm-ar").to_string_lossy(),
+ linker = clang_bin_path.join("ld.lld").to_string_lossy(),
+ target = triple_cpu,
+ targets = targets_name,
+ )?;
+
+ let sysroot_path = sysroot_path(target_options)?;
+ let sysroot_lib_path = sysroot_path.join("lib");
+ let clang_resource_lib = clang_resource_dir(&target_triple)?
+ .join(&target_triple)
+ .join("lib");
+
+ let cargo_dir = staging.join(".cargo");
+ create_dir_all(&cargo_dir)?;
+ let cargo_config_path = cargo_dir.join("config");
+
+ let mut cargo_config = File::create(&cargo_config_path)?;
+ writeln!(
+ cargo_config,
+ r#"
+[target.{target}-fuchsia]
+ar = "{ar}"
+rustflags = [
+ "-C", "link-arg=--sysroot={sysroot}",
+ "-C", "link-arg=-L{sysroot}/lib",
+ "-C", "link-arg=-L{target_lib}",
+ "-C", "link-arg=-L{clang_resource_lib}",
+]
+ "#,
+ target = triple_cpu,
+ sysroot = sysroot_path.to_string_lossy(),
+ ar = clang_bin_path.join("llvm-ar").to_string_lossy(),
+ target_lib = shared_libraries_path(target_options)?.to_string_lossy(),
+ clang_resource_lib = clang_resource_lib.to_string_lossy(),
+ )?;
+ let x_py = rust_root.join("x.py");
+ let common_c_flags = format!(
+ "--sysroot={} --target={}-fuchsia",
+ sysroot_path.to_str().unwrap(),
+ triple_cpu
+ );
+ let ld_flags = format!(
+ "--sysroot={} --target={}-fuchsia -L{}",
+ sysroot_path.to_str().unwrap(),
+ triple_cpu,
+ sysroot_lib_path.to_string_lossy()
+ );
+ let mut cmd = Command::new(x_py);
+ cmd.current_dir(build)
+ .env(format!("CFLAGS_{}-fuchsia", triple_cpu), &common_c_flags)
+ .env(format!("LDFLAGS_{}-fuchsia", triple_cpu), &ld_flags)
+ .arg("build")
+ .arg("--config")
+ .arg(&config_path)
+ .arg("--target")
+ .arg(format!("{}-fuchsia", triple_cpu));
+
+ println!("cmd = {:#?}", cmd);
+ cmd.status().expect("x_py command failed to start");
+ Ok(())
+}
diff --git a/src/lib.rs b/src/lib.rs
index 5e86567..7b707f2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,6 +8,7 @@
#![recursion_limit = "1024"]
+mod build_rustc;
mod cross;
mod device;
mod sdk;
@@ -15,6 +16,7 @@
pub use crate::sdk::{FuchsiaConfig, TargetOptions};
+use crate::build_rustc::build_rustc;
use crate::cross::{pkg_config_path, run_configure, run_pkg_config};
use crate::device::{enable_networking, netaddr, netls, scp_to_device, ssh, start_emulator,
stop_emulator, StartEmulatorOptions};
@@ -775,6 +777,9 @@
static WRITE_CONFIG: &str = "write-config";
+static BUILD_RUSTC: &str = "build-rustc";
+static RUST_ROOT: &str = "rust-root";
+
static RUN_ON_TARGET: &str = "run-on-target";
#[doc(hidden)]
@@ -1070,6 +1075,17 @@
.subcommand(SubCommand::with_name(WRITE_CONFIG).about(
"Write a .cargo/config file to allow cargo to operate correctly for Fuchsia",
))
+ .subcommand(
+ SubCommand::with_name(BUILD_RUSTC)
+ .arg(
+ Arg::with_name(RUST_ROOT)
+ .long(RUST_ROOT)
+ .value_name(RUST_ROOT)
+ .required(true)
+ .help("Path to rust checkout"),
+ )
+ .about("Build rustc targeting Fuchsia"),
+ )
.get_matches();
let verbose = matches.is_present("verbose");
@@ -1368,5 +1384,10 @@
return write_config(&run_cargo_options, &target_options);
}
+ if let Some(build_rustc_matches) = matches.subcommand_matches(BUILD_RUSTC) {
+ let rust_root = PathBuf::from(build_rustc_matches.value_of(RUST_ROOT).unwrap());
+ return build_rustc(&rust_root, &target_options);
+ }
+
Ok(())
}