diff --git a/.gitmodules b/.gitmodules index 70164d48a307b..62a79245484aa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/config.toml.example b/config.toml.example index f75e220de47e7..1d35a2cac996b 100644 --- a/config.toml.example +++ b/config.toml.example @@ -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 diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d143dffb24be5..6a9aee64f1cb3 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -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) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 405fc871eef76..626e9e35d8c1d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -363,6 +363,7 @@ impl<'a> Builder<'a> { tool::Rustdoc, tool::Clippy, native::Llvm, + native::Gdb, tool::Rustfmt, tool::Miri, native::Lld @@ -461,6 +462,7 @@ impl<'a> Builder<'a> { dist::Clippy, dist::LlvmTools, dist::Lldb, + dist::Gdb, dist::Extended, dist::HashSign ), diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 2ae9da9c085d4..79335b8556523 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -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, @@ -320,6 +322,7 @@ struct Rust { wasm_syscall: Option, lld: Option, lldb: Option, + build_gdb: Option, llvm_tools: Option, deny_warnings: Option, backtrace_on_ice: Option, @@ -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(); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index f2473cb9eda6b..790d5d611448a 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -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 diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 927f9bf8ddbca..4d56a6f4c5bb0 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -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()) @@ -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()) @@ -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), @@ -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 { @@ -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)); @@ -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, +} + +impl Step for Gdb { + type Output = Option; + 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 { + 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))) + } +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index c5b8f19eee6fb..850088ec97081 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -594,6 +594,11 @@ impl Build { self.out.join(&*target).join("lld") } + /// Output directory for gdb build. + fn gdb_out(&self, target: Interned) -> PathBuf { + self.out.join(&*target).join("gdb") + } + /// Output directory for all documentation for a target fn doc_out(&self, target: Interned) -> PathBuf { self.out.join(&*target).join("doc") @@ -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) -> bool { (target.contains("linux-gnu") || target.contains("apple-darwin")) } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d9f51f6fd3d07..86ad69d85bf46 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -473,6 +473,48 @@ impl Step for Lld { } } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Gdb { + pub target: Interned, +} + +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, diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index f585495b0aa94..b2dfc301ff630 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -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. diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 11932d58ceac6..e94c6f963330d 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -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| { diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile index b087ea7899f4c..aca828702a26c 100644 --- a/src/ci/docker/dist-i686-linux/Dockerfile +++ b/src/ci/docker/dist-i686-linux/Dockerfile @@ -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 @@ -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 \ diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index a1a778c2b2c61..cd870888c3c82 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -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 @@ -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 \ diff --git a/src/etc/rust-gdb b/src/etc/rust-gdb index 743952a5bef89..a1a526b4abe69 100755 --- a/src/etc/rust-gdb +++ b/src/etc/rust-gdb @@ -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" \ diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index aba0472ae366e..6a4e4e3051448 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -202,6 +202,7 @@ struct Builder { rustfmt_release: String, llvm_tools_release: String, lldb_release: String, + gdb_release: String, input: PathBuf, output: PathBuf, @@ -217,6 +218,7 @@ struct Builder { rustfmt_version: Option, llvm_tools_version: Option, lldb_version: Option, + gdb_version: Option, rust_git_commit_hash: Option, cargo_git_commit_hash: Option, @@ -225,6 +227,7 @@ struct Builder { rustfmt_git_commit_hash: Option, llvm_tools_git_commit_hash: Option, lldb_git_commit_hash: Option, + gdb_git_commit_hash: Option, should_sign: bool, } @@ -253,6 +256,7 @@ fn main() { let rustfmt_release = args.next().unwrap(); let llvm_tools_release = args.next().unwrap(); let lldb_release = args.next().unwrap(); + let gdb_release = args.next().unwrap(); let s3_address = args.next().unwrap(); // Do not ask for a passphrase while manually testing @@ -269,6 +273,7 @@ fn main() { rustfmt_release, llvm_tools_release, lldb_release, + gdb_release, input, output, @@ -284,6 +289,7 @@ fn main() { rustfmt_version: None, llvm_tools_version: None, lldb_version: None, + gdb_version: None, rust_git_commit_hash: None, cargo_git_commit_hash: None, @@ -292,6 +298,7 @@ fn main() { rustfmt_git_commit_hash: None, llvm_tools_git_commit_hash: None, lldb_git_commit_hash: None, + gdb_git_commit_hash: None, should_sign, }.build(); @@ -307,6 +314,7 @@ impl Builder { self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu"); // lldb is only built for macOS. self.lldb_version = self.version("lldb", "x86_64-apple-darwin"); + self.gdb_version = self.version("lldb", "x86_64-unknown-linux-gnu"); self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu"); self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu"); @@ -316,6 +324,7 @@ impl Builder { self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools", "x86_64-unknown-linux-gnu"); self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu"); + self.lldb_git_commit_hash = self.git_commit_hash("gdb", "x86_64-unknown-linux-gnu"); self.digest_and_sign(); let manifest = self.build_manifest(); @@ -355,6 +364,7 @@ impl Builder { self.package("rust-analysis", &mut manifest.pkg, TARGETS); self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS); self.package("lldb-preview", &mut manifest.pkg, TARGETS); + self.package("gdb", &mut manifest.pkg, TARGETS); manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() }); manifest.renames.insert("rustfmt".to_owned(), Rename { to: "rustfmt-preview".to_owned() }); @@ -405,6 +415,7 @@ impl Builder { Component { pkg: "rustfmt-preview".to_string(), target: host.to_string() }, Component { pkg: "llvm-tools-preview".to_string(), target: host.to_string() }, Component { pkg: "lldb-preview".to_string(), target: host.to_string() }, + Component { pkg: "gdb".to_string(), target: host.to_string() }, Component { pkg: "rust-analysis".to_string(), target: host.to_string() }, ]); @@ -526,6 +537,8 @@ impl Builder { format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target) } else if component == "lldb" || component == "lldb-preview" { format!("lldb-{}-{}.tar.gz", self.lldb_release, target) + } else if component == "gdb" { + format!("gdb-{}-{}.tar.gz", self.gdb_release, target) } else { format!("{}-{}-{}.tar.gz", component, self.rust_release, target) } @@ -544,6 +557,8 @@ impl Builder { &self.llvm_tools_version } else if component == "lldb" || component == "lldb-preview" { &self.lldb_version + } else if component == "gdb" { + &self.gdb_version } else { &self.rust_version } @@ -562,6 +577,8 @@ impl Builder { &self.llvm_tools_git_commit_hash } else if component == "lldb" || component == "lldb-preview" { &self.lldb_git_commit_hash + } else if component == "gdb" { + &self.gdb_git_commit_hash } else { &self.rust_git_commit_hash } diff --git a/src/tools/gdb b/src/tools/gdb new file mode 160000 index 0000000000000..f1f53755e84e3 --- /dev/null +++ b/src/tools/gdb @@ -0,0 +1 @@ +Subproject commit f1f53755e84e32511afd7cd38ee9d71987e2662c diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 614d2053a432b..f028e1bd5111d 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -70,6 +70,7 @@ fn filter_dirs(path: &Path) -> bool { "src/tools/miri", "src/tools/lld", "src/tools/lldb", + "src/tools/gdb", "src/target", "src/stdsimd", "src/rust-sgx",