Skip to content

Commit e11c95d

Browse files
committedJun 21, 2018
Auto merge of #50336 - japaric:llvm-tools, r=Mark-Simulacrum
ship LLVM tools with the toolchain this PR adds llvm-{nm,objcopy,objdump,size} to the rustc sysroot (right next to LLD) this slightly increases the size of the rustc component. I measured these numbers on x86_64 Linux: - rustc-1.27.0-dev-x86_64-unknown-linux-gnu.tar.gz 180M -> 193M (+7%) - rustc-1.27.0-dev-x86_64-unknown-linux-gnu.tar.xz 129M -> 137M (+6%) r? @alexcrichton cc #49584
2 parents 95979dc + 9a96876 commit e11c95d

File tree

7 files changed

+134
-4
lines changed

7 files changed

+134
-4
lines changed
 

‎config.toml.example

+4
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@
350350
# rustc to execute.
351351
#lld = false
352352

353+
# Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
354+
# sysroot.
355+
#llvm-tools = false
356+
353357
# Whether to deny warnings in crates
354358
#deny-warnings = true
355359

‎src/bootstrap/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ impl<'a> Builder<'a> {
453453
dist::Cargo,
454454
dist::Rls,
455455
dist::Rustfmt,
456+
dist::LlvmTools,
456457
dist::Extended,
457458
dist::HashSign
458459
),

‎src/bootstrap/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub struct Config {
8888
pub llvm_link_jobs: Option<u32>,
8989

9090
pub lld_enabled: bool,
91+
pub llvm_tools_enabled: bool,
9192

9293
// rust codegen options
9394
pub rust_optimize: bool,
@@ -309,6 +310,7 @@ struct Rust {
309310
codegen_backends_dir: Option<String>,
310311
wasm_syscall: Option<bool>,
311312
lld: Option<bool>,
313+
llvm_tools: Option<bool>,
312314
deny_warnings: Option<bool>,
313315
backtrace_on_ice: Option<bool>,
314316
}
@@ -536,6 +538,7 @@ impl Config {
536538
}
537539
set(&mut config.wasm_syscall, rust.wasm_syscall);
538540
set(&mut config.lld_enabled, rust.lld);
541+
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
539542
config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
540543
config.rustc_default_linker = rust.default_linker.clone();
541544
config.musl_root = rust.musl_root.clone().map(PathBuf::from);

‎src/bootstrap/configure.py

+1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ def set(key, value):
335335
elif option.name == 'full-tools':
336336
set('rust.codegen-backends', ['llvm', 'emscripten'])
337337
set('rust.lld', True)
338+
set('rust.llvm-tools', True)
338339
set('build.extended', True)
339340
elif option.name == 'option-checking':
340341
# this was handled above

‎src/bootstrap/dist.rs

+80-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::process::{Command, Stdio};
2626

2727
use build_helper::output;
2828

29-
use {Compiler, Mode};
29+
use {Compiler, Mode, LLVM_TOOLS};
3030
use channel;
3131
use util::{libdir, is_dylib, exe};
3232
use builder::{Builder, RunConfig, ShouldRun, Step};
@@ -43,6 +43,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
4343
format!("{}-{}", component, builder.rls_package_vers())
4444
} else if component == "rustfmt" {
4545
format!("{}-{}", component, builder.rustfmt_package_vers())
46+
} else if component == "llvm-tools" {
47+
format!("{}-{}", component, builder.llvm_tools_vers())
4648
} else {
4749
assert!(component.starts_with("rust"));
4850
format!("{}-{}", component, builder.rust_package_vers())
@@ -394,7 +396,7 @@ impl Step for Rustc {
394396
let compiler = self.compiler;
395397
let host = self.compiler.host;
396398

397-
builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, compiler.host));
399+
builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
398400
let name = pkgname(builder, "rustc");
399401
let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
400402
let _ = fs::remove_dir_all(&image);
@@ -1738,6 +1740,7 @@ impl Step for HashSign {
17381740
cmd.arg(builder.package_vers(&builder.release_num("cargo")));
17391741
cmd.arg(builder.package_vers(&builder.release_num("rls")));
17401742
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
1743+
cmd.arg(builder.llvm_tools_vers());
17411744
cmd.arg(addr);
17421745

17431746
builder.create_dir(&distdir(builder));
@@ -1748,3 +1751,78 @@ impl Step for HashSign {
17481751
assert!(status.success());
17491752
}
17501753
}
1754+
1755+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1756+
pub struct LlvmTools {
1757+
pub stage: u32,
1758+
pub compiler: Compiler,
1759+
pub target: Interned<String>,
1760+
}
1761+
1762+
impl Step for LlvmTools {
1763+
type Output = Option<PathBuf>;
1764+
const ONLY_HOSTS: bool = true;
1765+
1766+
fn should_run(run: ShouldRun) -> ShouldRun {
1767+
run.path("llvm-tools")
1768+
}
1769+
1770+
fn make_run(run: RunConfig) {
1771+
run.builder.ensure(LlvmTools {
1772+
stage: run.builder.top_stage,
1773+
compiler: run.builder.compiler(run.builder.top_stage, run.target),
1774+
target: run.target,
1775+
});
1776+
}
1777+
1778+
fn run(self, builder: &Builder) -> Option<PathBuf> {
1779+
let compiler = self.compiler;
1780+
let host = compiler.host;
1781+
1782+
let stage = self.stage;
1783+
assert!(builder.config.extended);
1784+
1785+
builder.info(&format!("Dist LlvmTools stage{} ({})", stage, host));
1786+
let src = builder.src.join("src/llvm");
1787+
let name = pkgname(builder, "llvm-tools");
1788+
1789+
let tmp = tmpdir(builder);
1790+
let image = tmp.join("llvm-tools-image");
1791+
drop(fs::remove_dir_all(&image));
1792+
t!(fs::create_dir_all(&image.join("bin")));
1793+
1794+
// Prepare the image directory
1795+
for tool in LLVM_TOOLS {
1796+
let exe = builder
1797+
.llvm_out(host)
1798+
.join("bin")
1799+
.join(exe(tool, &compiler.host));
1800+
builder.install(&exe, &image.join("bin"), 0o755);
1801+
}
1802+
1803+
// Prepare the overlay
1804+
let overlay = tmp.join("llvm-tools-overlay");
1805+
drop(fs::remove_dir_all(&overlay));
1806+
builder.create_dir(&overlay);
1807+
builder.install(&src.join("README.txt"), &overlay, 0o644);
1808+
builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
1809+
1810+
// Generate the installer tarball
1811+
let mut cmd = rust_installer(builder);
1812+
cmd.arg("generate")
1813+
.arg("--product-name=Rust")
1814+
.arg("--rel-manifest-dir=rustlib")
1815+
.arg("--success-message=llvm-tools-installed.")
1816+
.arg("--image-dir").arg(&image)
1817+
.arg("--work-dir").arg(&tmpdir(builder))
1818+
.arg("--output-dir").arg(&distdir(builder))
1819+
.arg("--non-installed-overlay").arg(&overlay)
1820+
.arg(format!("--package-name={}-{}", name, host))
1821+
.arg("--legacy-manifest-dirs=rustlib,cargo")
1822+
.arg("--component-name=llvm-tools");
1823+
1824+
1825+
builder.run(&mut cmd);
1826+
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host)))
1827+
}
1828+
}

