Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Auto merge of #56990 - tromey:build-gdb, r=<try>
Add gdb to the build

This optionally adds gdb to the Rust build, allowing gdb to be
installed via rustup.  This makes it simpler to make debuginfo
changes, as gdb updates can now be shipped immediately.

If gdb is not checked out, nothing changes.

The build is perhaps a bit chatty, as gdb's "make" and "make install"
are run each time, even if they do nothing.

rust-gdb is modified to prefer the gdb installed by rustup.  This is
analogous to what was done for rust-lldb.

The built gdb requires Python 2.7 as a shared library (other
dependencies are statically linked).  This is a
least-common-denominator Python that is widely available and stable;
dynamic linking is used to avoid breaking existing gdb Python code
that might load shared libraries that themselves require a dynamic
libpython.  To avoid problems here, a small wrapper program is used
that attemps to dlopen libpython; with failures being reported to the
user in an intelligible way.

Two of the Linux dist builds are updated to build gdb.  More could be
added if need be.

If gdb is built as part of the build, and if no other gdb was
specified in config.toml, then the just-built gdb will be used for
debuginfo testing.

Closes #34457
  • Loading branch information
bors committed Dec 21, 2018
2 parents 01c6ea2 + 5193d1f commit 4628fcb
Show file tree
Hide file tree
Showing 17 changed files with 227 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Expand Up @@ -52,6 +52,10 @@
path = src/tools/clang
url = https://github.com/rust-lang-nursery/clang.git
branch = rust-release-80-v2
[submodule "src/tools/gdb"]
path = src/tools/gdb
url = https://github.com/rust-dev-tools/gdb.git
branch = rust-8.2
[submodule "src/doc/rustc-guide"]
path = src/doc/rustc-guide
url = https://github.com/rust-lang/rustc-guide.git
Expand Down
3 changes: 3 additions & 0 deletions config.toml.example
Expand Up @@ -383,6 +383,9 @@
# This is only built if LLVM is also being built.
#lldb = false

# Indicates whether GDB will also be built.
#build-gdb = false

