GNOME 开发环境

最后更新: 2021-05-31 01:36:17 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

Debugging across GLib 和 GTK 需要 a consistent 依赖 graph. If GTK loads a 开发 libgtk but resolves GLib, Pango, 或 GDK Pixbuf 来自 the host, 源码 lines 和 runtime types no longer correspond 到 one coherent build. 一个 isolated installation prefix 提供 consistency without replacing distribution packages.

选择隔离边界 #

GNOME recommends Builder 用于 application 开发 和 Toolbx 用于 libraries, services, 和 host-integrated modules. JHBuild remains available 用于 building a 依赖 graph. Those tools encode more 的 the graph than a hand-written script 和 应当 be preferred 用于 sustained contribution work.

A manual Meson/Ninja prefix remains useful 用于 源码 inspection 或 a small, controlled stack. Use it inside a container 或 disposable development environment 当 possible. prefix isolates 已安装的 files, 同时 the container isolates 构建 tools 和 依赖项 still come 来自 the distribution.

GLib, GObject, GModule, GThread, 和 GIO 是 built 来自 the same GLib repository; GObject 是 不 a separate 源码 checkout. GTK 是 a separate repository. GTK’s exact dependency set varies,使用 its enabled Wayland, X11, Vulkan, documentation, and introspection features, so each checkout’s README.md, meson_options.txt, and Meson 错误 messages 是 authoritative 用于 revision.

Install the distribution’s compiler, Python, Meson, Ninja, pkg-config, and the 开发 头文件 needed 到 bootstrap the graph. Documentation builds may additionally require tools such 作为 gi-docgen, Graphviz, 和 Doxygen; they are 不 required 用于 every GLib 或 GTK configuration.

定义一个开发前缀 #

Keep source, 构建 directories, 和 已安装的 artifacts separate:

g`n-o-meeps`-nrr-dvec-e.f/vsigg/hxlt/ikb

An activation script makes all discovery paths refer 到 the same prefix:

sh
#!/usr/bin/env bash

ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
PREFIX="$ROOT/prefix"

export PREFIX
export PATH="$PREFIX/bin:$PATH"
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig"
export LD_LIBRARY_PATH="$PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export GI_TYPELIB_PATH="$PREFIX/lib/girepository-1.0"
export GIO_EXTRA_MODULES="$PREFIX/lib/gio/modules"
export GSETTINGS_SCHEMA_DIR="$PREFIX/share/glib-2.0/schemas"
export XDG_DATA_DIRS="$PREFIX/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"

Setting --libdir=lib during every Meson setup makes these paths independent of a distribution’s lib64 或 multiarch default. PKG_CONFIG_PATH searches the prefix first but still permits host fallback. After the entire required dependency closure has been 已安装的 到 the prefix, strict builds can replace it with:

sh
export PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig"
unset PKG_CONFIG_PATH

PKG_CONFIG_LIBDIR suppresses pkg-config’s standard search directories. Enabling it too early also hides bootstrap libraries such 作为 libffi, PCRE2, FreeType, 和 Fontconfig, so either 构建 those 到 the prefix 或 使用 a container,使用 an explicitly documented host baseline.

Do 不 place this activation in a login profile. LD_LIBRARY_PATH applies to every 进程 started 来自 the shell 和 可以 make unrelated host applications load ABI-incompatible 开发 libraries.

按依赖顺序构建 #

Build leaves 在……之前 roots because Meson resolves 依赖项 当 configuring each 构建 directory. 一个 GTK stack commonly includes the following groups:

  1. GLib’s bootstrap dependencies, including libffi 和 PCRE2.
  2. GLib, which produces GLib, GObject, 和 GIO together.
  3. Graphics 和 text 依赖项 such 作为 pixman/Cairo, FreeType, Fontconfig, HarfBuzz, GDK Pixbuf, Pango, Graphene, 和 libepoxy.
  4. Backend dependencies, such 作为 Wayland 和 wayland-protocols 或 the required X11 libraries.
  5. GTK, followed 由 language bindings such 作为 gtkmm 当 the project needs them.

Dependency edges within the middle groups depend 在 selected features. A topological module set 来自 JHBuild 或 GNOME Build Metadata 是 safer than copying a fixed 列表 across releases.

same 构建 函数 可以 be 用于 用于 each Meson project:

sh
build_one()
{
  source_dir=$1
  build_dir=$2

  meson setup "$build_dir" "$source_dir" \
    --prefix="$PREFIX" \
    --libdir=lib \
    -Ddebug=true \
    -Doptimization=0 \
    -Dstrip=false
  meson compile -C "$build_dir"
  meson test -C "$build_dir" --print-errorlogs
  meson install -C "$build_dir"
}

Run the 函数 来自 a shell has sourced env.sh:

sh
mkdir -p "$PREFIX"

build_one "$PWD/src/glib" "$PWD/src/glib/_build"
build_one "$PWD/src/gtk"  "$PWD/src/gtk/_build"

two 调用 show the endpoints, 不 a complete GTK 构建 plan. Invoke the same 函数 用于 every source-built 依赖 between GLib 和 GTK in the module set’s topological order.

Meson’s debug 构建 type currently corresponds 到 debug information with optimization level 0, but spelling out debug, optimization, 和 strip makes the intended debugger behavior visible. Individual projects 可以 add feature options 在……之后 inspecting meson configure _build; disabling an unneeded backend 是 preferable 到 accidentally satisfying it 来自 the host.

Installing each completed layer matters because the next project finds its headers, .pc files, shared objects, schemas, 和 introspection 数据 under one prefix. Compile 已安装的 schemas 在……之后 installing a project provides them:

sh
glib-compile-schemas "$PREFIX/share/glib-2.0/schemas"

避免混合系统构建 #

Check 依赖 resolution immediately 在……之后 Meson setup:

sh
pkg-config --variable=prefix glib-2.0
pkg-config --variable=prefix gtk4
meson introspect src/gtk/_build --dependencies

Both pkg-config prefix queries 应当 print the 开发 prefix. Meson’s setup log 必须 also show prefix paths 用于 Pango, GDK Pixbuf, Graphene, and other libraries intended 到 be under 源码 control.

Check the final ELF resolution rather than trusting link-time output:

sh
ldd "$PREFIX/bin/gtk4-demo"
readelf -d "$PREFIX/bin/gtk4-demo" | grep -E 'NEEDED|RPATH|RUNPATH'

All libraries in the source-built closure 应当 resolve below $PREFIX. System C libraries, the dynamic loader, GPU drivers, 和 deliberately retained bootstrap 依赖项 may still resolve 来自 the host. Record boundary instead 的 claiming complete isolation.

An rpath 可以 make binaries usable without LD_LIBRARY_PATH:

sh
export LDFLAGS="-Wl,-rpath,$PREFIX/lib"

Use the comma-separated linker form shown above. 一个 rpath 仅 changes runtime loading; it does 不 influence which 头文件 或 .pc metadata Meson selected. pkg-config inspection 是 still required.

使更新可重复 #

Clone each upstream repository once:

sh
git clone https://gitlab.gnome.org/GNOME/glib.git src/glib
git clone https://gitlab.gnome.org/GNOME/gtk.git src/gtk

Apply the same pattern 到 source-built 依赖项 来自 the selected module set. Subsequent updates 应当 不 delete untracked work:

sh
git -C src/glib fetch --prune
git -C src/glib switch main
git -C src/glib pull --ff-only

git -C src/gtk fetch --prune
git -C src/gtk switch main
git -C src/gtk pull --ff-only

For each dependency, record the tested commit in a lock 文件 或 构建 log. “Current source” changes continuously; commit IDs make a successful graph reproducible. Update leaves first, then rebuild 和 install dependents. Use meson setup --reconfigure 当 仅 options 或 detected 依赖项 changed, and meson setup --wipe 仅 用于 a 生成的 构建 目录 当 cached state 必须 be discarded.

Avoid git clean -fdx in update scripts because it destroys untracked source work. Build directories already provide a replaceable boundary.

调试已安装的依赖图 #

Run the debugger 来自 the activated environment:

sh
gdb --args "$PREFIX/bin/gtk4-demo"

Useful initial checks are:

gdb
(gdb) set breakpoint pending on
(gdb) break g_main_context_dispatch
(gdb) break gtk_widget_snapshot
(gdb) run
(gdb) info sharedlibrary

info sharedlibrary 应当 show the intended prefix. If a breakpoint resolves to a 系统 path, inspect LD_DEBUG=libs, ldd, pkg-config prefixes, and Meson’s 依赖 report 在……之前 debugging application logic. Source lookup can be corrected,使用 GDB’s directory 或 set substitute-path, but path substitution cannot repair a binary linked against the wrong library.

update workflow 是 therefore deterministic:

  1. Activate the environment.
  2. Fetch pinned 或 selected commits.
  3. Reconfigure, build, test, 和 install in 依赖 order.
  4. Recompile schemas 和 any 生成的 loader caches required 由 the stack.
  5. Audit pkg-config 和 ELF resolution.
  6. Start the debugger 仅 在……之后 the graph passes those checks.

Upstream 参考资料 #

评论

在 GitHub 上阅读或评论(发表评论需要登录)