./configure
make
make installCOSCUP 2019 BSDTW x Cat System Workshop
FreeBSD Ports 和 FreeBSD 官方提供預先編譯好的套件,應該可以說是在 FreeBSD 上安 裝與管理軟體最常見也最簡便的方式。然而就如同許多作業系統或發行版本內建的套件管 理程式,一個設計作為系統管理用途的工具,對於開發或測試軟體本身的人來說總是有些 不方便。一來是開發與測試過程中需要經常修改原始碼,與套件管理程式將原始碼視為固 定不變輸入的假設並不相同;二來是開發與測試中的軟體通常不穩定,隨意安裝到系統上 可能會影響其他軟體或其他使用者。因此我們很常見到「穩定版本留在系統中、開發與測 試版本裝進家目錄」的作法。這樣的作法聽起來簡單,但對 C 和 C++ 這種與系統高度整 合卻沒有固定的編譯與安裝流程的語言來說就有些複雜了。使用者需要知道常用的編譯器 與連結器參數,也要知道常見用來自動化編譯與安裝的工具,例如 Autotools、CMake、 Meson,會使用哪些環境變數,又會如何使用這些環境變數。這個講題會以 GNOME 的 JHBuild 工具為例,介紹在家目錄中開發時常用的環境變數以及它們造成的效果與影響, 同時也提及 FreeBSD Ports 常用的變數與檔案,讓入門的使用者能認知到使用 FreeBSD Ports 和平時手動編譯的環境有什麼樣的不同,而不至於在精簡的 Makefile 中找不出也 猜不出每個變數的效果。
pkg add
pkg install
make install
portmaster
portupgrade
svn log 有舊版本也不見得能直接拿來使用。
./configure
make
make installconfigure 和 ports 預設都安裝到 /usr/local
make install 只會無條件覆蓋檔案。
make uninstall 也只會無條件刪除檔案。
./configure --prefix=/home/user/prefix make make install
/usr 和 /usr/local 也都是 prefix,因此這裡指定的 /home/user/prefix
是環境中的第三個 prefix。
./configure --prefix=/home/user/prefix make make DESTDIR=/home/user/dest install <手動將檔案從 DESTDIR 移入 prefix>
DESTDIR 變數更改 make install 時使用的目錄
DESTDIR 不是 prefix, DESTDIR 是為了打包和記錄檔案所用的暫時目錄,
prefix 才是最終安裝的位置。
./configure --prefix=/home/user/prefix make make DESTDIR=/home/user/dest install <手動將檔案從 DESTDIR 移入 prefix> <手動執行安裝完成的後續指令>
DESTDIR 通常會使 Makefile 跳過某些指令的執行
install-info 、 glib-compile-schemas 、fc-cache 、 update-desktop-database 、update-mime-database ……
ld-elf.so 要能找到函式庫、 man 要能找到 man pages、
dbus-daemon 要能找到服務……
cmake -G 'Unix Makefiles' -DCMAKE_INSTALL_PREFIX=/home/user/prefix . make make DESTDIR=/home/user/dest install
cmake -G Ninja -DCMAKE_INSTALL_PREFIX=/home/user/prefix . ninja DESTDIR=/home/user/dest ninja install
mkdir _build && cd _build meson --prefix=/home/user/prefix .. ninja DESTDIR=/home/user/dest ninja install
configure 和 make 的選項與變數問題。
lib/pkgconfig → libdata/pkgconfig
share/man → man
var/lib → var/db
PORTSDIR: /usr/ports
LOCALBASE: /usr/localPREFIX: /usr/localDISTDIR: /usr/ports/distfilesPACKAGES: /usr/ports/packagesmake package 生成的套件放這裡。
make [variable=value] [target ...]
-C <目錄> 先 cd 到指定目錄再開始執行。
-V <變數> 印出變數值。
.include <bsd.port.mk>/usr/share/mk 找 bsd.port.mk 並把它引入。
<分類>/<名稱> 這樣的目錄下
/usr/ports 底下的目錄都是 <分類> 。
make -C /usr/ports -V IGNOREDIR
Mk Templates Tools distfiles packages pkg Keywords
distfiles 和 packages 不是重點。
Mk ,原因請看 /usr/share/mk/bsd.port.mk 。
extract 解開下載來的原始碼。
patch 適當修改原始碼。
configure → ./configure --prefix=«prefix»
build → make
stage → make DESTDIR=<暫時目錄> install
package 把暫時目錄裡的東西打包成套件。
ls /usr/ports/graphics/librsvg2
distinfo Makefile pkg-descr pkg-plist
distinfo 和 pkg-descr 基本上不用解釋。
Makefile 和 pkg-plist 比較需要認真看。
ls /usr/ports/devel/glib20
distinfo files Makefile pkg-descr pkg-plist
files ,裡面大多是放 patch。
files 底下 patch- 開頭的檔案都會在 make patch 時拿去修改原始碼。
PORTNAME= librsvg PORTVERSION= 2.40.20 ... MASTER_SITES= GNOME ...
Mk 之類的地方去了。
MASTER_SITES 指定原始碼從哪裡下載。
GNOME 顯然不是個完整網址而只是個簡寫,詳情請看
Mk/bsd.port.mk 和 Mk/bsd.sites.mk 。
BUILD_DEPENDS= valac:lang/vala LIB_DEPENDS= libfreetype.so:print/freetype2 \ libfontconfig.so:x11-fonts/fontconfig \ libpng.so:graphics/png \ libcroco-0.6.so:textproc/libcroco
*_DEPENDS 指定相依性,可在 Mk/bsd.port.mk 找到。
USES= gettext gmake gnome libtool localbase pathfix pkgconfig tar:xz USE_GNOME= cairo gnomeprefix libgsf gdkpixbuf2 introspection:build \ libxml2 pango
USES 引入 Mk/Uses 底下對應名稱的 .mk 檔案。
USES 引入的檔案什麼事都可能做,例如:
gmake 和 localbase 增加相依套件、修改環境變數。
gnome 在 plist 加入檔案與安裝時要執行的指令。
libtool 和 pathfix 甚至用 sed 自動修改原始碼!
USES 可能會另外用其他變數來接收值,像是這裡的 USE_GNOME 。
PLIST_SUB+= PORTVERSION=${PORTVERSION} post-patch: @${REINPLACE_CMD} -e 's|GTK3_REQUIRED=3.[0-9][0-9].[0-9]|GTK3_REQUIRED=9.90.0|g' \ ${WRKSRC}/configure .include <bsd.port.mk>
PLIST 的變數大概可以猜到跟 pkg-plist 有關。
USES 可以用 sed 改檔案, Makefile 自己當然也可以。
Makefile 檔案中至少會有一行用來引入其他檔案。
...
share/gir-1.0/Rsvg-2.0.gir
share/thumbnailers/librsvg.thumbnailer
share/vala/vapi/librsvg-2.0.vapi
@postexec %D/bin/gdk-pixbuf-query-loaders > /dev/null 2>&1 && %D/bin/gdk-pixbuf-query-loaders > %D/lib/gdk-pixbuf-2.0/%%GTK2_VERSION%%/loaders.cache 2>/dev/null || /usr/bin/true
@postunexec %D/bin/gdk-pixbuf-query-loaders > /dev/null 2>&1 && %D/bin/gdk-pixbuf-query-loaders > %D/lib/gdk-pixbuf-2.0/%%GTK2_VERSION%%/loaders.cache 2>/dev/null || /usr/bin/true
pkg-plist 就是個列出套件裡有哪些檔案。
%%OSREL%% 的變數來減少重複的內容或是選擇性加入某些檔案。
@postexec 的關鍵字用來指示 pkg 打包過程中的特殊事項,像是
在安裝或移除時要執行的指令。
cc 。
ld ,通常由編譯器間接執行。
ar 和 ranlib 。
pkg-config 或 cmake 。
cc 需要知道放在 /usr/include 以外的標頭檔。
ld 需要知道放在 /usr/lib 和 /lib 以外的函式庫。
ar 和 ranlib 不需要知道,靜態函式庫沒有相依性。
pkg-config 和 cmake 需要找 .pc 和 .cmake 檔。
PATH 用來找執行檔。
LD_LIBRARY_PATH 用來找函式庫。
man 需要 MANPATH 、 info 需要 INFOPATH 。
gobject-introspection 需要 GI_TYPELIB_PATH 。
XDG_CONFIG_DIRS 和 XDG_DATA_DIRS 設定好就能滿足很多程式的需求了。
DISPLAY=:1 → :1
PATH=/a:/b/c:/d → ['/a', '/b/c', '/d']
-g3 -g2 -g1 → -g1
-Werror -Wno-error → -Wno-error
-I/a -I/b -I/c → ['/a', '/b', '/c']
make 或 ninja 而不是你自己。
./configure --help
CC C compiler command
CFLAGS C compiler flags
CPP C preprocessor
CPPFLAGS (Objective) C/C++ preprocessor flags,
e.g. -I<include dir>
LDFLAGS linker flags,
e.g. -L<lib dir>
LIBS libraries to pass to the linker,
e.g. -l<library>
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CXXCPP C++ preprocessor
CPPFLAGS (Objective) C/C++ preprocessor flags,
e.g. -I<include dir>
LDFLAGS linker flags,
e.g. -L<lib dir>
LIBS libraries to pass to the linker,
e.g. -l<library>
Makefile
$(CC) $(project_CPPFLAGS) $(CPPFLAGS) $(project_CFLAGS) $(CFLAGS) $(project_LDFLAGS) $(LDFLAGS) -o <輸出檔> <輸入檔> ... $(project_LIBADD/LDADD) $(LIBS)
make 填入變數值組出 shell 指令
make 變數來使用。
CPPFLAGS 。
輸出陣列 = shlex.split(輸入字串) 輸出字串 = ' '.join([shlex.quote(x) for x in 輸入陣列])
pkg-config 需要 PKG_CONFIG_PATH
.pc 檔供 pkg-config 使用。
cmake 需要 CMAKE_PREFIX_PATH
Find<專案名稱>.cmake 檔案。
詳情請看 man cmake-packages 。
CMAKE_PREFIX_PATH 環境變數 ≠ CMAKE_PREFIX_PATH 變數。
PKG_CONFIG_PATH='«prefix»/lib/pkgconfig:«prefix»/share/pkgconfig' CMAKE_PREFIX_PATH='«prefix»:/usr/local'
man gcc9
-I 選項和 CPATH 環境變數。
-isystem 選項和 C_INCLUDE_PATH 環境變數。
/usr/include 和編譯器內建路徑。
-idirafter 選項。
pkg-config 和類似功能的 script
pkg-config --cflags 回傳 CPPFLAGS 。
-I 選項指定路徑,擁有最高優先權。
atk → -I«prefix»/include/atk-1.0
gtk+-3.0 → -I«prefix»/include/gtk-3.0 ...
«prefix»/include 。
USES=localbase 是用 -isystem 選項。
C_INCLUDE_PATH 、 CPLUS_INCLUDE_PATH 等環境變數。
pkg-config 回傳的 -I 選項沒有順序
«prefix»/include 下,順序不同通常不會造成問題。
-I«prefix»/include 造成衝突,也許就只能用 CPATH 調整了。
# Ports 風格,注意 CMake 不支援 CPPFLAGS。 CPPFLAGS='-isystem «prefix»/include -isystem /usr/local/include' # JHBuild 風格,直接用環境變數告知編譯器路徑。 C_INCLUDE_PATH='«prefix»/include:/usr/local/include' CPLUS_INCLUDE_PATH='«prefix»/include:/usr/local/include' OBJC_INCLUDE_PATH='«prefix»/include:/usr/local/include'
man ld
-L 選項。
-Y 選項,LLVM lld 不支援。
ld
cc 幫忙補足參數並執行。
cc -print-prog-name=ld
/usr/bin/ld
cc -B/usr/local/bin -print-prog-name=ld
/usr/local/bin/ld
ld 。
cc 幫忙傳參數給 ld 時記得加 -Wl,
-L 和 -l 外幾乎都需要。
ld --verbose → cc -Wl,--verbose
pkg-config 和類似功能的 script
pkg-config --libs 回傳 LIBADD/LDADD 。
-L 選項指定路徑、 -l 選項指定函式庫名稱。
atk → -L«prefix»/lib -latk-1.0
gtk+-3.0 → -L«prefix»/lib -lgtk-3 ...
«prefix»/lib 。
USES=localbase 和 JHBuild 都用 -L 選項。
-Y 選項似乎相當罕見,應該不是設計來這樣使用的。
pkg-config 回傳的 -L 沒有順序
-L 的順序卻是相當重要!
«prefix»/lib 下,順序錯誤很容易因為版本不符而出現
undefined reference 錯誤。
# Ports 和 JHBuild 都是這樣用。 LDFLAGS='-L«prefix»/lib -L/usr/local/lib'
pkg-config --libs harfbuzz libpng
-L«prefix»/lib -lharfbuzz -L/usr/local/lib -lpng16 -lz
pkg-config --libs libpng harfbuzz
-L/usr/local/lib -lpng16 -lz -L«prefix»/lib -lharfbuzz
harfbuzz 。
LDFLAGS 蓋過去。
LDFLAGS 擺放的位置為什麼可以剛好蓋過去?
.so 檔絕對路徑代替 -L 和 -l 。
.pc 檔都是用 -L 和 -l 。
-l 指定的函式庫在 -L 找不到怎麼辦?
ld 自己找到 .so 檔。
libc.so.92.5 沒有 libc.so 怎麼辦?
$(CC) ... $(project_LDFLAGS) $(LDFLAGS) ... $(project_LIBADD/LDADD) $(LIBS)
$(CC) ... $(內部參數與函式庫) $(LDFLAGS) ... $(外部參數與函式庫)
LDFLAGS 能蓋過普通參數,但不能蓋過搜尋路徑。
pkg-config 從系統上找到的函式庫(已安裝)
LDFLAGS 的 -L 蓋過 pkg-config 回傳的 -L 。
hello 專案,它需要 prefix 的 harfbuzz 和 ports 的
freetype 。
cc ... -L../libhello -lhello # 內部函式庫 ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lharfbuzz # 外部函式庫 ... -L/usr/local/lib -lfreetype # 外部函式庫
cc ... -L../libhello -lhello # 內部函式庫 ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L/usr/local/lib -lfreetype # 外部函式庫 ... -L«prefix»/lib -lharfbuzz # 外部函式庫
pkg-config 回傳的 -l = 專案需要的外部函式庫?
pkg-config 回傳的 -l ⊆ 專案需要的外部函式庫。
readelf -d 看看 NEEDED
$ readelf -d /usr/local/lib/libfreetype.so
Tag Type Name/Value
0x... NEEDED Shared library: [libbz2.so.4]
0x... NEEDED Shared library: [libpng16.so.16]
0x... NEEDED Shared library: [libz.so.6]
0x... NEEDED Shared library: [libc.so.7]
ld 去哪裡找這些函式庫?
man ld (GNU Binutils)
-rpath-link 選項。
-rpath 選項。
LD_RUN_PATH 環境變數。(ELF, native linker)-rpath-link 和 -rpath 時使用。
-L 選項。(SunOS)
LD_LIBRARY_PATH 環境變數。(native linker)
DT_RUNPATH 和 DT_RPATH 。(native linker)
/lib 和 /usr/lib 。
/etc/ld.so.conf 中的路徑。
-L 搜尋。
-rpath* 系列和 LD_LIBRARY_PATH 。
-L 和 -l 以避免 -L 順序問題,
但間接依賴的不行。
ld 去哪裡找了不合適的 .so 檔來用時,
就把 --verbose 加下去吧。
LIBRARIES 只支援靜態函式庫。
LTLIBRARIES 支援動態函式庫。
autoreconf -fi 來更新。
autoreconf 很慢?看看 USES=libtool 做了什麼。
libglib-2.0.so.3792 無論大小更新,只要更新後面的數字就改變,
SONAME 也跟著變,會如何?
.la 和 .lo 的檔案供內部使用
.la 檔案安裝到系統上。
.la 就以爲是內部函式庫
.la 安裝到系統上有何意義
pkg-config --static 。
.la 砍掉
USES=libtool 。
.la 就覺得是內部函式庫。
pango 和 gmp ,並且設定好環境, pango 來自 prefix,
gmp 來自 ports。
cc ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lpango-1.0 ... # Pango ... -L/usr/local/lib -lgmp # GMP
libgmp.la 存在會造成什麼問題?
cc ... -L/usr/local/lib -lgmp ... # GMP ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lpango-1.0 ... # Pango
main.o: In function `main':
main.c: undefined reference to `pango_font_family_is_variable'
main.c: undefined reference to `pango_font_metrics_get_height'
main.c: undefined reference to `pango_font_family_is_variable'
main.c: undefined reference to `pango_font_get_hb_font'
.la 讓 -L 出現在錯誤的地方,改變函式庫搜尋順序。
cc ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lpango-1.0 ... # Pango ... /usr/local/lib/libgmp.so # GMP ... -Wl,-rpath=/usr/local/lib
.../libpango-1.0.so: undefined reference to `fribidi_get_par_embedding_levels_ex'
.../libpango-1.0.so: undefined reference to `fribidi_get_bracket'
.la 使用 -rpath 結果讓改變了搜尋相依函式庫的路徑。
pango 需要 prefix 裡的 fribidi ,可是出現 -rpath 造成 ld
去 /usr/local/lib 找 fribidi 。
cc ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lpango-1.0 ... # Pango ... -L/usr/local/lib -lgmp # GMP ... -Wl,--verbose
attempt to open «prefix»/lib/libpango-1.0.so succeeded
-lpango-1.0 («prefix»/lib/libpango-1.0.so)
attempt to open «prefix»/lib/libgmp.so failed
attempt to open «prefix»/lib/libgmp.a failed
attempt to open /usr/local/lib/libgmp.so succeeded
-lgmp (/usr/local/lib/libgmp.so)
...
libfribidi.so.0 needed by «prefix»/lib/libpango-1.0.so
found libfribidi.so.0 at «prefix»/lib/libfribidi.so.0
cc ... -L«prefix»/lib -L/usr/local/lib # LDFLAGS ... -L«prefix»/lib -lpango-1.0 ... # Pango ... /usr/local/lib/libgmp.so # GMP ... -Wl,-rpath=/usr/local/lib ... -Wl,--verbose
attempt to open «prefix»/lib/libpango-1.0.so succeeded
-lpango-1.0 («prefix»/lib/libpango-1.0.so)
attempt to open /usr/local/lib/libgmp.so succeeded
/usr/local/lib/libgmp.so
...
libfribidi.so.0 needed by «prefix»/lib/libpango-1.0.so
found libfribidi.so.0 at /usr/local/lib/libfribidi.so.0
.la 檔案的。
libltdl 函式庫。
USES=libtool:keepla 。
USES=libtool:keepla 的 ports 真的都需要 .la 檔案,
很多時候只是沒有人去測試而已。
PATH="«prefix»/bin:«prefix»/sbin:${PATH}"
PATH 沒有什麼特別的,按照自己的習慣去設定就行了。
LD_LIBRARY_PATH="«prefix»/lib:${LD_LIBRARY_PATH}"
LD_LIBRARY_PATH 用來指示 runtime linker (rtld) 應該優先搜尋的函式庫
路徑,但是可執行檔本身也能指定搜尋路徑。
man ld.so 或是 man rtld
DT_RPATH 。(deprecated)
LD_LIBRARY_PATH 環境變數。
DT_RUNPATH 。
ldconfig 生成的 hints 檔案,通常是由 /etc/rc.d/ldconfig 在開機過程中從
/etc/rc.conf 的設定和 /usr/local/libdata/ldconfig 中的檔案生成。
/lib 和 /usr/lib 。
LD_LIBRARY_PATH_RPATH 和
LD_LIBRARY_PATH_FDS 。其他檔案像是 /etc/libmap.conf 也會影響函式庫載入。
DT_RPATH 不能被 LD_LIBRARY_PATH 覆蓋。
ld --disable-new-dtags 遇到 -rpath 產生。
DT_RUNPATH 可以被 LD_LIBRARY_PATH 覆蓋。
ld --enable-new-dtags 遇到 -rpath 產生。
DT_RUNPATH。
cc -v 可以看到 cc 在預設情況下會傳 --enable-new-dtags 給 ld 。
$ readelf -d «prefix»/bin/gnome-shell
Tag Type Name/Value
0x... NEEDED Shared library: [libgnome-shell.so]
0x... NEEDED Shared library: [libmutter-clutter-5.so.0]
0x... NEEDED Shared library: [libmutter-cogl-pango-5.so.0]
...
0x... RUNPATH Library runpath: [«prefix»/lib/mutter-5:«prefix»/lib/gnome-shell]
...
$ chrpath «prefix»/bin/gnome-shell
«prefix»/bin/gnome-shell: RUNPATH=«prefix»/lib/mutter-5:«prefix»/lib/gnome-shell
$ patchelf --print-rpath «prefix»/bin/gnome-shell
«prefix»/lib/mutter-5:«prefix»/lib/gnome-shell
make install ,要如何執行編譯出來的程式?
LD_LIBRARY_PATH 會讓 rtld 優先搜尋你的 prefix。
cairo ,想要執行專案中的 cairo-test-suite 測試程式,你會
希望它用的是剛才編譯出來的那個 libcairo.so.2 而不是去 prefix 找。
Makefile.am 指定的位置
libtool --mode=execute 。
DT_RPATH
-rpath 讓你可以直接執行。
DT_RUNPATH
LD_LIBRARY_PATH 再去執行程式。
$ ./bin/gegl --help
usage: .../bin/.libs/gegl [options] <file | -- [op [op] ..]>
...
$ file ./bin/gegl
./bin/gegl: POSIX shell script, ASCII text executable
$ ldd ./bin/gegl
ldd: ./bin/gegl: not a dynamic executable
$ libtool --mode=execute ldd ./bin/gegl
.../bin/.libs/gegl:
libgegl-0.4.so.0 => .../gegl/.libs/libgegl-0.4.so.0 (0x80082a000)
libgmodule-2.0.so.0 => «prefix»/lib/libgmodule-2.0.so.0 (0x800af0000)
libjson-glib-1.0.so.0 => «prefix»/lib/libjson-glib-1.0.so.0 (0x800cf3000)
...
-rpath 可以解決所有事
LD_LIBRARY_PATH 會把 DT_RUNPATH 蓋掉。
DT_RPATH 並不是個解法
DT_RPATH 已經被標記為 deprecated 非常多年了。
$ jhbuild buildone colord
...
[107/215] Generating AppleRGB.icc with a custom command.
FAILED: data/profiles/AppleRGB.icc
.../client/cd-create-profile --output=data/profiles/AppleRGB.icc data/profiles/AppleRGB.iccprofile.xml
.../client/cd-create-profile: Undefined symbol "cd_icc_set_created"
ninja: build stopped: subcommand failed.
$ jhbuild buildone babl
...
[186/189] Generating index.html.tmp with a meson_exe.py custom command.
FAILED: docs/index.html.tmp
«prefix»/bin/meson --internal exe .../meson-private/meson_exe_env_1e391eda23a81f355345fa1aadd0bf6fc89c918d.dat
«prefix»/lib/libbabl-0.1.so.0: version V0_1_0 required by .../tools/babl-html-dump not defined
ninja: build stopped: subcommand failed.
XDG_CONFIG_DIRS='«prefix»/etc/xdg:/usr/local/etc/xdg:/etc/xdg' XDG_DATA_DIRS='«prefix»/share:/usr/local/share:/usr/share'
dbus-daemon 根據 XDG base directory specification 找服務
XDG_DATA_DIRS 環境變數控制。
dbus-daemon 通常是由桌面環境用 dbus-launch 啟動的,可能會需要在啟動桌面
前就先設定好環境變數。
dbus-daemon
主動執行指定程式。
dbus-update-activation-environment 可以設定 dbus-daemon 啟動服務時的
環境變數。
MANPATH="«prefix»/share/man:/usr/local/man:$(manpath)" INFOPATH='«prefix»/share/info:/usr/local/share/info'
man 只要看到 MANPATH 環境變數就會忽略其他的搜尋路徑,所以要手動
把 manpath 列出的路徑加上去。
info 沒有這樣的現象,因此不需自己找出預設路徑。
ACLOCAL_PATH='«prefix»/share/aclocal:/usr/local/share/aclocal' GI_TYPELIB_PATH='«prefix»/lib/girepository-1.0:/usr/local/lib/girepository-1.0' GST_PLUGIN_PATH_1_0='«prefix»/lib/gstreamer-1.0:/usr/local/lib/gstreamer-1.0' PERL5LIB='«prefix»/lib/perl5:/usr/local/lib/perl5' PYTHONPATH='«prefix»/share/jhbuild/sitecustomize' XCURSOR_PATH='«prefix»/share/icons:/usr/local/share/icons'
PYTHONPATH 是這之中比較特別的,因為這個變數會同時被 Python 2 和 Python 3
使用。
sitecustomize 模組來動態設定 sys.path 。
venv 不太正常,使用 venv 前應自行拿掉 PYTHONPATH 。
DESTDIR 就要自己處理這些事。
/usr/ports/Keywords 目錄。
triggers 目錄。
# IfExecutable: update-desktop-database # REMatch: ^share/applications/.*\.desktop update-desktop-database -q # IfExecutable: update-mime-database # REMatch: /mime/packages/.*\.xml update-mime-database "$JHBUILD_PREFIX/share/mime" # IfExecutable: install-info # REMatch: ^share/info/.*\.info rm -f "$JHBUILD_PREFIX/share/info/dir-new" for info in "$JHBUILD_PREFIX/share/info/"*.info; do install-info "$info" "$JHBUILD_PREFIX/share/info/dir-new" done mv "$JHBUILD_PREFIX/share/info/dir-new" "$JHBUILD_PREFIX/share/info/dir"
sudo make install 。
DESTDIR 和安裝後續指令這件事。
CPPFLAGS 、 LDFLAGS 、
PKG_CONFIG_PATH 、 CMAKE_PREFIX_PATH 。
PATH 、 LD_LIBRARY_PATH 、
XDG_CONFIG_DIRS 、 XDG_DATA_DIRS 。
LD_LIBRARY_PATH 和 -rpath 可能造成不可靠的結果。
DT_SONAME 問題,使用前應先檢查。
.la 檔裝到系統上通常只會製造問題,記得刪除。