GLib と GTK をまたいでデバッグするには、一貫した依存関係グラフが必要です。GTK が開発用 libgtk をロードしながら、GLib、Pango、GDK Pixbuf をホストから解決すると、ソース行と実行時型が 1 つの一貫したビルドに対応しなくなります。分離されたインストールプレフィックスは、ディストリビューションのパッケージを置き換えずにその一貫性を提供します。
分離境界を選ぶ #
GNOME はアプリケーション開発に Builder を、ライブラリ、サービス、ホスト統合モジュールに Toolbx を推奨します。依存関係グラフの構築には JHBuild も利用できます。これらのツールは手書きスクリプトより多くのグラフをエンコードするため、継続的なコントリビューション作業では優先すべきです。
手動の Meson/Ninja プレフィックスは、ソース検査や小規模で管理されたスタックに役立ちます。可能な場合はコンテナーまたは使い捨ての開発環境内で使用します。プレフィックスはインストールされたファイルを分離し、コンテナーはディストリビューション由来のビルドツールと依存関係を分離します。
GLib、GObject、GModule、GThread、GIO は同じ GLib リポジトリからビルドされます。GObject は別のソースチェックアウトではありません。GTK は別のリポジトリです。GTK の正確な依存関係セットは、有効にした Wayland、X11、Vulkan、ドキュメント、イントロスペクション機能によって異なります。そのため、各チェックアウトの README.md、meson_options.txt、Meson のエラーメッセージがそのリビジョンに対する権威ある情報です。
ディストリビューションのコンパイラー、Python、Meson、Ninja、pkg-config と、グラフをブートストラップするために必要な開発ヘッダーをインストールします。ドキュメントのビルドには gi-docgen、Graphviz、Doxygen などの追加ツールが必要になる場合がありますが、すべての GLib または GTK 構成に必要なわけではありません。
1 つの開発プレフィックスを定義する #
ソース、ビルドディレクトリ、インストール済み成果物を分離します。
アクティベーションスクリプトによって、すべての検出パスが同じプレフィックスを参照するようにします。
#!/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}"すべての Meson セットアップで --libdir=lib を設定すると、これらのパスがディストリビューションの lib64 またはマルチアーキテクチャのデフォルトから独立します。PKG_CONFIG_PATH は最初にプレフィックスを検索しますが、ホストへのフォールバックも許可します。必要な依存関係の閉包全体をプレフィックスにインストールした後、厳密なビルドでは次のように置き換えられます。
export PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig"
unset PKG_CONFIG_PATHPKG_CONFIG_LIBDIR は pkg-config の標準検索ディレクトリを抑制します。早すぎる段階で有効にすると libffi、PCRE2、FreeType、Fontconfig などのブートストラップライブラリも隠れるため、これらをプレフィックスにビルドするか、明示的に文書化されたホスト基準を持つコンテナーを使用します。
このアクティベーションをログインプロファイルに置かないでください。LD_LIBRARY_PATH はシェルから起動されるすべてのプロセスに適用され、無関係なホストアプリケーションが ABI 非互換の開発ライブラリをロードする可能性があります。
依存関係の順序でビルドする #
Meson は各ビルドディレクトリの設定時に依存関係を解決するため、根ではなく葉からビルドします。GTK スタックには、通常次のグループが含まれます。
- libffi や PCRE2 など、GLib のブートストラップ依存関係。
- GLib。GLib、GObject、GIO をまとめて生成する。
- pixman/Cairo、FreeType、Fontconfig、HarfBuzz、GDK Pixbuf、Pango、Graphene、libepoxy などのグラフィックスおよびテキスト依存関係。
- Wayland と wayland-protocols、または必要な X11 ライブラリなどのバックエンド依存関係。
- GTK。その後、プロジェクトで必要な場合は gtkmm などの言語バインディング。
中間グループ内の依存関係エッジは、選択した機能に依存します。JHBuild または GNOME Build Metadata からのトポロジカルなモジュール集合は、固定リストをリリース間でコピーするより安全です。
各 Meson プロジェクトには、同じビルド関数を使用できます。
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"
}env.sh を source したシェルから関数を実行します。
mkdir -p "$PREFIX"
build_one "$PWD/src/glib" "$PWD/src/glib/_build"
build_one "$PWD/src/gtk" "$PWD/src/gtk/_build"2 つの呼び出しはエンドポイントを示すもので、完全な GTK ビルド計画ではありません。GLib と GTK の間にあるソースビルド依存関係ごとに、モジュール集合のトポロジカル順序で同じ関数を呼び出します。
Meson の debug ビルドタイプは、現在では最適化レベル 0 のデバッグ情報に対応しますが、debug、optimization、strip を明示すると、意図したデバッガー動作が明確になります。個々のプロジェクトでは meson configure _build を確認してから機能オプションを追加できます。不要なバックエンドを無効にする方が、ホストから偶然それを満たすより望ましいです。
次のプロジェクトがヘッダー、.pc ファイル、共有オブジェクト、スキーマ、イントロスペクションデータを 1 つのプレフィックスから見つけられるよう、完了した各層をインストールすることが重要です。それらを提供するプロジェクトをインストールした後、インストール済みスキーマをコンパイルします。
glib-compile-schemas "$PREFIX/share/glib-2.0/schemas"混在したシステムビルドを防ぐ #
Meson のセットアップ直後に依存関係の解決を確認します。
pkg-config --variable=prefix glib-2.0
pkg-config --variable=prefix gtk4
meson introspect src/gtk/_build --dependencies両方の pkg-config プレフィックスクエリは開発プレフィックスを出力するはずです。Meson のセットアップログにも、Pango、GDK Pixbuf、Graphene、その他ソース管理下に置くライブラリのプレフィックスパスが表示される必要があります。
リンク時の出力を信頼するのではなく、最終的な ELF 解決を確認します。
ldd "$PREFIX/bin/gtk4-demo"
readelf -d "$PREFIX/bin/gtk4-demo" | grep -E 'NEEDED|RPATH|RUNPATH'ソースからビルドした閉包内のすべてのライブラリは $PREFIX 以下に解決されるべきです。システム C ライブラリ、動的ローダー、GPU ドライバー、意図的に保持されたブートストラップ依存関係は、ホストから解決される場合があります。完全な分離を主張するのではなく、その境界を記録します。
RPATH により、LD_LIBRARY_PATH なしでバイナリを使用できます。
export LDFLAGS="-Wl,-rpath,$PREFIX/lib"上に示したカンマ区切りのリンカー形式を使用します。RPATH は実行時のロードだけを変更し、Meson が選択したヘッダーや .pc メタデータには影響しません。pkg-config の検査は引き続き必要です。
更新を再現可能にする #
各アップストリームリポジトリを 1 回だけクローンします。
git clone https://gitlab.gnome.org/GNOME/glib.git src/glib
git clone https://gitlab.gnome.org/GNOME/gtk.git src/gtk選択したモジュール集合からソースビルドする依存関係にも同じパターンを適用します。後続の更新で追跡されていない作業を削除しないようにします。
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各依存関係について、テスト済みのコミットをロックファイルまたはビルドログに記録します。「現在のソース」は継続的に変化するため、コミット ID によって成功したグラフを再現できます。まず葉を更新し、その後に依存先を再ビルドしてインストールします。オプションまたは検出された依存関係だけが変更された場合は meson setup --reconfigure を使用し、キャッシュされた状態を破棄する必要がある場合にのみ、生成されたビルドディレクトリへ meson setup --wipe を使用します。
更新スクリプトで git clean -fdx を避けてください。追跡されていないソース作業を破壊するためです。ビルドディレクトリは、すでに置換可能な境界を提供します。
インストール済みグラフをデバッグする #
アクティベートされた環境からデバッガーを実行します。
gdb --args "$PREFIX/bin/gtk4-demo"最初に役立つ確認は次のとおりです。
(gdb) set breakpoint pending on
(gdb) break g_main_context_dispatch
(gdb) break gtk_widget_snapshot
(gdb) run
(gdb) info sharedlibraryinfo sharedlibrary は意図したプレフィックスを表示するはずです。ブレークポイントがシステムパスに解決される場合は、アプリケーションロジックをデバッグする前に LD_DEBUG=libs、ldd、pkg-config のプレフィックス、Meson の依存関係レポートを確認します。GDB の directory または set substitute-path でソース検索を修正できますが、パス置換によって誤ったライブラリにリンクされたバイナリを修復することはできません。
したがって、更新ワークフローは決定論的です。
- 環境をアクティベートする。
- 固定または選択したコミットを取得する。
- 依存関係の順序で再設定、ビルド、テスト、インストールを行う。
- スキーマと、スタックに必要な生成ローダーキャッシュを再コンパイルする。
- pkg-config と ELF の解決を監査する。
- グラフがこれらの検査を通過した後にのみデバッガーを起動する。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)