From 78166b99f239d5e14719283f9563071904e6b3b2 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 May 2018 11:12:50 +0200 Subject: [PATCH 1/5] Build LLD in addition to Clang in Linux CI --- src/ci/docker/dist-x86_64-linux/build-clang.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ci/docker/dist-x86_64-linux/build-clang.sh b/src/ci/docker/dist-x86_64-linux/build-clang.sh index b0c27aa45bf93..4595eacb31061 100755 --- a/src/ci/docker/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/dist-x86_64-linux/build-clang.sh @@ -30,6 +30,12 @@ curl https://releases.llvm.org/$LLVM/cfe-$LLVM.src.tar.xz | \ xz -d | \ tar xf - -C tools/clang --strip-components=1 +mkdir -p tools/lld + +curl https://releases.llvm.org/$LLVM/lld-$LLVM.src.tar.xz | \ + xz -d | \ + tar xf - -C tools/lld --strip-components=1 + mkdir ../clang-build cd ../clang-build From 852bef968107c710000656b2a650cefd34213cb2 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 May 2018 16:34:02 +0200 Subject: [PATCH 2/5] Add build_helper::command_ext which extends std::process::Command. --- src/bootstrap/builder.rs | 2 +- src/bootstrap/cc_detect.rs | 6 +- src/bootstrap/channel.rs | 2 +- src/bootstrap/compile.rs | 3 +- src/bootstrap/dist.rs | 3 +- src/bootstrap/install.rs | 2 +- src/bootstrap/lib.rs | 3 +- src/bootstrap/metadata.rs | 2 +- src/bootstrap/native.rs | 2 +- src/bootstrap/sanity.rs | 2 +- src/bootstrap/test.rs | 2 +- src/bootstrap/tool.rs | 3 +- src/bootstrap/util.rs | 2 +- src/build_helper/command_ext.rs | 122 ++++++++++++++++++++++++++++++++ src/build_helper/lib.rs | 6 +- src/liballoc_jemalloc/build.rs | 2 +- src/librustc_llvm/build.rs | 2 +- src/libstd/build.rs | 2 +- 18 files changed, 150 insertions(+), 18 deletions(-) create mode 100644 src/build_helper/command_ext.rs diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f84ddf8a17d13..b75ffb1ec3d1c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -17,10 +17,10 @@ use std::fs; use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::process::Command; use std::time::{Instant, Duration}; use std::collections::HashMap; +use build_helper::command_ext::Command; use compile; use install; use dist; diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 698903f128d4d..b9d09f40fca6b 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -34,9 +34,9 @@ use std::collections::HashSet; use std::{env, iter}; use std::path::{Path, PathBuf}; -use std::process::Command; use build_helper::output; +use build_helper::command_ext::Command; use cc; use Build; @@ -158,7 +158,9 @@ fn set_compiler(cfg: &mut cc::Build, return } - let output = output(c.to_command().arg("--version")); + + let output = output(Command::from_std_command(c.to_command()) + .arg("--version")); let i = match output.find(" 4.") { Some(i) => i, None => return, diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index a2495f68c1fa3..4b2faa625c130 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -16,9 +16,9 @@ //! print out as part of its version information. use std::path::Path; -use std::process::Command; use build_helper::output; +use build_helper::command_ext::Command; use Build; use config::Config; diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 231ed9d40d2de..bbad27d28cc5c 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -22,11 +22,12 @@ use std::fs::{self, File}; use std::io::BufReader; use std::io::prelude::*; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::Stdio; use std::str; use std::cmp::min; use build_helper::{output, mtime, up_to_date}; +use build_helper::command_ext::Command; use filetime::FileTime; use serde_json; diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e21a59390b7b6..26796d4bc2982 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -22,9 +22,10 @@ use std::env; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::{PathBuf, Path}; -use std::process::{Command, Stdio}; +use std::process::Stdio; use build_helper::output; +use build_helper::command_ext::Command; use {Compiler, Mode}; use channel; diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index b37a007e86390..78054a93b6055 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -16,11 +16,11 @@ use std::env; use std::fs; use std::path::{Path, PathBuf, Component}; -use std::process::Command; use dist::{self, pkgname, sanitize_sh, tmpdir}; use builder::{Builder, RunConfig, ShouldRun, Step}; +use build_helper::command_ext::Command; use cache::Interned; use config::Config; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f64161fb0272c..e59b6fdaba4f8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -145,11 +145,12 @@ use std::env; use std::fs::{self, OpenOptions, File}; use std::io::{self, Seek, SeekFrom, Write, Read}; use std::path::{PathBuf, Path}; -use std::process::{self, Command}; +use std::process; use std::slice; use std::str; use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime}; +use build_helper::command_ext::Command; use filetime::FileTime; use util::{exe, libdir, OutputFolder, CiEnv}; diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 5f1df1d26e273..a521922d857a0 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -9,10 +9,10 @@ // except according to those terms. use std::collections::HashMap; -use std::process::Command; use std::path::PathBuf; use build_helper::output; +use build_helper::command_ext::Command; use serde_json; use {Build, Crate}; diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 93292c658bad2..8e4020e727868 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -23,9 +23,9 @@ use std::ffi::OsString; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use std::process::Command; use build_helper::output; +use build_helper::command_ext::Command; use cmake; use cc; diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index c7f514da939a6..2c36ea972b1ff 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -24,9 +24,9 @@ use std::ffi::{OsString, OsStr}; use std::fs::{self, File}; use std::io::Read; use std::path::PathBuf; -use std::process::Command; use build_helper::output; +use build_helper::command_ext::Command; use Build; diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 7a4924f03c8d2..521476ed56c8a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -19,10 +19,10 @@ use std::iter; use std::fmt; use std::fs::{self, File}; use std::path::{PathBuf, Path}; -use std::process::Command; use std::io::Read; use build_helper::{self, output}; +use build_helper::command_ext::Command; use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step}; use Crate as CargoCrate; diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 29f37b36e2a8c..f7c530696cbd1 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -12,11 +12,12 @@ use std::fs; use std::env; use std::iter; use std::path::PathBuf; -use std::process::{Command, exit}; +use std::process::exit; use Mode; use Compiler; use builder::{Step, RunConfig, ShouldRun, Builder}; +use build_helper::command_ext::Command; use util::{exe, add_lib_path}; use compile::{self, libtest_stamp, libstd_stamp, librustc_stamp}; use native; diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 9a2b9e90440e5..6db908ec42856 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -18,11 +18,11 @@ use std::str; use std::fs; use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use std::process::Command; use std::time::{SystemTime, Instant}; use config::Config; use builder::Builder; +use build_helper::command_ext::Command; /// Returns the `name` as the filename of a static library for `target`. pub fn staticlib(name: &str, target: &str) -> String { diff --git a/src/build_helper/command_ext.rs b/src/build_helper/command_ext.rs new file mode 100644 index 0000000000000..316e9e2a6f6bf --- /dev/null +++ b/src/build_helper/command_ext.rs @@ -0,0 +1,122 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ffi::{OsStr, OsString}; +use std::io::Result; +use std::process; +use std::path::Path; + +// std::process::Command but with addition support for add arguments past +// the `--` when invoking `cargo rustc` +#[derive(Debug)] +pub struct Command { + cmd: process::Command, + deferred_args: Vec, +} + +impl Command { + + pub fn new>(program: S) -> Command { + Command { + cmd: process::Command::new(program), + deferred_args: vec![], + } + } + + pub fn from_std_command(cmd: process::Command) -> Command { + Command { + cmd, + deferred_args: vec![], + } + } + + pub fn arg>(&mut self, arg: S) -> &mut Self { + self.cmd.arg(arg); + self + } + + pub fn args(&mut self, args: I) -> &mut Command + where + I: IntoIterator, + S: AsRef, + { + self.cmd.args(args); + self + } + + pub fn deferred_arg>(&mut self, arg: S) -> &mut Self { + self.deferred_args.push(arg.as_ref().to_owned()); + self + } + + pub fn env(&mut self, key: K, val: V) -> &mut Self + where + K: AsRef, + V: AsRef, + { + self.cmd.env(key, val); + self + } + + pub fn envs(&mut self, vars: I) -> &mut Command + where + I: IntoIterator, + K: AsRef, + V: AsRef, + { + self.cmd.envs(vars); + self + } + + pub fn env_remove>(&mut self, key: K) -> &mut Self { + self.cmd.env_remove(key); + self + } + + pub fn env_clear(&mut self) -> &mut Command { + self.cmd.env_clear(); + self + } + + pub fn current_dir>(&mut self, dir: P) -> &mut Command { + self.cmd.current_dir(dir); + self + } + + pub fn stdin>(&mut self, cfg: T) -> &mut Command { + self.cmd.stdin(cfg); + self + } + + pub fn stdout>(&mut self, cfg: T) -> &mut Command { + self.cmd.stdout(cfg); + self + } + + pub fn stderr>(&mut self, cfg: T) -> &mut Command { + self.cmd.stderr(cfg); + self + } + + pub fn spawn(&mut self) -> Result { + self.cmd.args(self.deferred_args.clone().into_iter()); + self.cmd.spawn() + } + + pub fn output(&mut self) -> Result { + self.cmd.args(self.deferred_args.clone().into_iter()); + self.cmd.output() + } + + pub fn status(&mut self) -> Result { + self.cmd.args(self.deferred_args.clone().into_iter()); + self.cmd.status() + } +} diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 2f9953330f42c..549300642f65c 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -10,10 +10,14 @@ use std::fs::File; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::Stdio; use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, fs}; +pub mod command_ext; + +use command_ext::Command; + /// A helper macro to `unwrap` a result except also print out details like: /// /// * The file/line of the panic diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index 0aa46dc6d205f..638e9a2b9275e 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -15,8 +15,8 @@ extern crate cc; use std::env; use std::path::PathBuf; -use std::process::Command; use build_helper::{run, native_lib_boilerplate}; +use build_helper::command_ext::Command; fn main() { // FIXME: This is a hack to support building targets that don't diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 1619637b827df..f4b3ece8ab5d4 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -11,11 +11,11 @@ extern crate cc; extern crate build_helper; -use std::process::Command; use std::env; use std::path::{PathBuf, Path}; use build_helper::output; +use build_helper::command_ext::Command; fn detect_llvm_link() -> (&'static str, &'static str) { // Force the link mode we want, preferring static by default, but diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 6652ff98201a0..c6e8928ff07db 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -13,8 +13,8 @@ extern crate build_helper; use std::env; -use std::process::Command; use build_helper::{run, native_lib_boilerplate}; +use build_helper::command_ext::Command; fn main() { let target = env::var("TARGET").expect("TARGET was not set"); From a8b2da391cbbcab81a7957439578b727645008b0 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 May 2018 16:34:54 +0200 Subject: [PATCH 3/5] bootstrap: Allow for invoking *cargo rustc* --- src/bootstrap/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b75ffb1ec3d1c..5557d071e4895 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -658,7 +658,7 @@ impl<'a> Builder<'a> { if let Some(ref error_format) = self.config.rustc_error_format { cargo.env("RUSTC_ERROR_FORMAT", error_format); } - if cmd != "build" && cmd != "check" && want_rustdoc { + if cmd != "build" && cmd != "check" && cmd != "rustc" && want_rustdoc { cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.config.build))); } @@ -804,7 +804,7 @@ impl<'a> Builder<'a> { } } - if cmd == "build" && mode == Mode::Libstd + if (cmd == "build" || cmd == "rustc") && mode == Mode::Libstd && self.config.extended && compiler.is_final_stage(self) { cargo.env("RUSTC_SAVE_ANALYSIS", "api".to_string()); From b447ad736e6261085b527cab589a6ba27144ff51 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 May 2018 16:36:18 +0200 Subject: [PATCH 4/5] bootstrap: Allow to specify ranlib tool used when compiling C++ code. --- src/bootstrap/config.rs | 3 +++ src/bootstrap/lib.rs | 7 +++++++ src/bootstrap/native.rs | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9840682d1379b..5b705ceae942a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -161,6 +161,7 @@ pub struct Target { pub cc: Option, pub cxx: Option, pub ar: Option, + pub ranlib: Option, pub linker: Option, pub ndk: Option, pub crt_static: Option, @@ -321,6 +322,7 @@ struct TomlTarget { cc: Option, cxx: Option, ar: Option, + ranlib: Option, linker: Option, android_ndk: Option, crt_static: Option, @@ -569,6 +571,7 @@ impl Config { target.cc = cfg.cc.clone().map(PathBuf::from); target.cxx = cfg.cxx.clone().map(PathBuf::from); target.ar = cfg.ar.clone().map(PathBuf::from); + target.ranlib = cfg.ranlib.clone().map(PathBuf::from); target.linker = cfg.linker.clone().map(PathBuf::from); target.crt_static = cfg.crt_static.clone(); target.musl_root = cfg.musl_root.clone().map(PathBuf::from); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e59b6fdaba4f8..3e34eaed007fe 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -265,6 +265,7 @@ pub struct Build { cc: HashMap, cc::Tool>, cxx: HashMap, cc::Tool>, ar: HashMap, PathBuf>, + ranlib: HashMap, PathBuf>, // Misc crates: HashMap, Crate>, is_sudo: bool, @@ -366,6 +367,7 @@ impl Build { cc: HashMap::new(), cxx: HashMap::new(), ar: HashMap::new(), + ranlib: HashMap::new(), crates: HashMap::new(), lldb_version: None, lldb_python_dir: None, @@ -725,6 +727,11 @@ impl Build { self.ar.get(&target).map(|p| &**p) } + /// Returns the path to the `ranlib` utility for the target specified. + fn ranlib(&self, target: Interned) -> Option<&Path> { + self.ranlib.get(&target).map(|p| &**p) + } + /// Returns the path to the C++ compiler for the target specified. fn cxx(&self, target: Interned) -> Result<&Path, String> { match self.cxx.get(&target) { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 8e4020e727868..9bee8aeabce74 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -352,6 +352,14 @@ fn configure_cmake(builder: &Builder, } } + if let Some(ranlib) = builder.ranlib(target) { + if ranlib.is_absolute() { + // LLVM build breaks if `CMAKE_RANLIB` is a relative path, for some reason it + // tries to resolve this path in the LLVM build directory. + cfg.define("CMAKE_RANLIB", sanitize_cc(ranlib)); + } + } + if env::var_os("SCCACHE_ERROR_LOG").is_some() { cfg.env("RUST_LOG", "sccache=warn"); } From 55aaf6301132d1136af634b9cc315a7d675ea22c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 May 2018 16:38:40 +0200 Subject: [PATCH 5/5] bootstrap: Build LLVM with ThinLTO on Linux64. --- src/bootstrap/compile.rs | 13 ++++++++++--- src/bootstrap/config.rs | 3 +++ src/bootstrap/native.rs | 5 +++++ src/ci/docker/dist-x86_64-linux/Dockerfile | 4 +++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index bbad27d28cc5c..a6395cafa5e47 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -35,7 +35,6 @@ use util::{exe, libdir, is_dylib, CiEnv}; use {Compiler, Mode}; use native; use tool; - use cache::{INTERNER, Interned}; use builder::{Step, RunConfig, ShouldRun, Builder}; @@ -635,20 +634,28 @@ impl Step for CodegenBackend { return; } - let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build"); + let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "rustc"); let mut features = builder.rustc_features().to_string(); cargo.arg("--manifest-path") .arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml")); rustc_cargo_env(builder, &mut cargo); features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend); + cargo.arg("--features").arg(features); let tmp_stamp = builder.cargo_out(compiler, Mode::Librustc, target) .join(".tmp.stamp"); + if builder.config.llvm_thin_lto { + cargo.deferred_arg("--") + .deferred_arg("-Clink-arg=-fuse-ld=lld") + .deferred_arg("-Clink-arg=-flto=thin") + .deferred_arg("-Clink-arg=-O2"); + } + let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage)); let files = run_cargo(builder, - cargo.arg("--features").arg(features), + &mut cargo, &tmp_stamp, false); if builder.config.dry_run { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 5b705ceae942a..963d250c6b854 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -79,6 +79,7 @@ pub struct Config { pub llvm_assertions: bool, pub llvm_optimize: bool, pub llvm_release_debuginfo: bool, + pub llvm_thin_lto: bool, pub llvm_version_check: bool, pub llvm_static_stdcpp: bool, pub llvm_link_shared: bool, @@ -246,6 +247,7 @@ struct Llvm { assertions: Option, optimize: Option, release_debuginfo: Option, + thin_lto: Option, version_check: Option, static_libstdcpp: Option, targets: Option, @@ -501,6 +503,7 @@ impl Config { llvm_assertions = llvm.assertions; set(&mut config.llvm_optimize, llvm.optimize); set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); + set(&mut config.llvm_thin_lto, llvm.thin_lto); set(&mut config.llvm_version_check, llvm.version_check); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); set(&mut config.llvm_link_shared, llvm.link_shared); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 9bee8aeabce74..10725f8db5176 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -154,6 +154,11 @@ impl Step for Llvm { .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) .define("LLVM_DEFAULT_TARGET_TRIPLE", target); + if builder.config.llvm_thin_lto { + cfg.define("LLVM_ENABLE_LTO", "Thin") + .define("LLVM_ENABLE_LLD", "ON"); + } + // By default, LLVM will automatically find OCaml and, if it finds it, // install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults // to /usr/bin/ocaml. diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index 5726fab7524ae..b21b74d6eb015 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -93,7 +93,9 @@ ENV RUST_CONFIGURE_ARGS \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs \ - --set target.x86_64-unknown-linux-gnu.linker=clang + --set target.x86_64-unknown-linux-gnu.linker=clang \ + --set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \ + --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang