Add support for more complex builds
Also up the amount of time waiting for tap0 to come up,
at 100ms it was timing out for femu all the time.
Change-Id: Ief73992f790427dbf63593d8f332201ee3601997
diff --git a/Cargo.lock b/Cargo.lock
index 4f11b53..d45d020 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -118,7 +118,7 @@
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"uname 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -545,7 +545,7 @@
[[package]]
name = "toml"
-version = "0.4.10"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -702,7 +702,7 @@
"checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
+"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
"checksum uname 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
diff --git a/Cargo.toml b/Cargo.toml
index 6dd17c2..9fa889e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,7 @@
serde_json = "1.0"
structopt = "0.3"
tempfile = "3.1"
-toml = "0.4"
+toml = "0.5"
[[bin]]
name = "fargo"
diff --git a/README.md b/README.md
index 06b592d..fd98ece 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@
## Getting started
-Since at the moment fargo requires the FUCHSIA\_DIR environmental variable be
+Since at the moment Fargo requires the FUCHSIA\_DIR environmental variable be
set to the path to a Fuchsia source tree containing a Fuchsia build,
the first step is to build Fuchsia.
@@ -54,7 +54,7 @@
instruction are what you need. Make sure that `fx serve` is running pointed at
this Fuchsia build.
-Once this build is complete, clone and build fargo. For this you will need
+Once this build is complete, clone and build Fargo. For this you will need
a working host Rust installation, most easily installed with [rustup](https://rustup.rs).
git clone https://fuchsia.googlesource.com/fargo
@@ -64,31 +64,31 @@
Fargo uses the values set by `./scripts/fx set` to know what
build directory to use.
-Fargo uses ssh to communicate between your host computer and either Qemu or a
-real device to copy build results and execute them. For Qemu there is a bit of
-[tricky set up](https://fuchsia.googlesource.com/fuchsia/+/master/zircon/docs/qemu.md#enabling-networking-under-qemu) to do.
+Fargo uses ssh to communicate between your host computer and either the emulator or a
+real device to copy build results and execute them. For the emulator there is a bit of
+[tricky set up](https://fuchsia.dev/fuchsia-src/getting_started#enabling_network) to do.
### Testing if Fargo is working
-Now to verify if fargo is working correctly, try starting a fuchsia machine and executing a test.
+Now to verify if Fargo is working correctly, try starting a fuchsia machine and executing a test.
fargo start
cd fargo/fargo-test
fargo test
-Note that fargo start now depends on an environment using fx set. If that isn't the way you start
-Fuchsia emulators, use fargo enable-networking after you've started the emulator.
+Note that Fargo start now depends on an environment using fx set. If that isn't the way you start
+Fuchsia emulators, use `fargo enable-networking` after you've started the emulator.
If all is well, you should see a successful test pass just as if you had ran cargo test on any other
rust project.
-Additionally, if you are using qemu you need to enable networking, otherwise fargo won't be able to
-use `fx shell` to invoke the test binary.
+Additionally, if you are using the emulator you need to enable networking, otherwise
+Fargo won't be able to use `fx shell` to invoke the test binary.
### Escaping parameters
-Sometimes you want to pass parameters through fargo and cargo and on to
-somethinglike rustc. To make this easier fargo will convert a "++"
+Sometimes you want to pass parameters through Fargo and cargo and on to
+somethinglike rustc. To make this easier Fargo will convert a "++"
parameter to "--" when invoking cargo. For example, the following
command:
@@ -98,9 +98,10 @@
### Running view-producing Rust binaries
-fargo run has the options, `--run-with-tiles` and `--run-with-sessionctl`, that will use
-`tiles_ctl add` to launch the Rust binary. Use this option when running if your binaries
-wants to provide a
+`fargo run` has the options, `--run-with-tiles` and `--run-with-sessionctl`, that will use
+`tiles_ctl` or `sessionctl`, respectively, to launch the Rust binary.
+Use this option when running if your binaries
+want to provide a
[view provider service](https://fuchsia.googlesource.com/fuchsia/+/refs/heads/master/sdk/fidl/fuchsia.ui.app/view_provider.fidl)
## Creating a .cargo/config
@@ -111,22 +112,74 @@
for Fuchsia.
The config file created will be for the architecture and debug/release options that are
-passed to fargo with the `write-config` command. If you wish to switch to a different
+passed to Fargo with the `write-config` command. If you wish to switch to a different
architecture or build, re-run `write-config`.
+## The Fargo manifest file
+
+Some build configuration needed to create a functioning Fuchsia package are not contained
+inside the Cargo.toml files generated as part of `fx build`. The Fargo manifest file
+Fargo.toml exists to provide those configuration.
+
+There are three properties that one can set with this file, `library_search_paths`,
+`additional_shared_libraries` and `data_files` as shown in the example below.
+
+ library_search_paths = [
+ "obj/src/graphics/lib/compute/spinel",
+ "obj/src/graphics/lib/compute/common",
+ "obj/src/graphics/lib/compute/common/vk",
+ "obj/src/graphics/lib/compute/hotsort/platforms/vk",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/intel/gen8/hotsort",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/amd/gcn3/hotsort",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/nvidia/sm50/hotsort",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/intel/gen8",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/amd/gcn3",
+ "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/nvidia/sm50",
+ ]
+
+ additional_shared_libraries = [
+ "libvulkan.so",
+ "librust-trace-provider.so",
+ ]
+
+ data_files = [
+ { src = "examples/shaders/copy.comp.spv", dst = "data/shaders/copy.comp.spv"},
+ { src = "examples/shaders/motioncopy.comp.spv", dst = "data/shaders/motioncopy.comp.spv"},
+ ]
+
+`library_search_paths` are additional paths to pass to `rustc` to resolve external
+references at compile time. The paths should be the partial path from the Fuchsia build
+directory.
+
+`additional_shared_libraries` are the names of shared libraries that should be included in
+the Fuchsia package that is created by Fargo to run Rust executables on Fuchsia. These
+are expected to be found in the shared libraries folder in the Fuchsia build
+directory
+
+`data_files` are partial paths to additional data files to be included in the Fuchsia
+package that is created by Fargo to run Rust executables on Fuchsia. These paths should be
+the partial path from the root of the crate being compiled.
+
+In the example above, `Fargo.toml` is used to resolve the static libraries used by Spinel,
+to include two shared libraries needed by some of the samples for Carnelian and to include
+two compiled shaders also needed by a particular sample.
+
+Currently there is no way to limit these configuration to one example or binary.
+
## Getting help
For problems getting the Fuchsia build to complete, the [getting started](https://fuchsia.dev/fuchsia-src/getting_started.md)
page on [fuchsia.dev](https://fuchsia.dev) is the best place to start looking for help.
-For fargo itself, the best place for help is the
+For Fargo itself, the best place for help is the
[rust-fuchsia](https://groups.google.com/a/fuchsia.com/forum/#!aboutgroup/rust-fuchsia) Google group.
## Using different versions of cargo and rustc
-By default fargo will use the copies of cargo and rustc provided in `$FUCHSIA_DIR/buildtools`.
+By default Fargo will use the copies of cargo and rustc provided in `$FUCHSIA_DIR/buildtools`.
To change this behavior, set the environmental variables `FARGO_CARGO` and `FARGO_RUSTC` before
-running fargo.
+running Fargo.
If you need to be using a different version of nightly for some reason, you'll need the `x86_64-fuchsia` target.
If you installed rust with [rustup](https://www.rustup.rs) you can install the target with:
@@ -135,9 +188,9 @@
rustup target add x86_64-fuchsia
-## Environmental variables set by fargo
+## Environmental variables set by Fargo
-CARGO\_TARGET\_[X86\_64|AARCH64]\_UNKNOWN\_FUCHSIA\_RUNNER - set to the fargo binary to run remotely on simulator or device.
+CARGO\_TARGET\_[X86\_64|AARCH64]\_UNKNOWN\_FUCHSIA\_RUNNER - set to the Fargo binary to run remotely on simulator or device.
CARGO\_TARGET\_[X86\_64|AARCH64]\_UNKNOWN\_FUCHSIA\_RUSTFLAGS - set to provide linker flags
@@ -178,7 +231,7 @@
See `scripts/build_cairo_support.sh` for an example of how to use these
functions to build native support.
-fargo sets the following environmental variables before invoking configure:
+Fargo sets the following environmental variables before invoking configure:
CC, CXX, RANLIB, LD, AR, CFLAGS, CXXFLAGS, CPPFLAGS
LDFLAGS, PKG_CONFIG_PATH, PKG_CONFIG_LIBDIR,
@@ -190,4 +243,4 @@
## Fargo roadmap
-The goal is to transition fargo to using something like an SDK instead.
+The goal is to transition Fargo to using something like an SDK instead.
diff --git a/src/command_line.rs b/src/command_line.rs
index dce3cc4..0873b21 100644
--- a/src/command_line.rs
+++ b/src/command_line.rs
@@ -5,7 +5,7 @@
cross::run_pkg_config,
device::{netls, ssh, start_emulator, stop_emulator, StartEmulatorOptions},
enable_networking, format_project,
- package::make_package,
+ manifest::load_manifest,
random_story_name, run_binary, run_cargo, run_configure, run_program_on_target,
run_switches_to_mode, run_tests,
sdk::TargetOptions,
@@ -38,8 +38,6 @@
Fmt,
/// List visible Fuchsia devices
ListDevices,
- /// Make a Fuchsia package from an unstripped binary
- MakePackage(MakePackage),
/// Run pkg-config for the cross compilation environment
PkgConfig(PkgConfig),
/// Stop all Fuchsia emulators and start a new one
@@ -368,6 +366,7 @@
#[doc(hidden)]
pub fn run() -> Result<(), Error> {
let opt = FargoOption::from_args();
+ let fargo_manifest = load_manifest(&opt.manifest_path)?;
let verbose = opt.verbose;
let fuchsia_config = FuchsiaConfig::new_from_fx_exec()?;
if verbose {
@@ -376,7 +375,12 @@
let target_options =
TargetOptions::new(&fuchsia_config, opt.device_name.as_ref().map(String::as_str));
- let run_cargo_options = RunCargoOptions { verbose, ..RunCargoOptions::default() };
+ let run_cargo_options = RunCargoOptions {
+ verbose,
+ fargo_manifest: fargo_manifest.clone(),
+ manifest_path: opt.manifest_path.clone(),
+ ..RunCargoOptions::default()
+ };
match opt.command {
FargoCommand::Autotest(autotest_opts) => {
@@ -409,6 +413,7 @@
cargo_opts.cargo_params.iter().map(String::as_str).collect();
return run_cargo(
&RunCargoOptions {
+ fargo_manifest,
verbose,
release: false,
nocapture: false,
@@ -467,20 +472,6 @@
return netls(opt.verbose, &target_options);
}
- FargoCommand::MakePackage(make_package_opts) => {
- println!(
- "make package {}",
- make_package(
- verbose,
- &target_options,
- &make_package_opts.binary_path,
- &make_package_opts.cmx_path,
- &make_package_opts.app_name
- )?
- );
- return Ok(());
- }
-
FargoCommand::PkgConfig(pkg_config_opts) => {
let pkg_params: Vec<&str> =
pkg_config_opts.pkg_config_params.iter().map(String::as_str).collect();
@@ -557,7 +548,7 @@
&fuchsia_config,
&target_options,
run_mode,
- &run_cargo_options.cmx_path,
+ &run_cargo_options,
&run_on_target.story_name.unwrap_or(random_story_name()),
&run_on_target.mod_name.unwrap_or(DEFAULT_MOD_NAME.to_string()),
&run_on_target.app_name,
diff --git a/src/device.rs b/src/device.rs
index 18f458a..6d831b4 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -114,7 +114,7 @@
bail!("ifconfig failed: {}", ifconfig_status);
}
loop_count += 1;
- thread::sleep(time::Duration::from_millis(100));
+ thread::sleep(time::Duration::from_millis(300));
} else {
break;
}
diff --git a/src/lib.rs b/src/lib.rs
index 4ab7738..2699443 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,6 +13,7 @@
pub mod command_line;
mod cross;
mod device;
+mod manifest;
mod package;
mod sdk;
mod utils;
@@ -25,8 +26,9 @@
use crate::sdk::{
cargo_path, clang_archiver_path, clang_c_compiler_path, clang_cpp_compiler_path,
clang_ranlib_path, clang_resource_dir, rustc_path, rustdoc_path, shared_libraries_path,
- sysroot_path, zircon_build_path,
+ sysroot_path, target_out_dir, zircon_build_path,
};
+use manifest::Manifest;
use failure::{bail, err_msg, Error, ResultExt};
use std::fs;
@@ -43,7 +45,7 @@
config: &FuchsiaConfig,
target_options: &TargetOptions<'_, '_>,
run_mode: RunMode,
- cmx_path: &Option<PathBuf>,
+ run_cargo_options: &RunCargoOptions,
story_name: &str,
mod_name: &str,
app_name: &str,
@@ -52,7 +54,8 @@
) -> Result<(), Error> {
let source_path = PathBuf::from(&filename);
- let target_string = make_package(verbose, target_options, &source_path, cmx_path, app_name)?;
+ let target_string =
+ make_package(verbose, target_options, &run_cargo_options, &source_path, app_name)?;
let mut command_string = match run_mode {
RunMode::Tiles => "tiles_ctl add ".to_string(),
@@ -241,6 +244,7 @@
#[derive(Debug, Clone, Default)]
pub struct RunCargoOptions {
+ pub fargo_manifest: Manifest,
pub verbose: bool,
pub release: bool,
pub run_mode: RunMode,
@@ -322,6 +326,7 @@
}
fn get_rustflags(
+ run_cargo_options: &RunCargoOptions,
target_options: &TargetOptions<'_, '_>,
sysroot_as_path: &PathBuf,
) -> Result<String, Error> {
@@ -352,6 +357,12 @@
rust_flags.push("-Clink-arg=--fix-cortex-a53-843419".to_string());
}
+ for search_path in &run_cargo_options.fargo_manifest.library_search_paths {
+ let full_search_path = target_out_dir(&target_options.config)?.join(search_path);
+ let arg = format!("-Lnative={}", full_search_path.to_string_lossy());
+ rust_flags.push(arg);
+ }
+
Ok(rust_flags.join(" "))
}
@@ -370,6 +381,7 @@
options.get_story_name(),
options.get_mod_name()
);
+ let manifest_path_string;
let cmx_arg = format!("--{}", CMX_PATH);
let app_name_arg = format!("--{}", APP_NAME);
let run_arg = format!("--{}", RUN_WITH_RUN);
@@ -389,6 +401,12 @@
runner_args.push("-v");
}
+ if let Some(manifest_path) = options.manifest_path.as_ref() {
+ manifest_path_string = manifest_path.to_string_lossy();
+ runner_args.push("--manifest-path");
+ runner_args.push(&manifest_path_string);
+ }
+
if let Some(device_name) = target_options.device_name {
runner_args.push("--device-name");
runner_args.push(device_name);
@@ -531,7 +549,7 @@
}
cmd.env(runner_env_name, fargo_command)
- .env(rustflags_env_name, get_rustflags(target_options, &sysroot_as_path)?)
+ .env(rustflags_env_name, get_rustflags(options, target_options, &sysroot_as_path)?)
.env("RUSTC", rustc_path()?.to_string_lossy().as_ref())
.env("RUSTDOC", rustdoc_path()?.to_string_lossy().as_ref())
.env("RUSTDOCFLAGS", "--cap-lints allow -Z unstable-options")
@@ -597,7 +615,11 @@
let sysroot_as_path = sysroot_path(target_options)?;
writeln!(config, "[target.{}]", get_target_triple(target_options))?;
- writeln!(config, "rustflags = \"{}\"", get_rustflags(target_options, &sysroot_as_path)?)?;
+ writeln!(
+ config,
+ "rustflags = \"{}\"",
+ get_rustflags(options, target_options, &sysroot_as_path)?
+ )?;
writeln!(
config,
"runner = \"{}\"",
diff --git a/src/manifest.rs b/src/manifest.rs
new file mode 100644
index 0000000..efbe999
--- /dev/null
+++ b/src/manifest.rs
@@ -0,0 +1,39 @@
+// Copyright 2020 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use failure::{Error, ResultExt};
+use serde_derive::Deserialize;
+use std::{fs, path::PathBuf};
+
+#[derive(Clone, Debug, Default, Deserialize)]
+pub struct DataFile {
+ pub src: String,
+ pub dst: String,
+}
+
+#[derive(Clone, Debug, Default, Deserialize)]
+pub struct Manifest {
+ #[serde(default)]
+ pub library_search_paths: Vec<String>,
+ #[serde(default)]
+ pub additional_shared_libraries: Vec<String>,
+ #[serde(default)]
+ pub data_files: Vec<DataFile>,
+}
+
+pub fn load_manifest(manifest_path: &Option<PathBuf>) -> Result<Manifest, Error> {
+ let cwd: PathBuf = if let Some(actual_manifest_path) = manifest_path.as_ref() {
+ actual_manifest_path.parent().expect("manifest_path parent").to_path_buf()
+ } else {
+ std::fs::canonicalize(std::env::current_dir()?)
+ .context("autotest: canonicalize working directory")?
+ };
+ let manifest_path = cwd.join("Fargo.toml");
+ if !manifest_path.exists() {
+ return Ok(Manifest::default());
+ }
+ let manifest_contents = fs::read_to_string(manifest_path)?;
+ let manifest = toml::from_str(&manifest_contents)?;
+ Ok(manifest)
+}
diff --git a/src/package.rs b/src/package.rs
index 5d9ecf6..2d5e25e 100644
--- a/src/package.rs
+++ b/src/package.rs
@@ -6,9 +6,10 @@
get_triple_cpu,
sdk::{
amber_path, clang_base_path, cmc_path, fuchsia_dir, package_manager_path,
- zircon_build_path, FuchsiaConfig, TargetOptions,
+ shared_libraries_path, zircon_build_path, FuchsiaConfig, TargetOptions,
},
- utils::strip_binary,
+ utils::{strip_binary, target_crate_path},
+ RunCargoOptions,
};
use failure::{bail, format_err, Error, ResultExt};
use serde::{Deserialize, Serialize};
@@ -105,6 +106,7 @@
fn write_manifest_file(
verbose: bool,
target_options: &TargetOptions<'_, '_>,
+ run_cargo_options: &RunCargoOptions,
target: &Path,
binary_path: &Path,
package_path: &Path,
@@ -159,6 +161,32 @@
triple,
);
+ let shared_lib_path = shared_libraries_path(target_options)?;
+ let additional_libs: Vec<String> = run_cargo_options
+ .fargo_manifest
+ .additional_shared_libraries
+ .iter()
+ .map(|lib_name| {
+ format!("lib/{}={}/{}", lib_name, shared_lib_path.to_string_lossy(), lib_name)
+ })
+ .collect();
+
+ let additional_lib_str = additional_libs.join("\n");
+
+ let target_crate_path = target_crate_path(&run_cargo_options.manifest_path)?;
+ let target_crate_path_string = target_crate_path.to_string_lossy();
+
+ let data_files: Vec<String> = run_cargo_options
+ .fargo_manifest
+ .data_files
+ .iter()
+ .map(|data_file| {
+ format!("{}={}/{}", data_file.dst, target_crate_path_string, data_file.src)
+ })
+ .collect();
+
+ let data_files_str = data_files.join("\n");
+
writeln!(
manifest,
r#"bin/{}={}
@@ -172,6 +200,8 @@
lib/libunwind.so.1={}
meta/package={}
meta/{}.cmx={}
+{}
+{}
"#,
app_name,
binary_path.to_string_lossy(),
@@ -186,6 +216,8 @@
package_path.to_string_lossy(),
package_name,
cmx_path.to_string_lossy(),
+ additional_lib_str,
+ data_files_str,
)?;
Ok(())
}
@@ -324,13 +356,13 @@
pub fn make_package(
verbose: bool,
target_options: &TargetOptions<'_, '_>,
+ run_cargo_options: &RunCargoOptions,
binary_path: &Path,
- optional_cmx_path: &Option<PathBuf>,
app_name: &str,
) -> Result<String, Error> {
let temp_dir = tempdir()?;
let dfs;
- let cmx_path = if let Some(path) = optional_cmx_path.as_ref() {
+ let cmx_path = if let Some(path) = run_cargo_options.cmx_path.as_ref() {
path
} else {
dfs = default_sandbox_file(&temp_dir)?;
@@ -362,6 +394,7 @@
write_manifest_file(
verbose,
&target_options,
+ &run_cargo_options,
&manifest_path,
&stripped_binary_path,
&package_path,
diff --git a/src/utils.rs b/src/utils.rs
index 6b14d2e..a68094e 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -39,3 +39,14 @@
Ok(target_path)
}
+
+pub fn target_crate_path(manifest_path: &Option<PathBuf>) -> Result<PathBuf, Error> {
+ let cwd: PathBuf = if let Some(actual_manifest_path) = manifest_path.as_ref() {
+ actual_manifest_path.parent().expect("manifest_path parent").to_path_buf()
+ } else {
+ std::fs::canonicalize(std::env::current_dir()?)
+ .context("autotest: canonicalize working directory")?
+ };
+
+ Ok(cwd)
+}