./configure
make
make install
COSCUP 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 install
configure
和 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/local
PREFIX: /usr/local
DISTDIR: /usr/ports/distfiles
PACKAGES: /usr/ports/packages
make 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
檔裝到系統上通常只會製造問題,記得刪除。