Use Fuchsia-supplied rustc and cargo

One can override this by setting the enviromental variables
FARGO_CARGO and FARGO_RUSTC.

Also updated the documentation and command line help version
number.

Change-Id: I5e824ae1bced69852f7be41c7453714e81037321
diff --git a/README.md b/README.md
index a68185f..3435bdb 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # fargo
 
-    fargo v0.1.0
+    fargo v0.2.0
     Fargo is a prototype Fuchsia-specific wrapper around Cargo
 
     USAGE:
@@ -21,6 +21,7 @@
         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.
+        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.
         enable-networking    Enable networking for a running emulator
@@ -105,6 +106,12 @@
 folks happens to be paying attention. More reliable 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_ROOT/buildtools`.
+To change this behavior, set the environmental variables `FARGO_CARGO` and `FARGO_RUSTC` before
+running fargo.
+
 ## Using crates that link with native libraries
 
 Some crates are wrappers around libraries written in other languages. An
diff --git a/src/lib.rs b/src/lib.rs
index 3789904..24320e9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,9 +27,9 @@
 use device::{enable_networking, netaddr, netls, scp_to_device, ssh, start_emulator, stop_emulator};
 use facade::create_facade;
 use failure::{err_msg, Error, ResultExt};
-use sdk::{cargo_out_dir, clang_archiver_path, clang_c_compiler_path, clang_cpp_compiler_path,
-          clang_linker_path, clang_ranlib_path, shared_libraries_path, sysroot_path,
-          target_gen_dir, FuchsiaConfig};
+use sdk::{cargo_out_dir, cargo_path, clang_archiver_path, clang_c_compiler_path,
+          clang_cpp_compiler_path, clang_linker_path, clang_ranlib_path, rustc_path,
+          shared_libraries_path, sysroot_path, target_gen_dir, FuchsiaConfig};
 pub use sdk::TargetOptions;
 use std::fs;
 use std::path::PathBuf;
@@ -313,7 +313,7 @@
     }
 
     let pkg_path = pkg_config_path(target_options)?;
-    let mut cmd = Command::new("cargo");
+    let mut cmd = Command::new(cargo_path(target_options)?);
 
     cmd.env("CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUNNER", fargo_command)
         .env(
@@ -329,6 +329,10 @@
             clang_linker_path(target_options)?.to_str().unwrap(),
         )
         .env(
+            "CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTC",
+            rustc_path(target_options)?.to_str().unwrap(),
+        )
+        .env(
             "CC",
             clang_c_compiler_path(target_options)?.to_str().unwrap(),
         )
@@ -376,7 +380,7 @@
 #[doc(hidden)]
 pub fn run() -> Result<(), Error> {
     let matches = App::new("fargo")
-        .version("v0.1.0")
+        .version("v0.2.0")
         .setting(AppSettings::GlobalVersion)
         .about("Fargo is a prototype Fuchsia-specific wrapper around Cargo")
         .arg(
diff --git a/src/sdk.rs b/src/sdk.rs
index 0a61f09..69060ec 100644
--- a/src/sdk.rs
+++ b/src/sdk.rs
@@ -135,12 +135,45 @@
     Ok(fuchsia_root(&options)?.join("out").join(shared_name))
 }
 
-pub fn toolchain_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {
+fn buildtools_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {
     let platform_name = if is_mac() { "mac-x64" } else { "linux-x64" };
     Ok(fuchsia_root(target_options)?
         .join("buildtools")
-        .join(platform_name)
-        .join("clang"))
+        .join(platform_name))
+}
+
+pub fn cargo_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {
+    if let Ok(cargo_path_value) = env::var("FARGO_CARGO") {
+        let cargo_path = PathBuf::from(&cargo_path_value);
+        if !cargo_path.exists() {
+            bail!(
+                "FARGO_CARGO is set to '{}' but that path does not point to a file.",
+                &cargo_path_value
+            );
+        }
+        Ok(cargo_path)
+    } else {
+        Ok(buildtools_path(target_options)?.join("rust/bin/cargo"))
+    }
+}
+
+pub fn rustc_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {
+    if let Ok(rustc_path_value) = env::var("FARGO_RUSTC") {
+        let rustc_path = PathBuf::from(&rustc_path_value);
+        if !rustc_path.exists() {
+            bail!(
+                "FARGO_RUSTC is set to '{}' but that path does not point to a file.",
+                &rustc_path_value
+            );
+        }
+        Ok(rustc_path)
+    } else {
+        Ok(buildtools_path(target_options)?.join("rust/bin/rustc"))
+    }
+}
+
+pub fn toolchain_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {
+    Ok(buildtools_path(target_options)?.join("clang"))
 }
 
 pub fn clang_linker_path(target_options: &TargetOptions) -> Result<PathBuf, Error> {