Update to new lld-only linkage

Change-Id: I54a914e4a64e49c8080485da9c9de84ac402d47f
diff --git a/src/cross.rs b/src/cross.rs
index 79b665d..9d28c36 100644
--- a/src/cross.rs
+++ b/src/cross.rs
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use crate::sdk::{sysroot_path, toolchain_path, TargetOptions};
+use crate::sdk::{clang_base_path, sysroot_path, TargetOptions};
 use failure::{Error, ResultExt};
 use std::env;
 use std::fs;
@@ -61,13 +61,13 @@
         println!("sysroot_path: {:?}", sysroot_path);
     }
 
-    let toolchain_path = toolchain_path()?;
+    let clang_base_path = clang_base_path()?;
 
     if verbose {
-        println!("toolchain_path: {:?}", toolchain_path);
+        println!("clang_base_path: {:?}", clang_base_path);
     }
 
-    let toolchain_bin_path = toolchain_path.join("bin");
+    let clang_bin_path = clang_base_path.join("bin");
 
     let common_c_flags = format!(
         "--sysroot={} --target=x86_64-fuchsia -fPIC -I{}",
@@ -97,11 +97,11 @@
 
     cmd.args(&configure_args)
         .args(args)
-        .env("CC", toolchain_bin_path.join("clang"))
-        .env("CXX", toolchain_bin_path.join("clang++"))
-        .env("RANLIB", toolchain_bin_path.join("llvm-ranlib"))
-        .env("LD", toolchain_bin_path.join("llvm-lld"))
-        .env("AR", toolchain_bin_path.join("llvm-ar"))
+        .env("CC", clang_bin_path.join("clang"))
+        .env("CXX", clang_bin_path.join("clang++"))
+        .env("RANLIB", clang_bin_path.join("llvm-ranlib"))
+        .env("LD", clang_bin_path.join("llvm-lld"))
+        .env("AR", clang_bin_path.join("llvm-ar"))
         .env("CFLAGS", &common_c_flags)
         .env("CXXFLAGS", &common_c_flags)
         .env("CPPFLAGS", &common_c_flags)
diff --git a/src/lib.rs b/src/lib.rs
index 0478950..a823b48 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -18,10 +18,10 @@
 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};
-use crate::sdk::{cargo_out_dir, cargo_path, clang_archiver_path, clang_c_compiler_path,
+use crate::sdk::{cargo_out_dir, cargo_path, clang_archiver_path, clang_resource_dir, clang_c_compiler_path,
                  clang_cpp_compiler_path, clang_linker_path, clang_ranlib_path, rustc_path,
                  rustdoc_path, shared_libraries_path, sysroot_path, zircon_build_path};
-use crate::utils::{is_mac, strip_binary};
+use crate::utils::strip_binary;
 
 use clap::{App, AppSettings, Arg, SubCommand};
 use failure::{bail, err_msg, Error, ResultExt};
@@ -463,24 +463,28 @@
 fn get_rustflags(
     target_options: &TargetOptions<'_, '_>, sysroot_as_path: &PathBuf,
 ) -> Result<String, Error> {
+    let target_triple = get_target_triple(target_options);
+    let sysroot_lib_pathbuf = sysroot_as_path.join("lib");
+    let sysroot_lib = sysroot_lib_pathbuf.to_str().unwrap();
+    let clang_resource_lib =
+        clang_resource_dir(&target_triple)?
+            .join(&target_triple)
+            .join("lib");
+
     let mut rust_flags = vec![
-        format!("-C link-arg=--target={}", get_target_triple(target_options)),
-        format!(
-            "-C link-arg=--sysroot={}",
-            sysroot_as_path.to_str().unwrap()
-        ),
-        format!(
-            "-Lnative={}",
-            shared_libraries_path(target_options)?.to_str().unwrap()
-        ),
-        "-Clink-arg=-Wl,--pack-dyn-relocs=relr".to_string(),
+        "-L".to_string(), sysroot_lib.to_string(),
+        "-Clink-arg=--pack-dyn-relocs=relr".to_string(),
+        "-Clink-arg=--threads".to_string(),
+        format!("-Clink-arg=-L{}", sysroot_lib),
+        format!("-Clink-arg=-L{}", clang_resource_lib.to_str().unwrap()),
+        format!("-Clink-arg=--sysroot={}", sysroot_as_path.to_str().unwrap()),
+        format!("-Lnative={}", shared_libraries_path(target_options)?.to_str().unwrap()),
     ];
-    if !is_mac() {
-        rust_flags.push("-C link-arg=-Wl,--threads".to_string());
-    }
+
     if get_triple_cpu(target_options) == "aarch64" {
-        rust_flags.push("-Clink-arg=-Wl,--fix-cortex-a53-843419".to_string());
+        rust_flags.push("-Clink-arg=--fix-cortex-a53-843419".to_string());
     }
+
     Ok(rust_flags.join(" "))
 }
 
@@ -631,12 +635,10 @@
 
     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);
 
     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_path: {:?}", rustc_path()?.to_str().unwrap());
         println!("cargo_path: {:?}", cargo_path()?.to_str().unwrap());
     }
