Skip to content

Commit 6e3a4f4

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 5bb2094 commit 6e3a4f4

16 files changed

+225
-23
lines changed

.gitmodules

+8
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/tools/lldb"]
60+
path = src/tools/lldb
61+
url = https://github.com/rust-lang-nursery/lldb/
62+
branch = rust-release-70
63+
[submodule "src/tools/clang"]
64+
path = src/tools/clang
65+
url = https://github.com/rust-lang-nursery/clang/
66+
branch = release_70

.travis.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ matrix:
3030

3131
- env: >
3232
RUST_CHECK_TARGET=dist
33-
RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler"
33+
RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --enable-lldb"
3434
SRC=.
3535
DEPLOY_ALT=1
3636
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -85,7 +85,7 @@ matrix:
8585
# OSX 10.7 and `xcode7` is the latest Xcode able to compile LLVM for 10.7.
8686
- env: >
8787
RUST_CHECK_TARGET=dist
88-
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler"
88+
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb"
8989
SRC=.
9090
DEPLOY=1
9191
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -99,7 +99,7 @@ matrix:
9999
100100
- env: >
101101
RUST_CHECK_TARGET=dist
102-
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler"
102+
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb"
103103
SRC=.
104104
DEPLOY=1
105105
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -233,7 +233,8 @@ install:
233233
osx)
234234
if [[ "$RUST_CHECK_TARGET" == dist ]]; then
235235
travis_retry brew update &&
236-
travis_retry brew install xz;
236+
travis_retry brew install xz &&
237+
travis_retry brew install swig;
237238
fi &&
238239
travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin &&
239240
chmod +x /usr/local/bin/sccache &&

config.toml.example

+4
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ name = "installer"
10151015
version = "0.0.0"
10161016
dependencies = [
10171017
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
1018-
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
1018+
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
10191019
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
10201020
"lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
10211021
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",

src/bootstrap/bootstrap.py

+4
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,10 @@ def update_submodules(self):
721721
config = self.get_toml('lld')
722722
if config is None or config == 'false':
723723
continue
724+
if module.endswith("lldb") or module.endswith("clang"):
725+
config = self.get_toml('lldb')
726+
if config is None or config == 'false':
727+
continue
724728
check = self.check_submodule(module, slow_submodules)
725729
filtered_submodules.append((module, check))
726730
submodules_names.append(module)

src/bootstrap/builder.rs

+1
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

+3
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def v(*args):
6868
o("profiler", "build.profiler", "build the profiler runtime")
6969
o("emscripten", None, "compile the emscripten backend as well as LLVM")
7070
o("full-tools", None, "enable all tools")
71+
o("lldb", "rust.lldb", "build lldb")
7172

7273
# Optimization and debugging options. These may be overridden by the release
7374
# channel, etc.
@@ -350,7 +351,7 @@ def set(key, value):
350351
# all the various comments and whatnot.
351352
#
352353
# Note that the `target` section is handled separately as we'll duplicate it
353-
# per configure dtarget, so there's a bit of special handling for that here.
354+
# per configured target, so there's a bit of special handling for that here.
354355
sections = {}
355356
cur_section = None
356357
sections[None] = []

src/bootstrap/dist.rs

+123
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,121 @@ 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/tools/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+
if builder.config.dry_run {
1996+
return None;
1997+
}
1998+
1999+
let bindir = builder
2000+
.llvm_out(target)
2001+
.join("bin");
2002+
let lldb_exe = bindir.join(exe("lldb", &target));
2003+
if !lldb_exe.exists() {
2004+
return None;
2005+
}
2006+
2007+
builder.info(&format!("Dist Lldb ({})", target));
2008+
let src = builder.src.join("src/tools/lldb");
2009+
let name = pkgname(builder, "lldb");
2010+
2011+
let tmp = tmpdir(builder);
2012+
let image = tmp.join("lldb-image");
2013+
drop(fs::remove_dir_all(&image));
2014+
2015+
// Prepare the image directory
2016+
let dst = image.join("bin");
2017+
t!(fs::create_dir_all(&dst));
2018+
for program in &["lldb", "lldb-argdumper", "lldb-mi", "lldb-server"] {
2019+
let exe = bindir.join(exe(program, &target));
2020+
builder.install(&exe, &dst, 0o755);
2021+
}
2022+
2023+
// The libraries.
2024+
let libdir = builder.llvm_out(target).join("lib");
2025+
let dst = image.join("lib");
2026+
t!(fs::create_dir_all(&dst));
2027+
for entry in t!(fs::read_dir(&libdir)) {
2028+
// let entry = t!(entry);
2029+
let entry = entry.unwrap();
2030+
if let Ok(name) = entry.file_name().into_string() {
2031+
if name.starts_with("liblldb.") && !name.ends_with(".a") {
2032+
if t!(entry.file_type()).is_symlink() {
2033+
builder.copy_to_folder(&entry.path(), &dst);
2034+
} else {
2035+
builder.install(&entry.path(), &dst, 0o755);
2036+
}
2037+
}
2038+
}
2039+
}
2040+
2041+
// The lldb scripts might be installed in lib/python$version
2042+
// or in lib64/python$version. If lib64 exists, use it;
2043+
// otherwise lib.
2044+
let libdir = builder.llvm_out(target).join("lib64");
2045+
let (libdir, libdir_name) = if libdir.exists() {
2046+
(libdir, "lib64")
2047+
} else {
2048+
(builder.llvm_out(target).join("lib"), "lib")
2049+
};
2050+
for entry in t!(fs::read_dir(&libdir)) {
2051+
let entry = t!(entry);
2052+
if let Ok(name) = entry.file_name().into_string() {
2053+
if name.starts_with("python") {
2054+
let dst = image.join(libdir_name)
2055+
.join(entry.file_name());
2056+
t!(fs::create_dir_all(&dst));
2057+
builder.cp_r(&entry.path(), &dst);
2058+
break;
2059+
}
2060+
}
2061+
}
2062+
2063+
// Prepare the overlay
2064+
let overlay = tmp.join("lldb-overlay");
2065+
drop(fs::remove_dir_all(&overlay));
2066+
builder.create_dir(&overlay);
2067+
builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
2068+
builder.create(&overlay.join("version"), &builder.lldb_vers());
2069+
2070+
// Generate the installer tarball
2071+
let mut cmd = rust_installer(builder);
2072+
cmd.arg("generate")
2073+
.arg("--product-name=Rust")
2074+
.arg("--rel-manifest-dir=rustlib")
2075+
.arg("--success-message=lldb-installed.")
2076+
.arg("--image-dir").arg(&image)
2077+
.arg("--work-dir").arg(&tmpdir(builder))
2078+
.arg("--output-dir").arg(&distdir(builder))
2079+
.arg("--non-installed-overlay").arg(&overlay)
2080+
.arg(format!("--package-name={}-{}", name, target))
2081+
.arg("--legacy-manifest-dirs=rustlib,cargo")
2082+
.arg("--component-name=lldb-preview");
2083+
2084+
2085+
builder.run(&mut cmd);
2086+
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
2087+
}
2088+
}

src/bootstrap/lib.rs

+30-13
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

+16-3
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,22 @@ 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+
let want_lldb = builder.config.lldb_enabled && !self.emscripten;
166+
166167
// This setting makes the LLVM tools link to the dynamic LLVM library,
167168
// which saves both memory during parallel links and overall disk space
168169
// for the tools. We don't distribute any of those tools, so this is
169170
// just a local concern. However, it doesn't work well everywhere.
170171
//
171172
// If we are shipping llvm tools then we statically link them LLVM
172173
if (target.contains("linux-gnu") || target.contains("apple-darwin")) &&
173-
!builder.config.llvm_tools_enabled {
174+
!builder.config.llvm_tools_enabled &&
175+
!want_lldb {
174176
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
175177
}
176178

177179
// For distribution we want the LLVM tools to be *statically* linked to libstdc++
178-
if builder.config.llvm_tools_enabled {
180+
if builder.config.llvm_tools_enabled || want_lldb {
179181
if !target.contains("windows") {
180182
if target.contains("apple") {
181183
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
@@ -196,6 +198,17 @@ impl Step for Llvm {
196198
cfg.define("LLVM_BUILD_32_BITS", "ON");
197199
}
198200

201+
if want_lldb {
202+
cfg.define("LLVM_EXTERNAL_CLANG_SOURCE_DIR", builder.src.join("src/tools/clang"));
203+
cfg.define("LLVM_EXTERNAL_LLDB_SOURCE_DIR", builder.src.join("src/tools/lldb"));
204+
// For the time being, disable code signing.
205+
cfg.define("LLDB_CODESIGN_IDENTITY", "");
206+
} else {
207+
// LLDB requires libxml2; but otherwise we want it to be disabled.
208+
// See https://github.com/rust-lang/rust/pull/50104
209+
cfg.define("LLVM_ENABLE_LIBXML2", "OFF");
210+
}
211+
199212
if let Some(num_linkers) = builder.config.llvm_link_jobs {
200213
if num_linkers > 0 {
201214
cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());

0 commit comments

Comments
 (0)