Skip to content

Commit bb88c98

Browse files
committed
Add lldb to the build
This optionally adds lldb (and clang, which it needs) to the build. Because rust uses LLVM 7, and because clang 7 is not yet released, a recent git master version of clang is used. The lldb that is used includes the Rust plugin. lldb is only built when asked for, or when doing a nightly build on macOS. Only macOS is done for now due to difficulties with the Python dependency.
1 parent 11f812a commit bb88c98

12 files changed

+182
-18
lines changed

.gitmodules

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,11 @@
5656
[submodule "src/libbacktrace"]
5757
path = src/libbacktrace
5858
url = https://github.com/rust-lang-nursery/libbacktrace
59+
[submodule "src/lldb"]
60+
path = src/lldb
61+
url = https://github.com/rust-lang-nursery/lldb/
62+
branch = rust-release-70
63+
[submodule "src/clang"]
64+
path = src/clang
65+
url = https://github.com/rust-lang-nursery/clang/
66+
branch = master

config.toml.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@
354354
# sysroot.
355355
#llvm-tools = false
356356

357+
# Indicates whether LLDB will be made available in the sysroot.
358+
# This is only built if LLVM is also being built.
359+
#lldb = false
360+
357361
# Whether to deny warnings in crates
358362
#deny-warnings = true
359363