@@ -646,7 +648,6 @@
             rustflags_env_name,
             get_rustflags(target_options, &sysroot_as_path)?,
         )
-        .env(linker_env_name, clang_linker_path()?.to_str().unwrap())
         .env("RUSTC", rustc_path()?.to_str().unwrap())
         .env("RUSTDOC", rustdoc_path()?.to_str().unwrap())
         .env("RUSTDOCFLAGS", "--cap-lints allow -Z unstable-options")
diff --git a/src/sdk.rs b/src/sdk.rs
index 0e88613..110dbea 100644
--- a/src/sdk.rs
+++ b/src/sdk.rs
@@ -5,11 +5,12 @@
 use crate::get_target_triple;
 use crate::utils::is_mac;
 use crate::X64;
-use failure::{bail, Error};
+use failure::{bail, Error, ResultExt};
 use std::env;
 use std::fs::File;
 use std::io::Read;
 use std::path::PathBuf;
+use std::process::Command;
 
 /// The `TargetOptions` struct bundles together a number of parameters specific to
 /// the Fuchsia target that need to be passed through various internal functions. For
@@ -117,7 +118,7 @@
 }
 
 pub fn strip_tool_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin/llvm-objcopy"))
+    Ok(clang_base_path()?.join("bin/llvm-objcopy"))
 }
 
 pub fn sysroot_path(options: &TargetOptions<'_, '_>) -> Result<PathBuf, Error> {
@@ -182,28 +183,48 @@
     }
 }
 
-pub fn toolchain_path() -> Result<PathBuf, Error> {
+pub fn clang_base_path() -> Result<PathBuf, Error> {
     Ok(buildtools_path()?.join("clang"))
 }
 
 pub fn clang_linker_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin").join("clang"))
+    Ok(clang_base_path()?.join("bin").join("clang"))
 }
 
 pub fn clang_c_compiler_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin").join("clang"))
+    Ok(clang_base_path()?.join("bin").join("clang"))
 }
 
 pub fn clang_cpp_compiler_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin").join("clang++"))
+    Ok(clang_base_path()?.join("bin").join("clang++"))
 }
 
 pub fn clang_archiver_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin").join("llvm-ar"))
+    Ok(clang_base_path()?.join("bin").join("llvm-ar"))
 }
 
 pub fn clang_ranlib_path() -> Result<PathBuf, Error> {
-    Ok(toolchain_path()?.join("bin").join("llvm-ranlib"))
+    Ok(clang_base_path()?.join("bin").join("llvm-ranlib"))
+}
+
+pub fn clang_resource_dir(target: &str) -> Result<PathBuf, Error> {
+    let clang = clang_c_compiler_path()?;
+
+    let output = Command::new(clang)
+        .arg(format!("--target={}", target))
+        .arg("-print-resource-dir")
+        .output()
+        .context("Running `clang` to get resource dir")?;
+
+    if !output.status.success() {
+        bail!("Failed to get `clang` resource dir: {}",
+              String::from_utf8_lossy(&output.stderr));
+    }
+
+    let path_string = String::from_utf8(output.stdout)
+        .context("Invalid UTF8 in `clang` resource dir")?;
+
+    Ok(PathBuf::from(path_string.trim()))
 }
 
 pub fn fx_path() -> Result<PathBuf, Error> {