‎src/bootstrap/lib.rs

+29
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ use flags::Subcommand;
199199
use cache::{Interned, INTERNER};
200200
use toolstate::ToolState;
201201

202+
const LLVM_TOOLS: &[&str] = &[
203+
"llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility
204+
"llvm-objcopy", // used to transform ELFs into binary format which flashing tools consume
205+
"llvm-objdump", // used to disassemble programs
206+
"llvm-profdata", // used to inspect and merge files generated by profiles
207+
"llvm-size", // prints the size of the linker sections of a program
208+
];
209+
202210
/// A structure representing a Rust compiler.
203211
///
204212
/// Each compiler has a `stage` that it is associated with and a `host` that
@@ -965,6 +973,27 @@ impl Build {
965973
self.package_vers(&self.release_num("rustfmt"))
966974
}
967975

976+
fn llvm_tools_vers(&self) -> String {
977+
// japaric: should we use LLVM version here?
978+
// let stdout = build_helper::output(
979+
// Command::new(self.llvm_out(self.config.build).join("build/bin/llvm-size"))
980+
// .arg("--version"),
981+
// );
982+
983+
// for line in stdout.lines() {
984+
// if line.contains("LLVM version") {
985+
// if let Some(vers) = line.split_whitespace().nth(2) {
986+
// return vers.to_string();
987+
// }
988+
// }
989+
// }
990+
991+
// panic!("The output of $LLVM_TOOL has changed; \
992+
// please fix `bootstrap::Build.llvm_tools_vers`");
993+
994+
self.rust_version()
995+
}
996+
968997
/// Returns the `version` string associated with this compiler for Rust
969998
/// itself.
970999
///

‎src/bootstrap/native.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,22 @@ impl Step for Llvm {
167167
// which saves both memory during parallel links and overall disk space
168168
// for the tools. We don't distribute any of those tools, so this is
169169
// just a local concern. However, it doesn't work well everywhere.
170-
if target.contains("linux-gnu") || target.contains("apple-darwin") {
171-
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
170+
//
171+
// If we are shipping llvm tools then we statically link them LLVM
172+
if (target.contains("linux-gnu") || target.contains("apple-darwin")) &&
173+
!builder.config.llvm_tools_enabled {
174+
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
175+
}
176+
177+
// For distribution we want the LLVM tools to be *statically* linked to libstdc++
178+
if builder.config.llvm_tools_enabled {
179+
if !target.contains("windows") {
180+
if target.contains("apple") {
181+
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
182+
} else {
183+
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-Wl,-Bsymbolic -static-libstdc++");
184+
}
185+
}
172186
}
173187

174188
if target.contains("msvc") {

0 commit comments

Comments
 (0)
Please sign in to comment.