Emscripten 是建構 WASM 應用程式的首選工具鏈。雖然還有其他幾個工具可用,例如 wasi-sdk 甚至是原生的 clang,但 Emscripten 有一些功能是讓許多類型的 C 函式庫開箱即可用的必要條件,最值得注意的是它們的 POSIX I/O API 代理支援。sqlite3 雖然可以使用其他工具鏈建構,但目前無法執行太多功能,因為載入產生的 WASM 檔案需要客戶端提供 I/O 層函式的實作(這是一項相當大的工程!)。
本頁說明在 Linux 上使用 Emscripten SDK 建構 sqlite3 的過程。在其他平台上尚未經過測試。使用透過 Linux 套件管理器安裝的 Emscripten 版本建構可能會成功也可能不會成功。
Emscripten SDK (又名 emsdk)
首先,按照這裡的說明安裝 Emscripten SDK,以下為 Linux 環境的摘要:
# Clone the emscripten repository:
$ sudo apt install git
$ git clone https://github.com/emscripten-core/emsdk.git
$ cd emsdk
# Download and install the latest SDK tools:
$ ./emsdk install latest
# Make the "latest" SDK "active" for the current user:
$ ./emsdk activate latest
這些部分只需要執行一次,但可以使用以下指令更新 SDK:
$ git pull
$ ./emsdk install latest
$ ./emsdk activate latest
根據慘痛的經驗提醒:如果更新 SDK 導致問題,請務必查看EMSDK 更新日誌,了解不相容的變更(例如,堆疊記憶體大小等預設值的變更)。
需要 emcc
編譯器的每個 shell 實例都需要執行以下指令:
# Activate PATH and other environment variables in the current terminal:
$ source /path/to/emsdk/emsdk_env.sh
$ which emcc
/path/to/emsdk/upstream/emscripten/emcc
或者,將其新增到您的登入 shell 的資源檔(~/.bashrc
或同等檔案)中
EMSDK_HOME=$HOME/src/emsdk
if [ -f "$EMSDK_HOME/emsdk_env.sh" ]; then
export EMSDK_HOME
export EMSDK_QUIET=1
source "$EMSDK_HOME/emsdk_env.sh"
fi
WABT 工具 (wasm-strip
)
wabt 工具包含 wasm-strip
,標準建構流程使用它來「剝離」產生的 .wasm
檔案,使其更小。
由於 Emscripten 混淆和縮小符號名稱的方法與 sqlite3 建構不相容(導致完全無法運作的 JS 檔案),因此必須使用 -g3
啟用完整的除錯資訊來建立建構。這會抑制 Emscripten 對符號的縮小,但也會導致巨大的 .wasm
檔案。然後可以使用 wasm-strip
移除除錯符號來縮小這些檔案。如果建構找到 wasm-strip
,就會自動使用它。如果找不到,建構會發出警告但仍可運作,主要的缺點是 .wasm
檔案會非常大。
如果 wasm-strip
警告「無效的程式碼區段」,則表示 wasm-strip
的版本太舊,只需要更新即可。
使用 Emscripten 建構 sqlite3
最簡單的方法是從 sqlite3 原始程式碼樹狀結構的頂端執行以下指令:
$ ./configure --enable-all
$ make sqlite3.c
$ cd ext/wasm
$ make
請注意,這裡的 make
是 GNU Make,在某些平台上稱為 gmake
。
該目錄中的GNUMakefile
包含用於建立結果 WASM 檔案的建構選項的完整詳細資訊。Emscripten 提供了數量驚人的設定,makefile 中包含關於其中幾個設定的說明,以及使用(或不使用)它們的原因。
待辦事項:擴展這些文件,提供「散文式指南」來建立自訂建構,而不是告訴客戶「只要修改 makefile 中的建構選項即可」。
Achtung:程式碼縮小
建置環境非常喜歡最小化所有程式碼,包含將程式碼符號縮減成短小的偽隨機版本。這種方法在所有參與的程式碼都被鎖在產生的 JS/WASM 模組中時運作良好,但對於打算供模組外部程式碼使用的函式庫(例如本專案)來說卻是致命的。
在所有高於 1 的最佳化等級中,Emscripten 都會嘗試最小化所有 JS 程式碼,即使透過 --minify 0
旗標告知不要這樣做。解決方法是永遠使用 -g3
(高除錯資訊等級)建置,然後使用 wasm-strip
移除產生的 WASM 檔案中的除錯資訊。