Skip to content

Commit afd0a2f

Browse files
committed
Auto merge of #52716 - tromey:rustup-lldb, r=alexcrichton
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.
2 parents fa23350 + 6e3a4f4 commit afd0a2f

File tree

16 files changed

+225
-23
lines changed

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)