Refactor run_cargo to support better nested escaped parameters
Also fix a lot of arm64 support bugs.
Change-Id: I3b7a921160512e9ef32954e62ca790c718cefe1d
diff --git a/README.md b/README.md
index 3435bdb..081f019 100644
--- a/README.md
+++ b/README.md
@@ -13,19 +13,25 @@
-v, --verbose Print verbose output while performing commands
OPTIONS:
- -N, --device-name <device-name> Name of device to target, needed if there are multiple devices visible on the network
+ -N, --device-name <device-name>
+ Name of device to target, needed if there are multiple devices visible on
+ the network
+ -T, --target-cpu <target-cpu>
+ Architecture of target device [default: x64] [values: x64, arm64]
+
SUBCOMMANDS:
autotest Auto build and test in Fuchsia device or emulator
build Build binary targeting Fuchsia device or emulator
build-tests Build tests for Fuchsia device or emulator
- cargo Run a cargo command for Fuchsia. Use -- to indicate that all following arguments should be passed to
- cargo.
+ cargo Run a cargo command for Fuchsia. Use -- to indicate that
+ all following arguments should be passed to cargo.
check Check binary targeting Fuchsia device or emulator
- configure Run a configure script for the cross compilation environment
- create-facade Create an in-tree facade crate for a FIDL interface.
+ configure Run a configure script for the cross compilation
+ environment
enable-networking Enable networking for a running emulator
- help Prints this message or the help of the given subcommand(s)
+ help Prints this message or the help of the given
+ subcommand(s)
list-devices List visible Fuchsia devices
load-driver Build driver and load it on Fuchsia device or emulator.
pkg-config Run pkg-config for the cross compilation environment
@@ -97,6 +103,14 @@
Additionally, if you are using qemu you need to enable networking, otherwise fargo won't be able to
copy the binary onto then fuchsia machine to run the tests.
+### Escaping parameters
+
+Sometimes you want to pass parameters through fargo and cargo and on to something like rustc. To make this easier fargo will convert a "++" parameter to "--" when invoking cargo. For example, the following command:
+
+ fargo cargo rustc -- ++ --emit=llvm-ir
+
+will get cargo to cause rustc to emil llvm ir files.
+
## Getting help
For problems getting the Fuchsia build to complete, the #fuchsia IRC channel on
diff --git a/src/lib.rs b/src/lib.rs
index b52cf96..ca34272 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -149,7 +149,7 @@
verbose: bool, release: bool, no_run: bool, target_options: &TargetOptions, test_target: &str,
params: &[&str], target_params: Option<&str>,
) -> Result<(), Error> {
- let mut args = vec!["test"];
+ let mut args = vec![];
if !test_target.is_empty() {
args.push("--test");
@@ -167,16 +167,30 @@
if target_params.is_some() {
let formatted_target_params = format!("--args={}", target_params.unwrap());
run_cargo(
- verbose,
- release,
- false,
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view: false,
+ },
+ "test",
&args,
target_options,
None,
Some(&formatted_target_params),
)?;
} else {
- run_cargo(verbose, release, false, &args, target_options, None, None)?;
+ run_cargo(
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view: false,
+ },
+ "test",
+ &args,
+ target_options,
+ None,
+ None,
+ )?;
}
Ok(())
@@ -185,39 +199,49 @@
fn build_binary(
verbose: bool, release: bool, target_options: &TargetOptions, params: &[&str]
) -> Result<(), Error> {
- let mut args = vec!["build"];
- for param in params {
- args.push(param);
- }
-
- run_cargo(verbose, release, false, &args, target_options, None, None)
+ run_cargo(
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view: false,
+ },
+ "build",
+ params,
+ target_options,
+ None,
+ None,
+ )
}
fn check_binary(
verbose: bool, release: bool, target_options: &TargetOptions, params: &[&str]
) -> Result<(), Error> {
- let mut args = vec!["check"];
- for param in params {
- args.push(param);
- }
-
- run_cargo(verbose, release, false, &args, target_options, None, None)
+ run_cargo(
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view: false,
+ },
+ "check",
+ params,
+ target_options,
+ None,
+ None,
+ )
}
fn run_binary(
verbose: bool, release: bool, set_root_view: bool, target_options: &TargetOptions,
params: &[&str],
) -> Result<(), Error> {
- let mut args = vec!["run"];
- for param in params {
- args.push(param);
- }
-
run_cargo(
- verbose,
- release,
- set_root_view,
- &args,
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view,
+ },
+ "run",
+ params,
target_options,
None,
None,
@@ -226,8 +250,19 @@
}
fn load_driver(verbose: bool, release: bool, target_options: &TargetOptions) -> Result<(), Error> {
- let args = vec!["build"];
- run_cargo(verbose, release, false, &args, target_options, None, None)?;
+ let args = vec![];
+ run_cargo(
+ RunCargoOptions {
+ verbose,
+ release,
+ set_root_view: false,
+ },
+ "build",
+ &args,
+ target_options,
+ None,
+ None,
+ )?;
let cwd = std::env::current_dir()?;
let package = cwd.file_name()
.ok_or(err_msg("No current directory"))?
@@ -243,6 +278,12 @@
Ok(())
}
+pub struct RunCargoOptions {
+ pub verbose: bool,
+ pub release: bool,
+ pub set_root_view: bool,
+}
+
/// Runs the cargo tool configured to target Fuchsia. When used as a library,
/// the runner options must contain the path to fargo or some other program
/// that implements the `run-on-target` subcommand in a way compatible with
@@ -251,26 +292,56 @@
/// # Examples
///
/// ```
-/// use fargo::{run_cargo, TargetOptions};
+/// use fargo::{run_cargo, RunCargoOptions, TargetOptions};
///
-/// let target_options = TargetOptions::new(true, None);
-/// run_cargo(false, true, false, &["--help"], &target_options, None, None);
+/// let target_options = TargetOptions::new(true, "x64", None);
+/// run_cargo(
+/// RunCargoOptions {
+/// verbose: false,
+/// release: true,
+/// set_root_view: false,
+/// },
+/// "help",
+/// &[],
+/// &target_options,
+/// None,
+/// None,
+/// );
/// ```
pub fn run_cargo(
- verbose: bool, release: bool, set_root_view: bool, args: &[&str],
- target_options: &TargetOptions, runner: Option<PathBuf>, additional_target_args: Option<&str>,
+ options: RunCargoOptions, subcommand: &str, args: &[&str], target_options: &TargetOptions,
+ runner: Option<PathBuf>, additional_target_args: Option<&str>,
) -> Result<(), Error> {
- let set_root_view_arg = format!("--{}", SET_ROOT_VIEW);
- let mut target_args = vec!["--target", "x86_64-unknown-fuchsia"];
+ if options.verbose {
+ println!("target_options = {:?}", target_options);
+ }
- if release {
+ let set_root_view_arg = format!("--{}", SET_ROOT_VIEW);
+
+ let triple_cpu = if target_options.target_cpu == X64 {
+ "x86_64"
+ } else {
+ "aarch64"
+ };
+ let target_triple = format!("{}-unknown-fuchsia", triple_cpu);
+ let mut target_args = vec!["--target", &target_triple];
+
+ if options.release {
target_args.push("--release");
}
- if verbose {
+ if options.verbose {
+ println!(
+ "target_options.target_cpu = {:?}",
+ target_options.target_cpu
+ );
+ println!("triple_cpu = {:?}", triple_cpu);
+ println!("target_triple = {:?}", target_triple);
println!("target_args = {:?}", target_args);
}
+ let target_triple_uc = format!("{}_unknown_fuchsia", triple_cpu).to_uppercase();
+
let fargo_path = if runner.is_some() {
runner.unwrap()
} else {
@@ -283,7 +354,7 @@
.ok_or_else(|| err_msg("unable to convert path to utf8 encoding"))?,
];
- if verbose {
+ if options.verbose {
runner_args.push("-v");
}
@@ -294,7 +365,7 @@
runner_args.push("run-on-target");
- if set_root_view {
+ if options.set_root_view {
runner_args.push(&set_root_view_arg);
}
@@ -304,7 +375,7 @@
let fargo_command = runner_args.join(" ");
- if verbose {
+ if options.verbose {
println!("fargo_command: {:?}", fargo_command);
}
@@ -313,21 +384,38 @@
let sysroot_as_path = sysroot_path(target_options)?;
let sysroot_as_str = sysroot_as_path.to_str().unwrap();
- cmd.env("CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUNNER", fargo_command)
+ let args: Vec<&str> = args.iter()
+ .map(|a| if *a == "++" { "--" } else { *a })
+ .collect();
+
+ let runner_env_name = format!("CARGO_TARGET_{}_RUNNER", target_triple_uc);
+ let rustflags_env_name = format!("CARGO_TARGET_{}_RUSTFLAGS", target_triple_uc);
+ let linker_env_name = format!("CARGO_TARGET_{}_LINKER", target_triple_uc);
+ let rustc_env_name = format!("CARGO_TARGET_{}_RUSTC", target_triple_uc);
+
+ if options.verbose {
+ println!("runner_env_name: {:?}", runner_env_name);
+ println!("rustflags_env_name: {:?}", rustflags_env_name);
+ println!("linker_env_name: {:?}", linker_env_name);
+ println!("rustc_env_name: {:?}", rustc_env_name);
+ }
+
+ cmd.env(runner_env_name, fargo_command)
.env(
- "CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS",
+ rustflags_env_name,
format!(
- "-C link-arg=--target=x86_64-unknown-fuchsia -C link-arg=--sysroot={} -Lnative={}",
+ "-C link-arg=--target={}-unknown-fuchsia -C link-arg=--sysroot={} -Lnative={}",
+ triple_cpu,
sysroot_as_str,
shared_libraries_path(target_options)?.to_str().unwrap(),
),
)
.env(
- "CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_LINKER",
+ linker_env_name,
clang_linker_path(target_options)?.to_str().unwrap(),
)
.env(
- "CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTC",
+ rustc_env_name,
rustc_path(target_options)?.to_str().unwrap(),
)
.env(
@@ -350,10 +438,11 @@
.env("PKG_CONFIG_LIBDIR", pkg_path)
.env("FUCHSIA_GEN_ROOT", target_gen_dir(target_options)?)
.env("FIDL_GEN_ROOT", fidl2_target_gen_dir(target_options)?)
- .args(args)
- .args(target_args);
+ .arg(subcommand)
+ .args(target_args)
+ .args(args);
- if verbose {
+ if options.verbose {
println!("cargo cmd: {:?}", cmd);
}
@@ -376,6 +465,8 @@
static X64: &str = "x64";
static ARM64: &str = "arm64";
+static SUBCOMMAND: &str = "subcommand";
+
#[doc(hidden)]
pub fn run() -> Result<(), Error> {
let matches = App::new("fargo")
@@ -560,7 +651,8 @@
"Run a cargo command for Fuchsia. Use -- to indicate that all following \
arguments should be passed to cargo.",
)
- .arg(Arg::with_name("cargo_params").index(1).multiple(true)),
+ .arg(Arg::with_name(SUBCOMMAND).required(true))
+ .arg(Arg::with_name("cargo_params").index(2).multiple(true)),
)
.subcommand(
SubCommand::with_name("run-on-target")
@@ -759,14 +851,18 @@
}
if let Some(cargo_matches) = matches.subcommand_matches("cargo") {
+ let subcommand = cargo_matches.value_of(SUBCOMMAND).unwrap();
let cargo_params = cargo_matches
.values_of("cargo_params")
.map(|x| x.collect())
.unwrap_or_else(|| vec![]);
return run_cargo(
- verbose,
- false,
- false,
+ RunCargoOptions {
+ verbose,
+ release: false,
+ set_root_view: false,
+ },
+ subcommand,
&cargo_params,
&target_options,
None,
diff --git a/src/sdk.rs b/src/sdk.rs
index 8938e6f..faa62cc 100644
--- a/src/sdk.rs
+++ b/src/sdk.rs
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+use X64;
use failure::Error;
use std::env;
use std::fs::File;
@@ -29,7 +30,7 @@
/// ```
/// use fargo::TargetOptions;
///
- /// let target_options = TargetOptions::new(true, Some("ivy-donut-grew-stoop"));
+ /// let target_options = TargetOptions::new(true, "x64", Some("ivy-donut-grew-stoop"));
/// ```
pub fn new(
@@ -147,7 +148,7 @@
}
pub fn shared_libraries_path(options: &TargetOptions) -> Result<PathBuf, Error> {
- let shared_name = if options.target_cpu == "x64" {
+ let shared_name = if options.target_cpu == X64 {
"x64-shared"
} else {
"arm64-shared"