# Whether to deny warnings in crates
#deny-warnings = true

Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/bootstrap.py
Expand Up @@ -723,6 +723,10 @@ def update_submodules(self):
config = self.get_toml('lldb')
if config is None or config == 'false':
continue
if module.endswith("gdb"):
config = self.get_toml('build-gdb')
if config is None or config == 'false':
continue
check = self.check_submodule(module, slow_submodules)
filtered_submodules.append((module, check))
submodules_names.append(module)
Expand Down
2 changes: 2 additions & 0 deletions src/bootstrap/builder.rs
Expand Up @@ -363,6 +363,7 @@ impl<'a> Builder<'a> {
tool::Rustdoc,
tool::Clippy,
native::Llvm,
native::Gdb,
tool::Rustfmt,
tool::Miri,
native::Lld
Expand Down Expand Up @@ -461,6 +462,7 @@ impl<'a> Builder<'a> {
dist::Clippy,
dist::LlvmTools,
dist::Lldb,
dist::Gdb,
dist::Extended,
dist::HashSign
),
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/config.rs
Expand Up @@ -92,6 +92,8 @@ pub struct Config {
pub lldb_enabled: bool,
pub llvm_tools_enabled: bool,

pub gdb_enabled: bool,

// rust codegen options
pub rust_optimize: bool,
pub rust_codegen_units: Option<u32>,
Expand Down Expand Up @@ -320,6 +322,7 @@ struct Rust {
wasm_syscall: Option<bool>,
lld: Option<bool>,
lldb: Option<bool>,
build_gdb: Option<bool>,
llvm_tools: Option<bool>,
deny_warnings: Option<bool>,
backtrace_on_ice: Option<bool>,
Expand Down Expand Up @@ -552,6 +555,7 @@ impl Config {
set(&mut config.wasm_syscall, rust.wasm_syscall);
set(&mut config.lld_enabled, rust.lld);
set(&mut config.lldb_enabled, rust.lldb);
set(&mut config.gdb_enabled, rust.build_gdb);
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
config.rustc_default_linker = rust.default_linker.clone();
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/configure.py
Expand Up @@ -70,6 +70,7 @@ def v(*args):
o("full-tools", None, "enable all tools")
o("lld", "rust.lld", "build lld")
o("lldb", "rust.lldb", "build lldb")
o("gdb", "rust.build-gdb", "build gdb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")

# Optimization and debugging options. These may be overridden by the release
Expand Down
99 changes: 99 additions & 0 deletions src/bootstrap/dist.rs
Expand Up @@ -35,6 +35,11 @@ use crate::tool::{self, Tool};
use crate::cache::{INTERNER, Interned};
use time;

#[cfg(unix)]
use std::os::unix::fs::symlink as symlink_file;
#[cfg(windows)]
use std::os::windows::fs::symlink_file;

pub fn pkgname(builder: &Builder, component: &str) -> String {
if component == "cargo" {
format!("{}-{}", component, builder.cargo_package_vers())
Expand All @@ -48,6 +53,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
format!("{}-{}", component, builder.llvm_tools_package_vers())
} else if component == "lldb" {
format!("{}-{}", component, builder.lldb_package_vers())
} else if component == "gdb" {
format!("{}-{}", component, builder.gdb_package_vers())
} else {
assert!(component.starts_with("rust"));
format!("{}-{}", component, builder.rust_package_vers())
Expand Down Expand Up @@ -1400,6 +1407,7 @@ impl Step for Extended {
let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
let clippy_installer = builder.ensure(Clippy { stage, target });
let lldb_installer = builder.ensure(Lldb { target });
let gdb_installer = builder.ensure(Gdb { target });
let mingw_installer = builder.ensure(Mingw { host: target });
let analysis_installer = builder.ensure(Analysis {
compiler: builder.compiler(stage, self.host),
Expand Down Expand Up @@ -1440,6 +1448,7 @@ impl Step for Extended {
tarballs.extend(rustfmt_installer.clone());
tarballs.extend(llvm_tools_installer);
tarballs.extend(lldb_installer);
tarballs.extend(gdb_installer);
tarballs.push(analysis_installer);
tarballs.push(std_installer);
if builder.config.docs {
Expand Down Expand Up @@ -1873,6 +1882,7 @@ impl Step for HashSign {
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
cmd.arg(builder.llvm_tools_package_vers());
cmd.arg(builder.lldb_package_vers());
cmd.arg(builder.gdb_package_vers());
cmd.arg(addr);

builder.create_dir(&distdir(builder));
Expand Down Expand Up @@ -2121,3 +2131,92 @@ impl Step for Lldb {
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
}
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Gdb {
pub target: Interned<String>,
}

impl Step for Gdb {
type Output = Option<PathBuf>;
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = false;

fn should_run(run: ShouldRun) -> ShouldRun {
let builder = run.builder;
run.path("src/tools/gdb").default_condition(builder.config.gdb_enabled)
}

fn make_run(run: RunConfig) {
run.builder.ensure(Gdb {
target: run.target,
});
}

fn run(self, builder: &Builder) -> Option<PathBuf> {
let target = self.target;

if builder.config.dry_run {
return None;
}

let gdb_install = builder.gdb_out(target).join("install");
let bindir = gdb_install.join("bin");
let gdb_exe = bindir.join(exe("gdb", &target));
if !gdb_exe.exists() {
return None;
}

builder.info(&format!("Dist Gdb ({})", target));
let src = builder.src.join("src/tools/gdb");
let name = pkgname(builder, "gdb");

let tmp = tmpdir(builder);
let image = tmp.join("gdb-image");
drop(fs::remove_dir_all(&image));

// Prepare the image directory
let root = image.join("lib/rustlib").join(&*target);
let dst = root.join("bin");
t!(fs::create_dir_all(&dst));
// Install gdb as real-gdb, and run-gdb as gdb.
let filename = bindir.join(exe("gdb", &target));
builder.copy(&filename, &dst.join(exe("real-gdb", &target)));
let filename = bindir.join(exe("run-gdb", &target));
builder.copy(&filename, &dst.join(exe("gdb", &target)));

// gdb "share" files.
let sharedir = gdb_install.join("share/gdb");
let dst = root.join("share/gdb");
t!(fs::create_dir_all(&dst));
builder.cp_r(&sharedir, &dst);

// We want to pick up the system auto-loads.
t!(symlink_file(&Path::new("/usr/share/gdb/auto-load"), &dst.join("auto-load")));

// Prepare the overlay
let overlay = tmp.join("gdb-overlay");
drop(fs::remove_dir_all(&overlay));
builder.create_dir(&overlay);
builder.install(&src.join("COPYING3"), &overlay, 0o644);
builder.create(&overlay.join("version"), &builder.gdb_vers());

// Generate the installer tarball
let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
.arg("--success-message=gdb-installed.")
.arg("--image-dir").arg(&image)
.arg("--work-dir").arg(&tmpdir(builder))
.arg("--output-dir").arg(&distdir(builder))
.arg("--non-installed-overlay").arg(&overlay)
.arg(format!("--package-name={}-{}", name, target))
.arg("--legacy-manifest-dirs=rustlib,cargo")
.arg("--component-name=gdb");


builder.run(&mut cmd);
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
}
}
13 changes: 13 additions & 0 deletions src/bootstrap/lib.rs
Expand Up @@ -594,6 +594,11 @@ impl Build {
self.out.join(&*target).join("lld")
}

/// Output directory for gdb build.
fn gdb_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("gdb")
}

/// Output directory for all documentation for a target
fn doc_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("doc")
Expand Down Expand Up @@ -1047,6 +1052,14 @@ impl Build {
self.rust_version()
}

fn gdb_package_vers(&self) -> String {
self.package_vers(&self.rust_version())
}

fn gdb_vers(&self) -> String {
self.rust_version()
}

fn llvm_link_tools_dynamically(&self, target: Interned<String>) -> bool {
(target.contains("linux-gnu") || target.contains("apple-darwin"))
}
Expand Down
42 changes: 42 additions & 0 deletions src/bootstrap/native.rs
Expand Up @@ -473,6 +473,48 @@ impl Step for Lld {
}
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Gdb {
pub target: Interned<String>,
}

impl Step for Gdb {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = false;

fn should_run(run: ShouldRun) -> ShouldRun {
let builder = run.builder;
run.path("src/tools/gdb").default_condition(builder.config.gdb_enabled)
}

fn make_run(run: RunConfig) {
run.builder.ensure(Gdb {
target: run.target
});
}

fn run(self, builder: &Builder) {
if builder.config.dry_run {
return;
}

let root = builder.gdb_out(self.target);
let build = root.join("build");
let install = root.join("install");
let src = builder.src.join("src/tools/gdb");
t!(fs::create_dir_all(&build));
t!(fs::create_dir_all(&install));

let mut cmd = Command::new(&src.join("build-for-rust.sh"));
cmd.arg(&src)
.arg(&build)
.arg(&install);

builder.run(&mut cmd);
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct TestHelpers {
pub target: Interned<String>,
Expand Down
3 changes: 1 addition & 2 deletions src/bootstrap/sanity.rs
Expand Up @@ -126,8 +126,7 @@ pub fn check(build: &mut Build) {
.or_else(|| cmd_finder.maybe_have("node"))
.or_else(|| cmd_finder.maybe_have("nodejs"));

build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p))
.or_else(|| cmd_finder.maybe_have("gdb"));
build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p));

// We're gonna build some custom C code here and there, host triples
// also build some C++ shims for LLVM so we need a C++ compiler.
Expand Down
6 changes: 6 additions & 0 deletions src/bootstrap/test.rs
Expand Up @@ -1111,8 +1111,14 @@ impl Step for Compiletest {
cmd.arg("--lldb-python").arg(builder.python());
}

// If config.toml specifies a gdb, use it; otherwise, if we
// built a gdb, prefer that.
if let Some(ref gdb) = builder.config.gdb {
cmd.arg("--gdb").arg(gdb);
} else if builder.config.gdb_enabled {
cmd.arg("--gdb").arg(builder.gdb_out(target).join("install/bin/gdb"));
} else {
cmd.arg("--gdb").arg("gdb");
}

let run = |cmd: &mut Command| {
Expand Down
9 changes: 8 additions & 1 deletion src/ci/docker/dist-i686-linux/Dockerfile
Expand Up @@ -23,7 +23,13 @@ RUN yum upgrade -y && yum install -y \
pkgconfig \
wget \
autoconf \
gettext
gettext \
xz-static \
xz-devel \
expat-static \
expat-devel \
ncurses-static \
ncurses-devel

ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
Expand Down Expand Up @@ -95,6 +101,7 @@ ENV HOSTS=i686-unknown-linux-gnu

ENV RUST_CONFIGURE_ARGS \
--enable-full-tools \
--enable-gdb \
--enable-sanitizers \
--enable-profiler \
--set target.i686-unknown-linux-gnu.linker=clang \
Expand Down
9 changes: 8 additions & 1 deletion src/ci/docker/dist-x86_64-linux/Dockerfile
Expand Up @@ -23,7 +23,13 @@ RUN yum upgrade -y && yum install -y \
pkgconfig \
wget \
autoconf \
gettext
gettext \
xz-static \
xz-devel \
expat-static \
expat-devel \
ncurses-static \
ncurses-devel

ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
Expand Down Expand Up @@ -95,6 +101,7 @@ ENV HOSTS=x86_64-unknown-linux-gnu

ENV RUST_CONFIGURE_ARGS \
--enable-full-tools \
--enable-gdb \
--enable-sanitizers \
--enable-profiler \
--enable-compiler-docs \
Expand Down
14 changes: 13 additions & 1 deletion src/etc/rust-gdb
Expand Up @@ -16,10 +16,22 @@ set -e
RUSTC_SYSROOT=`rustc --print=sysroot`
GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"

if [ -z "$RUST_GDB" ]; then
# Find the host triple so we can find lldb in rustlib.
host=`rustc -vV | sed -n -e 's/^host: //p'`
RUST_GDB=gdb
if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/gdb" ]; then
bin="$RUSTC_SYSROOT/lib/rustlib/$host/bin"
# Pass the path to real-gdb to the wrapper. This avoids
# having to modify PATH here, which might possibly be
# confusing inside gdb.
RUST_GDB="$bin/gdb $bin/real-gdb"
fi
fi

# Run GDB with the additional arguments that load the pretty printers
# Set the environment variable `RUST_GDB` to overwrite the call to a
# different/specific command (defaults to `gdb`).
RUST_GDB="${RUST_GDB:-gdb}"
PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} \
--directory="$GDB_PYTHON_MODULE_DIRECTORY" \
-iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \
Expand Down

0 comments on commit 4628fcb

Please sign in to comment.