src/Cargo.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ name = "installer"
10111011
version = "0.0.0"
10121012
dependencies = [
10131013
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
1014-
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
1014+
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
10151015
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
10161016
"lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
10171017
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",

src/bootstrap/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ impl<'a> Builder<'a> {
461461
dist::Rustfmt,
462462
dist::Clippy,
463463
dist::LlvmTools,
464+
dist::Lldb,
464465
dist::Extended,
465466
dist::HashSign
466467
),

src/bootstrap/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pub struct Config {
8787
pub llvm_link_jobs: Option<u32>,
8888

8989
pub lld_enabled: bool,
90+
pub lldb_enabled: bool,
9091
pub llvm_tools_enabled: bool,
9192

9293
// rust codegen options
@@ -310,6 +311,7 @@ struct Rust {
310311
codegen_backends_dir: Option<String>,
311312
wasm_syscall: Option<bool>,
312313
lld: Option<bool>,
314+
lldb: Option<bool>,
313315
llvm_tools: Option<bool>,
314316
deny_warnings: Option<bool>,
315317
backtrace_on_ice: Option<bool>,
@@ -538,6 +540,7 @@ impl Config {
538540
}
539541
set(&mut config.wasm_syscall, rust.wasm_syscall);
540542
set(&mut config.lld_enabled, rust.lld);
543+
set(&mut config.lldb_enabled, rust.lldb);
541544
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
542545
config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
543546
config.rustc_default_linker = rust.default_linker.clone();

src/bootstrap/configure.py

Lines changed: 1 addition & 0 deletions
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.lldb', True)
338339
set('rust.llvm-tools', True)
339340
set('build.extended', True)
340341
elif option.name == 'option-checking':

src/bootstrap/dist.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
4747
format!("{}-{}", component, builder.rustfmt_package_vers())
4848
} else if component == "llvm-tools" {
4949
format!("{}-{}", component, builder.llvm_tools_package_vers())
50+
} else if component == "lldb" {
51+
format!("{}-{}", component, builder.lldb_package_vers())
5052
} else {
5153
assert!(component.starts_with("rust"));
5254
format!("{}-{}", component, builder.rust_package_vers())
@@ -1396,6 +1398,7 @@ impl Step for Extended {
13961398
let rls_installer = builder.ensure(Rls { stage, target });
13971399
let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
13981400
let clippy_installer = builder.ensure(Clippy { stage, target });
1401+
let lldb_installer = builder.ensure(Lldb { target });
13991402
let mingw_installer = builder.ensure(Mingw { host: target });
14001403
let analysis_installer = builder.ensure(Analysis {
14011404
compiler: builder.compiler(stage, self.host),
@@ -1435,6 +1438,7 @@ impl Step for Extended {
14351438
tarballs.extend(clippy_installer.clone());
14361439
tarballs.extend(rustfmt_installer.clone());
14371440
tarballs.extend(llvm_tools_installer.clone());
1441+
tarballs.extend(lldb_installer.clone());
14381442
tarballs.push(analysis_installer);
14391443
tarballs.push(std_installer);
14401444
if builder.config.docs {
@@ -1869,6 +1873,7 @@ impl Step for HashSign {
18691873
cmd.arg(builder.package_vers(&builder.release_num("clippy")));
18701874
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
18711875
cmd.arg(builder.llvm_tools_package_vers());
1876+
cmd.arg(builder.lldb_package_vers());
18721877
cmd.arg(addr);
18731878

18741879
builder.create_dir(&distdir(builder));
@@ -1963,3 +1968,112 @@ impl Step for LlvmTools {
19631968
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
19641969
}
19651970
}
1971+
1972+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1973+
pub struct Lldb {
1974+
pub target: Interned<String>,
1975+
}
1976+
1977+
impl Step for Lldb {
1978+
type Output = Option<PathBuf>;
1979+
const ONLY_HOSTS: bool = true;
1980+
const DEFAULT: bool = true;
1981+
1982+
fn should_run(run: ShouldRun) -> ShouldRun {
1983+
run.path("src/lldb")
1984+
}
1985+
1986+
fn make_run(run: RunConfig) {
1987+
run.builder.ensure(Lldb {
1988+
target: run.target,
1989+
});
1990+
}
1991+
1992+
fn run(self, builder: &Builder) -> Option<PathBuf> {
1993+
let target = self.target;
1994+
1995+
builder.info(&format!("Dist Lldb ({})", target));
1996+
let src = builder.src.join("src/lldb");
1997+
let name = pkgname(builder, "lldb");
1998+
1999+
let tmp = tmpdir(builder);
2000+
let image = tmp.join("lldb-image");
2001+
drop(fs::remove_dir_all(&image));
2002+
2003+
// Prepare the image directory
2004+
let bindir = builder
2005+
.llvm_out(target)
2006+
.join("bin");
2007+
let dst = image.join("bin");
2008+
t!(fs::create_dir_all(&dst));
2009+
for program in &["lldb", "lldb-argdumper", "lldb-mi", "lldb-server"] {
2010+
let exe = bindir.join(exe(program, &target));
2011+
builder.install(&exe, &dst, 0o755);
2012+
}
2013+
2014+
// The libraries.
2015+
let libdir = builder.llvm_out(target).join("lib");
2016+
let dst = image.join("lib");
2017+
t!(fs::create_dir_all(&dst));
2018+
for entry in t!(fs::read_dir(&libdir)) {
2019+
// let entry = t!(entry);
2020+
let entry = entry.unwrap();
2021+
if let Ok(name) = entry.file_name().into_string() {
2022+
if name.starts_with("liblldb.") && !name.ends_with(".a") {
2023+
if t!(entry.file_type()).is_symlink() {
2024+
builder.copy_to_folder(&entry.path(), &dst);
2025+
} else {
2026+
builder.install(&entry.path(), &dst, 0o755);
2027+
}
2028+
}
2029+
}
2030+
}
2031+
2032+
// The lldb scripts might be installed in lib/python$version
2033+
// or in lib64/python$version. If lib64 exists, use it;
2034+
// otherwise lib.
2035+
let libdir = builder.llvm_out(target).join("lib64");
2036+
let (libdir, libdir_name) = if libdir.exists() {
2037+
(libdir, "lib64")
2038+
} else {
2039+
(builder.llvm_out(target).join("lib"), "lib")
2040+
};
2041+
for entry in t!(fs::read_dir(&libdir)) {
2042+
let entry = t!(entry);
2043+
if let Ok(name) = entry.file_name().into_string() {
2044+
if name.starts_with("python") {
2045+
let dst = image.join(libdir_name)
2046+
.join(entry.file_name());
2047+
t!(fs::create_dir_all(&dst));
2048+
builder.cp_r(&entry.path(), &dst);
2049+
break;
2050+
}
2051+
}
2052+
}
2053+
2054+
// Prepare the overlay
2055+
let overlay = tmp.join("lldb-overlay");
2056+
drop(fs::remove_dir_all(&overlay));
2057+
builder.create_dir(&overlay);
2058+
builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
2059+
builder.create(&overlay.join("version"), &builder.lldb_vers());
2060+
2061+
// Generate the installer tarball
2062+
let mut cmd = rust_installer(builder);
2063+
cmd.arg("generate")
2064+
.arg("--product-name=Rust")
2065+
.arg("--rel-manifest-dir=rustlib")
2066+
.arg("--success-message=lldb-installed.")
2067+
.arg("--image-dir").arg(&image)
2068+
.arg("--work-dir").arg(&tmpdir(builder))
2069+
.arg("--output-dir").arg(&distdir(builder))
2070+
.arg("--non-installed-overlay").arg(&overlay)
2071+
.arg(format!("--package-name={}-{}", name, target))
2072+
.arg("--legacy-manifest-dirs=rustlib,cargo")
2073+
.arg("--component-name=lldb-preview");
2074+
2075+
2076+
builder.run(&mut cmd);
2077+
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
2078+
}
2079+
}

src/bootstrap/lib.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ use std::process::{self, Command};
151151
use std::slice;
152152
use std::str;
153153

154+
#[cfg(unix)]
155+
use std::os::unix::fs::symlink as symlink_file;
156+
#[cfg(windows)]
157+
use std::os::windows::fs::symlink_file;
158+
154159
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime};
155160
use filetime::FileTime;
156161

@@ -1005,6 +1010,14 @@ impl Build {
10051010
self.rust_version()
10061011
}
10071012

1013+
fn lldb_package_vers(&self) -> String {
1014+
self.package_vers(&self.rust_version())
1015+
}
1016+
1017+
fn lldb_vers(&self) -> String {
1018+
self.rust_version()
1019+
}
1020+
10081021
/// Returns the `version` string associated with this compiler for Rust
10091022
/// itself.
10101023
///
@@ -1123,20 +1136,24 @@ impl Build {
11231136
pub fn copy(&self, src: &Path, dst: &Path) {
11241137
if self.config.dry_run { return; }
11251138
let _ = fs::remove_file(&dst);
1126-
// Attempt to "easy copy" by creating a hard link (symlinks don't work on
1127-
// windows), but if that fails just fall back to a slow `copy` operation.
1128-
if let Ok(()) = fs::hard_link(src, dst) {
1129-
return
1130-
}
1131-
if let Err(e) = fs::copy(src, dst) {
1132-
panic!("failed to copy `{}` to `{}`: {}", src.display(),
1133-
dst.display(), e)
1139+
let metadata = t!(src.symlink_metadata());
1140+
if metadata.file_type().is_symlink() {
1141+
let link = t!(fs::read_link(src));
1142+
t!(symlink_file(link, dst));
1143+
} else if let Ok(()) = fs::hard_link(src, dst) {
1144+
// Attempt to "easy copy" by creating a hard link
1145+
// (symlinks don't work on windows), but if that fails
1146+
// just fall back to a slow `copy` operation.
1147+
} else {
1148+
if let Err(e) = fs::copy(src, dst) {
1149+
panic!("failed to copy `{}` to `{}`: {}", src.display(),
1150+
dst.display(), e)
1151+
}
1152+
t!(fs::set_permissions(dst, metadata.permissions()));
1153+
let atime = FileTime::from_last_access_time(&metadata);
1154+
let mtime = FileTime::from_last_modification_time(&metadata);
1155+
t!(filetime::set_file_times(dst, atime, mtime));
11341156
}
1135-
let metadata = t!(src.metadata());
1136-
t!(fs::set_permissions(dst, metadata.permissions()));
1137-
let atime = FileTime::from_last_access_time(&metadata);
1138-
let mtime = FileTime::from_last_modification_time(&metadata);
1139-
t!(filetime::set_file_times(dst, atime, mtime));
11401157
}
11411158

11421159
/// Search-and-replaces within a file. (Not maximally efficiently: allocates a

src/bootstrap/native.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ impl Step for Llvm {
149149
.define("WITH_POLLY", "OFF")
150150
.define("LLVM_ENABLE_TERMINFO", "OFF")
151151
.define("LLVM_ENABLE_LIBEDIT", "OFF")
152-
.define("LLVM_ENABLE_LIBXML2", "OFF")
153152
.define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
154153
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
155154
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
@@ -163,19 +162,28 @@ impl Step for Llvm {
163162
cfg.define("LLVM_OCAML_INSTALL_PATH",
164163
env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into()));
165164

165+
// Build clang and lldb if asked, or if doing a macOS nightly
166+
// build. LLVM_ENABLE_PROJECTS allows them to be checked out
167+
// parallel to src/llvm, and makes conditionally building them
168+
// simpler.
169+
let want_lldb = builder.config.lldb_enabled ||
170+
(target.contains("apple-darwin") &&
171+
builder.config.channel == "nightly");
172+
166173
// This setting makes the LLVM tools link to the dynamic LLVM library,
167174
// which saves both memory during parallel links and overall disk space
168175
// for the tools. We don't distribute any of those tools, so this is
169176
// just a local concern. However, it doesn't work well everywhere.
170177
//
171178
// If we are shipping llvm tools then we statically link them LLVM
172179
if (target.contains("linux-gnu") || target.contains("apple-darwin")) &&
173-
!builder.config.llvm_tools_enabled {
180+
!builder.config.llvm_tools_enabled &&
181+
!want_lldb {
174182
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
175183
}
176184

177185
// For distribution we want the LLVM tools to be *statically* linked to libstdc++
178-
if builder.config.llvm_tools_enabled {
186+
if builder.config.llvm_tools_enabled || want_lldb {
179187
if !target.contains("windows") {
180188
if target.contains("apple") {
181189
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
@@ -196,6 +204,12 @@ impl Step for Llvm {
196204
cfg.define("LLVM_BUILD_32_BITS", "ON");
197205
}
198206

207+
if want_lldb {
208+
cfg.define("LLVM_ENABLE_PROJECTS", "clang;lldb");
209+
} else {
210+
cfg.define("LLVM_ENABLE_LIBXML2", "OFF");
211+
}
212+
199213
if let Some(num_linkers) = builder.config.llvm_link_jobs {
200214
if num_linkers > 0 {
201215
cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());

src/clang

Submodule clang added at 6fda594

src/lldb

Submodule lldb added at 3dbe998

0 commit comments

Comments
 (0)