aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2022-02-23 08:17:08 -0500
committerXavier Claessens <xclaesse@gmail.com>2022-02-28 09:03:27 -0500
commit30cdb2a28077d9a0364b9ef6b231927c52436a6b (patch)
tree1e4f74d9a66d43b859d1a68ef7bbb018bfc9d34c
parent6fafeb13b3b115b5fddf371b6b7624801559b99f (diff)
downloadmeson-30cdb2a28077d9a0364b9ef6b231927c52436a6b.zip
meson-30cdb2a28077d9a0364b9ef6b231927c52436a6b.tar.gz
meson-30cdb2a28077d9a0364b9ef6b231927c52436a6b.tar.bz2
devenv: Setup GDB auto-load scripts
When the project instals GDB helper scripts, copy them into meson-private directory with the right tree layout and write a .gdbinit script to load them automatically.
-rw-r--r--docs/markdown/Commands.md7
-rw-r--r--docs/markdown/snippets/devenv.md8
-rw-r--r--mesonbuild/mdevenv.py52
3 files changed, 65 insertions, 2 deletions
diff --git a/docs/markdown/Commands.md b/docs/markdown/Commands.md
index 2623b5c..3542aa4 100644
--- a/docs/markdown/Commands.md
+++ b/docs/markdown/Commands.md
@@ -324,4 +324,11 @@ These variables are set in environment in addition to those set using `meson.add
Since *Since 0.62.0* if bash-completion scripts are being installed and the
shell is bash, they will be automatically sourced.
+Since *Since 0.62.0* when GDB helper scripts (*-gdb.py, *-gdb.gdb, and *-gdb.csm)
+are installed with a library name that matches one being built, Meson adds the
+needed auto-load commands into `<builddir>/.gdbinit` file. When running gdb from
+top build directory, that file is loaded by gdb automatically. In the case of
+python scripts that needs to load other python modules, `PYTHONPATH` may need
+to be modified using `meson.add_devenv()`.
+
{{ devenv_arguments.inc }}
diff --git a/docs/markdown/snippets/devenv.md b/docs/markdown/snippets/devenv.md
index 19a272c..1c401c1 100644
--- a/docs/markdown/snippets/devenv.md
+++ b/docs/markdown/snippets/devenv.md
@@ -8,3 +8,11 @@ and [`python.extension_module()`](Python-module.md#extension_module).
If bash-completion scripts are being installed and the shell is bash, they will
be automatically sourced.
+
+## Setup GDB auto-load for `meson devenv`
+
+When GDB helper scripts (*-gdb.py, *-gdb.gdb, and *-gdb.csm) are installed with
+a library name that matches one being built, Meson adds the needed auto-load
+commands into `<builddir>/.gdbinit` file. When running gdb from top build
+directory, that file is loaded by gdb automatically.
+
diff --git a/mesonbuild/mdevenv.py b/mesonbuild/mdevenv.py
index 3bd66ef..0fc8595 100644
--- a/mesonbuild/mdevenv.py
+++ b/mesonbuild/mdevenv.py
@@ -1,10 +1,12 @@
import os, subprocess
import argparse
import tempfile
+import shutil
from pathlib import Path
from . import build, minstall, dependencies
from .mesonlib import MesonException, RealPathAction, is_windows, setup_vsenv, OptionKey
+from . import mlog
import typing as T
if T.TYPE_CHECKING:
@@ -56,15 +58,61 @@ def bash_completion_files(b: build.Build, install_data: 'InstallData') -> T.List
result.append(f.path)
return result
+def add_gdb_auto_load(autoload_path: Path, gdb_helper: str, fname: Path) -> None:
+ # Copy or symlink the GDB helper into our private directory tree
+ destdir = autoload_path / fname.parent
+ destdir.mkdir(parents=True, exist_ok=True)
+ try:
+ if is_windows():
+ shutil.copy(gdb_helper, str(destdir / os.path.basename(gdb_helper)))
+ else:
+ os.symlink(gdb_helper, str(destdir / os.path.basename(gdb_helper)))
+ except (FileExistsError, shutil.SameFileError):
+ pass
+
+def write_gdb_script(privatedir: Path, install_data: 'InstallData') -> None:
+ if not shutil.which('gdb'):
+ return
+ bdir = privatedir.parent
+ autoload_basedir = privatedir / 'gdb-auto-load'
+ autoload_path = Path(autoload_basedir, *bdir.parts[1:])
+ have_gdb_helpers = False
+ for d in install_data.data:
+ if d.path.endswith('-gdb.py') or d.path.endswith('-gdb.gdb') or d.path.endswith('-gdb.scm'):
+ # This GDB helper is made for a specific shared library, search if
+ # we have it in our builddir.
+ libname = Path(d.path).name.rsplit('-', 1)[0]
+ for t in install_data.targets:
+ path = Path(t.fname)
+ if path.name == libname:
+ add_gdb_auto_load(autoload_path, d.path, path)
+ have_gdb_helpers = True
+ if have_gdb_helpers:
+ gdbinit_line = f'add-auto-load-scripts-directory {autoload_basedir}\n'
+ gdbinit_path = bdir / '.gdbinit'
+ first_time = False
+ try:
+ with gdbinit_path.open('r+', encoding='utf-8') as f:
+ if gdbinit_line not in f.readlines():
+ f.write(gdbinit_line)
+ first_time = True
+ except FileNotFoundError:
+ gdbinit_path.write_text(gdbinit_line, encoding='utf-8')
+ first_time = True
+ if first_time:
+ mlog.log('Meson detected GDB helpers and added config in', mlog.bold(str(gdbinit_path)))
+
def run(options: argparse.Namespace) -> int:
- buildfile = Path(options.wd) / 'meson-private' / 'build.dat'
+ privatedir = Path(options.wd) / 'meson-private'
+ buildfile = privatedir / 'build.dat'
if not buildfile.is_file():
raise MesonException(f'Directory {options.wd!r} does not seem to be a Meson build directory.')
b = build.load(options.wd)
- install_data = minstall.load_install_data(str(buildfile.parent / 'install.dat'))
+ install_data = minstall.load_install_data(str(privatedir / 'install.dat'))
setup_vsenv(b.need_vsenv)
devenv = get_env(b, options.wd)
+ write_gdb_script(privatedir, install_data)
args = options.command
if not args: