GNOME 開發環境

最後更新: 2021-05-31 01:36:17 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

跨 GLib 與 GTK 偵錯需要一致的相依性圖。如果 GTK 載入開發用 libgtk,卻從主機解析 GLib、Pango 或 GDK Pixbuf,來源行與執行期型別便不再對應至單一一致的建置。隔離的安裝前綴可提供這種一致性,而不必取代發行版套件。

選擇隔離邊界 #

GNOME 建議應用程式開發使用 Builder,函式庫、服務與主機整合模組使用 Toolbx。JHBuild 仍可用於建置相依性圖。相較於手寫指令碼,這些工具編碼了更多圖的內容,應優先用於持續貢獻工作。

手動 Meson/Ninja 前綴仍適合來源檢查或小型受控堆疊。可行時請在容器或可拋棄的開發環境中使用它。前綴隔離已安裝檔案,而容器隔離仍來自發行版的建置工具與相依項。

GLib、GObject、GModule、GThread 與 GIO 都從相同的 GLib 儲存庫 建置;GObject 不是分開的來源檢出。GTK 是分開的儲存庫。GTK 的確切相依項集合會隨啟用的 Wayland、X11、Vulkan、文件與 introspection 功能而變化,因此每次檢出的 README.md、meson_options.txt 與 Meson 錯誤訊息,才是該修訂版本的權威資料。

安裝發行版的編譯器、Python、Meson、Ninja、pkg-config,以及啟動圖所需的開發標頭。文件建置可能另外需要 gi-docgen、Graphviz 與 Doxygen 等工具;不是每個 GLib 或 GTK 設定都需要它們。

定義單一開發前綴 #

讓來源、建置目錄與已安裝成品分開:

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

啟用指令碼會讓所有探索路徑指向相同前綴:

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}"

每次 Meson 設定時設定 --libdir=lib,可使這些路徑不受發行版 lib64 或多架構預設值影響。PKG_CONFIG_PATH 會先搜尋前綴,但仍允許回退至主機。整個所需相依性閉包都安裝至前綴後,嚴格建置可以改用:

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

PKG_CONFIG_LIBDIR 會抑制 pkg-config 的標準搜尋目錄。過早啟用它也會隱藏 libffi、PCRE2、FreeType 與 Fontconfig 等啟動函式庫,因此請將它們建置至前綴,或使用具有明確文件化主機基線的容器。

不要將此啟用內容放入登入設定檔。LD_LIBRARY_PATH 會套用至從 shell 啟動的每個程序,可能使無關的主機應用程式載入 ABI 不相容的開發函式庫。

依相依順序建置 #

先建置葉節點,再建置根節點,因為 Meson 會在設定每個建置目錄時解析相依項。GTK 堆疊通常包含以下群組:

  1. GLib 的啟動相依項,包括 libffi 與 PCRE2。
  2. GLib,它會一同產生 GLib、GObject 與 GIO。
  3. 圖形與文字相依項,例如 pixman/Cairo、FreeType、Fontconfig、HarfBuzz、GDK Pixbuf、Pango、Graphene 與 libepoxy。
  4. 後端相依項,例如 Wayland 與 wayland-protocols,或所需的 X11 函式庫。
  5. GTK,接著是在專案需要時的語言繫結,例如 gtkmm。

中間群組內的相依邊會取決於選取的功能。使用 JHBuild 或 GNOME Build Metadata 提供的拓撲模組集合,比跨版本複製固定清單更安全。

每個 Meson 專案都可以使用相同建置函數:

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"
}

從已載入 env.sh 的 shell 執行函數:

sh
mkdir -p "$PREFIX"

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

兩個呼叫顯示的是端點,不是完整 GTK 建置計畫。請依模組集合的拓撲順序,對 GLib 與 GTK 之間每個從來源建置的相依項呼叫相同函數。

Meson 目前的 debug 建置型別相當於具備偵錯資訊與最佳化等級 0,但明確寫出 debug、optimization 與 strip 可讓預期的偵錯器行為可見。檢查 meson configure _build 後,各專案可以加入功能選項;停用不需要的後端,比意外從主機滿足它更好。

安裝每個完成層很重要,因為下一個專案會在同一前綴下找到其標頭、.pc 檔案、共用物件、結構描述與 introspection 資料。提供結構描述的專案安裝後,請編譯已安裝的結構描述:

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

防止混合系統建置 #

Meson 設定後立即檢查相依性解析:

sh
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 解析,而不要信任連結時輸出:

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

來源建置閉包中的所有函式庫都應解析至 $PREFIX 以下。系統 C 函式庫、動態載入器、GPU 驅動程式與刻意保留的啟動相依項可能仍從主機解析。請記錄該邊界,而不要宣稱完全隔離。

rpath 可以使二進位檔不使用 LD_LIBRARY_PATH 也能使用:

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

請使用上方顯示的逗號分隔連結器形式。rpath 只會改變執行期載入,不會影響 Meson 選取的標頭或 .pc 中繼資料。仍然需要檢查 pkg-config。

讓更新可重複 #

每個上游儲存庫只複製一次:

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

對所選模組集合中從來源建置的相依項套用相同模式。後續更新不應刪除未追蹤工作:

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

對每個相依項,在鎖定檔或建置記錄中記錄已測試的提交。「目前來源」會持續變化;提交 ID 讓成功的圖可重現。先更新葉節點,再重新建置並安裝相依者。只有選項或偵測到的相依項變更時,使用 meson setup --reconfigure;只有在必須捨棄快取狀態時,才對產生的建置目錄使用 meson setup --wipe。

避免在更新指令碼中使用 git clean -fdx,因為它會破壞未追蹤的來源工作。建置目錄已提供可替換的邊界。

偵錯已安裝的圖 #

從已啟用的環境執行偵錯器:

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

有用的初始檢查如下:

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

info sharedlibrary 應顯示預期前綴。如果中斷點解析至系統路徑,請在偵錯應用程式邏輯前檢查 LD_DEBUG=libs、ldd、pkg-config 前綴與 Meson 相依性報告。可以使用 GDB 的 directory 或 set substitute-path 修正來源查詢,但路徑替換無法修復連結至錯誤函式庫的二進位檔。

因此,更新工作流程是確定性的:

  1. 啟用環境。
  2. 擷取固定或選定的提交。
  3. 依相依順序重新設定、建置、測試與安裝。
  4. 重新編譯結構描述與堆疊所需的任何產生載入器快取。
  5. 稽核 pkg-config 與 ELF 解析。
  6. 只有在圖通過這些檢查後才啟動偵錯器。

上游參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)