Emscripten 編譯器前端 (emcc)

Emscripten 編譯器前端 (emcc) 用於從命令列呼叫 Emscripten 編譯器。它實際上是標準編譯器(如 gccclang)的直接替代品。

命令列語法

emcc [options] file...

(請注意,如果您想從目前目錄執行 emcc,您需要 ./emcc。)

輸入檔案可以是 Clang 可以處理的原始碼檔案(C 或 C++)、物件檔案(由 emcc -c 產生)或 LLVM 組譯檔案。

引數

大多數 clang 選項都會起作用,gcc 選項也會起作用,例如

# Display this information
emcc --help

# Display compiler version information
emcc --version

若要查看 Emscripten 使用的 Clang 版本支援的完整 Clang 選項列表,請執行 clang --help

以下列出在 emcc 中修改或新增的選項

-O0

[編譯+連結] 無最佳化 (預設)。這是開始移植專案的建議設定,因為它包含各種斷言。

此設定和其他最佳化設定在編譯和連結期間都有意義。在編譯期間,它會影響 LLVM 最佳化,而在連結期間,它會影響 Binaryen 中程式碼的最終最佳化,以及 JS 的最佳化。(對於快速增量建置,-O0 最佳,而對於發行版本,您應該使用更高的設定進行連結。)

-O1

[編譯+連結] 簡單最佳化。在編譯步驟期間,這些包括 LLVM -O1 最佳化。在連結步驟期間,這不包含 -O0 會執行的 JS 中各種執行階段斷言。

-O2

[編譯+連結] 類似 -O1,但啟用更多最佳化。在連結期間,這也會啟用各種 JavaScript 最佳化。

注意

這些 JavaScript 最佳化可以透過移除編譯器看不到正在使用的內容來減少程式碼大小,特別是,如果未在 Module 物件上匯出,則可能會移除部分執行階段。編譯器知道 –pre-js–post-js 中的程式碼,因此您可以安全地從那裡使用執行階段。或者,您可以使用 EXPORTED_RUNTIME_METHODS,請參閱 src/settings.js

-O3

[編譯+連結] 類似 -O2,但具有可能需要較長時間執行的額外最佳化。

注意

這是發行建置的良好設定。

-Og

[編譯+連結] 類似 -O1。在未來版本中,此選項可能會停用不同的最佳化,以提高除錯能力。

-Os

[編譯+連結] 類似 -O3,但更側重於程式碼大小(並且可能會在速度方面做出取捨)。這可能會影響 Wasm 和 JavaScript。

-Oz

[編譯+連結] 類似 -Os,但會進一步縮減程式碼大小,並且可能需要較長時間才能執行。這可能會影響 Wasm 和 JavaScript。

注意

如需最佳化程式碼的更多提示,請參閱 程式碼最佳化

-sOPTION[=VALUE]

[不同的 OPTION 在不同的階段影響,大多數在連結時間] Emscripten 建置選項。如需可用的選項,請參閱 src/settings.js

注意

如果未指定值,則預設為 1

注意

對於布林值選項,可以使用 NO_ 前置詞來反轉其含義。例如,-sEXIT_RUNTIME=0-sNO_EXIT_RUNTIME=1 相同,反之亦然。在大多數情況下,不建議這樣做。

注意

清單可以指定為逗號分隔的字串

-sEXPORTED_FUNCTIONS=foo,bar

注意

我們也支援涉及更多引號的舊清單格式。清單可以指定為每個元素周圍帶有或不帶有引號,並且清單周圍帶有或不帶有括號。例如,以下所有內容都等效

-sEXPORTED_FUNCTIONS="foo","bar"
-sEXPORTED_FUNCTIONS=["foo","bar"]
-sEXPORTED_FUNCTIONS=[foo,bar]

注意

對於包含括號或引號的清單,您需要在大多數 Shell 中使用引號 (”) 括住清單(以避免引發錯誤)。以下顯示兩個範例

-sEXPORTED_FUNCTIONS="['liblib.so']"
-s"EXPORTED_FUNCTIONS=['liblib.so']"

您也可以指定從檔案讀取選項的值。例如,以下內容將根據 path/to/file 檔案的內容設定 EXPORTED_FUNCTIONS

-sEXPORTED_FUNCTIONS=@/path/to/file

注意

  • 在這種情況下,該檔案應包含符號清單,每行一個符號。對於舊版使用案例,也支援 JSON 格式的檔案:例如 ["_func1", "func2"]

  • 指定的檔案路徑必須是絕對路徑,而不是相對路徑。

  • 檔案可以包含註解,其中行的第一個字元為 '#'

注意

選項可以指定為單一引數,且 -s 與選項名稱之間有或沒有空格。例如 -sFOO-s FOO。強烈建議您使用不帶空格的表示法。

-g

[編譯+連結] 保留除錯資訊。

  • 編譯為物件檔案時,這與 Clanggcc 中的相同,它會將 DWARF 除錯資訊新增至物件檔案。

  • 連結時,這相當於 -g3

-gseparate-dwarf[=FILENAME]

[如果在編譯時傳遞,則與 -g3 相同,否則在連結時套用] 保留除錯資訊,但放在側邊的個別檔案中。這與 -g 相同,但主要檔案不會包含除錯資訊。相反地,除錯資訊將存在於側邊的檔案中,如果提供 FILENAME,則存在於該檔案中,否則與 Wasm 檔案相同,但帶有後綴 .debug.wasm。雖然主要檔案不包含除錯資訊,但它確實包含除錯檔案位置的 URL,以便開發人員工具可以找到它。您可以使用 -sSEPARATE_DWARF_URL=URL 來客製化該位置(例如,如果您想將其託管在不同的伺服器上,這會很有用)。

-gsplit-dwarf

啟用除錯裂變,這會建立與 wasm 物件檔案並排的分割 DWARF 物件檔案。此選項必須與 -c 一起使用。

-gsource-map

[連結] 使用 LLVM 除錯資訊產生原始碼對應表(必須存在於目標檔案中,也就是說,它們應該使用 -g 進行編譯)。當提供此選項時,.wasm 檔案會更新為具有 sourceMappingURL 區段。產生的 URL 格式將為:<base-url> + <wasm-file-name> + .map<base-url> 預設為空(表示原始碼對應表與 Wasm 檔案位於同一目錄)。可以使用 --source-map-base 變更。

-g<層級>

[編譯+連結] 控制除錯能力等級。每個層級都建立在前一個層級的基礎之上。

  • -g0:不努力保持程式碼可除錯。

  • -g1:連結時,保留 JavaScript 中的空白。

  • -g2:連結時,保留編譯後程式碼中的函式名稱。

  • -g3:當編譯為目標檔案時,保留除錯資訊,包括 JS 空白、函式名稱和 LLVM 除錯資訊(DWARF)(如果有的話)(與 -g 相同)。

--profiling

[編譯時與 -g2 相同,否則在連結時應用] 當發出 JavaScript 時使用合理的預設值,使建置可讀,但仍可用於分析。這會設定 -g2(保留空白和函式名稱),也可能會啟用影響效能且在 -g2 中可能不會執行的最佳化。

--profiling-funcs

[連結] 在分析時保留函式名稱,但在其他方面會像在最佳化建置中一樣縮小空白和名稱。如果您想根據函式名稱查看分析器結果,但不打算閱讀發出的程式碼,這會很有用。

--tracing

[連結] 啟用 Emscripten 追蹤 API

--reproduce=<file.tar>

[編譯+連結] 寫入包含輸入和命令的 tar 檔案,以重現調用。分享此檔案時,請注意它將包含傳遞給編譯器的任何目標檔案、原始碼檔案和程式庫。

--emit-symbol-map

[連結] 在 Wasm 中的函式索引與函式名稱之間儲存一個對應檔。透過將名稱儲存在側邊的檔案中,您可以避免傳送名稱,並且仍然可以透過將索引轉換回名稱來重建有意義的堆疊追蹤。

注意

當與 -sWASM=2 一起使用時,會建立兩個符號檔案。[name].js.symbols(具有 WASM 符號)和 [name].wasm.js.symbols(具有 ASM.js 符號)

--emit-minification-map <檔案>

[連結] 在 emscripten 執行匯入/匯出縮小的情況下,可以使用此選項輸出一個檔案,將縮小的名稱對應回其原始名稱。此檔案的格式為每個匯入/匯出單行,格式為 <縮小的名稱>:<原始名稱>

-flto

[編譯+連結] 啟用連結時最佳化 (LTO)。

--closure 0|1|2

[連結] 執行 Closure Compiler。可能的值為

  • 0:無 Closure Compiler(在 -O2 及以下為預設值)。

  • 1:執行 Closure Compiler。這會大幅縮減支援 JavaScript 程式碼的大小(除了 WebAssembly 或 asm.js 的所有程式碼)。請注意,這會顯著增加編譯時間。

  • 2:在所有發出的程式碼上執行 Closure Compiler,甚至在 asm.js 模式下的 asm.js 輸出上也是如此。這可以進一步縮減程式碼大小,但會阻止大量的 asm.js 最佳化,因此除非您想不惜一切代價縮減程式碼大小,否則不建議使用。

注意

  • 使用 Closure 時,請考慮使用 -sMODULARIZE,因為它會將全域變數縮小為可能與全域範圍中其他變數衝突的名稱。MODULARIZE 會將所有輸出放入函式中(請參閱 src/settings.js)。

  • Closure 預設會縮小 Module 本身的名稱!使用 MODULARIZE 也可以解決此問題。另一個解決方案是確保在執行經過 Closure 編譯的程式碼之前,已存在一個名為 Module 的全域變數,因為它會重複使用該變數。

  • 只有在執行 JavaScript 選項時 ( -O2 或以上) 才會執行 Closure。

--closure-args=<args>

[連結] 將引數傳遞給 Closure Compiler。這是 EMCC_CLOSURE_ARGS 的替代方案。

例如,可能會想要傳遞一個 externs 檔案,以避免縮小在 --pre-js--post-js 檔案中定義的 JS 函式。為了將 externs.js 檔案傳遞給 Closure,其中包含不應縮小的那些公用 API,可以新增標誌:--closure-args=--externs=path/to/externs.js

--pre-js <檔案>

[連結] 指定一個檔案,其內容會新增到發出的程式碼之前,並與其一起進行最佳化。請注意,這可能不會是 JS 輸出中的第一個項目,例如,如果使用 MODULARIZE(請參閱 src/settings.js)。如果您想要這樣,您可以直接附加到 emscripten 的輸出;--pre-js 的好處是它會將程式碼與其餘 emscripten 輸出一起最佳化,這允許更好的無用程式碼消除和縮小,而且它只應出於此目的使用。特別是,--pre-js 程式碼不應以可能會混淆最佳化工具的方式變更 emscripten 的主要輸出,例如使用 --pre-js + --post-js 將所有輸出放入內部函式範圍(請參閱 MODULARIZE)。

--pre-js(但不是 --post-js)也適用於在 Module 物件上指定項目,因為它會在 JS 查看 Module 之前出現(例如,您可以在那裡定義 Module['print'])。

--post-js <檔案>

[連結] 與 --pre-js 類似,但會在發出的程式碼之後發出檔案。

--extern-pre-js <檔案>

[連結] 指定一個檔案,其內容會附加到 JavaScript 輸出之前。此檔案會附加到最終 JavaScript 輸出之前,完成所有其他工作之後,包括最佳化、選擇性的 MODULARIZE 化、SAFE_HEAP 等檢測。這與在 emcc 完成執行後附加此檔案相同,而且這只是一種方便的方法。(為了比較,--pre-js--post-js 會將程式碼與所有其他程式碼一起最佳化,如果執行 MODULARIZE,則會將其保留在相同的範圍內等等)。

--extern-post-js <檔案>

[連結] 與 --extern-pre-js 類似,但會附加到結尾。

--embed-file <檔案>

[連結] 指定要嵌入到產生的 WebAssembly 模組中的檔案(含路徑)。該路徑是相對於編譯時的目前目錄。如果在這邊傳遞目錄,則會嵌入其所有內容。

例如,如果命令包含 --embed-file dir/file.dat,則 dir/file.dat 必須存在於您執行 emcc 的目錄的相對位置。

注意

嵌入檔案通常比 預先載入 更有效率,因為它可以避免在執行階段複製檔案資料。

如需關於 --embed-file 選項的詳細資訊,請參閱 封裝檔案

--preload-file <名稱>

[連結] 指定要在非同步執行編譯後程式碼之前預先載入的檔案。該路徑是相對於編譯時的目前目錄。如果在這邊傳遞目錄,則會嵌入其所有內容。

預先載入的檔案會儲存在 filename.data 中,其中 filename.html 是您要編譯的主檔案。為了執行您的程式碼,您將需要 .html.data

注意

此選項與 --embed-file 類似,只是它只在產生 HTML 時相關(它使用非同步二進位 XHR),或是將在網頁中使用的 JavaScript。

emcc 執行 tools/file_packager 來進行嵌入和預載檔案的實際封裝。如果你想的話,可以自己執行檔案封裝器(請參閱 使用檔案封裝器工具進行封裝)。然後,您應該將檔案封裝器的輸出放在 emcc 的 --pre-js 中,以便它在您的主要編譯程式碼之前執行。

有關 --preload-file 選項的更多資訊,請參閱 封裝檔案

--exclude-file <name>

[連結] 從 --embed-file--preload-file 中排除的檔案和目錄。支援萬用字元 (*)。

--use-preload-plugins

[連結] 告知檔案封裝器在載入檔案時執行預載外掛程式。這會執行諸如使用瀏覽器的編解碼器解碼圖像和音訊等任務。

--shell-file <path>

[連結] 當生成 HTML 輸出時使用的骨架 HTML 檔案的路徑名稱。使用的 shell 檔案需要在其中包含此符記:{{{ SCRIPT }}}

注意

--source-map-base <base-url>

[連結] WebAssembly 來源對應將發布的位置的基礎 URL。必須與 -gsource-map 一起使用。

--minify 0

[如果在編譯時傳遞,則與 -g1 相同,否則在連結時套用] 與 -g1 相同。

--js-transform <cmd>

[連結] 指定要在最佳化之前對產生的程式碼呼叫的 <cmd>。這讓您可以修改 JavaScript,例如新增或移除某些程式碼,使得這些修改會與產生的程式碼一起最佳化。

<cmd> 將使用產生程式碼的檔案名稱作為參數呼叫。要修改程式碼,您可以讀取原始資料,然後附加或覆寫為修改後的資料。

<cmd> 會被解譯為以空格分隔的參數列表,例如,<cmd>python processor.py 將導致 Python 腳本執行。

--bind

[連結] 連結 embind 程式庫。已棄用:請改用 -lembind

--embind-emit-tsd <path>

[連結] 產生 TypeScript 定義檔案。已棄用:請改用 --emit-tsd

--emit-tsd <path>

[連結] 為 emscripten 模組產生 TypeScript 定義檔案。定義檔案將包含匯出的 Wasm 函數、執行階段匯出和匯出的 embind 繫結(如果使用)。為了從 embind 產生繫結,程式將在節點中進行檢測和執行。

--ignore-dynamic-linking

[連結] 告知編譯器忽略動態連結(使用者稍後需要手動連結到共享程式庫)。

通常,emcc 會簡單地將動態程式庫中的程式碼連結進來,如同它是靜態連結一樣,如果同一個動態程式庫被連結多次,將會失敗。使用此選項,動態連結會被忽略,這允許建置系統繼續進行而不會發生錯誤。

--js-library <lib>

[連結] 除了 Emscripten 核心程式庫 (src/library_*) 中的程式庫之外,要使用的 JavaScript 程式庫。

-v

[一般] 開啟詳細輸出。

這將印出 emscripten 執行的內部子命令以及 Clang-v

提示

emcc -v 是診斷錯誤的實用工具。它在有無其他參數的情況下都有效。

--check

[一般] 執行 Emscripten 的內部健全性檢查,並報告目前組態的任何問題。

--cache <directory>

[一般] 設定要用作 Emscripten 快取的目錄。Emscripten 快取用於儲存 libclibcxx 和其他程式庫的預先建置版本。

如果在組合使用此項與 --clear-cache,請務必先指定此參數。

Emscripten 快取預設為 emscripten/cache,但可以使用 EM_CACHE 環境變數或 CACHE 組態設定來覆寫。

--clear-cache

[一般] 手動清除編譯後的 Emscripten 系統程式庫 (libc++、libc++abi、libc) 的快取。

這通常會自動處理,但如果您就地更新 LLVM(而不是為新版本使用不同的目錄),快取機制可能會混亂。清除快取可以修正與快取不相容相關的奇怪問題,例如 Clang 無法連結程式庫檔案。這也會清除其他快取資料。清除快取後,此程序將會結束。

預設情況下,這也會清除任何下載埠,因為埠目錄通常位於快取目錄中。

--use-port=<port>

[編譯+連結] 使用指定的埠。如果您需要使用多個埠,您可以多次使用此選項(例如:--use-port=sdl2 --use-port=bzip2)。埠可以使用 : 分隔的選項(例如:--use-port=sdl2_image:formats=png,jpg)。若要使用外部埠,您可以直接提供埠的路徑(例如:--use-port=/path/to/my_port.py)。若要取得有關埠的更多資訊,請使用 help 選項(例如:--use-port=sdl2_image:help)。若要取得可用埠的清單,請使用 --show-ports

--clear-ports

[一般] 手動清除來自 Emscripten 埠儲存庫 (sdl2 等) 的埠的本機副本。這也會清除快取,以移除其建置。

只有在發生問題且您希望所有使用的埠都從頭開始下載和建置時,才需要執行此操作。此操作完成後,此程序將會結束。

--show-ports

[一般] 顯示 Emscripten 埠儲存庫中可用專案的清單。此操作完成後,此程序將會結束。

-Wwarn-absolute-paths

[編譯+連結] 啟用有關在 -I-L 命令列指令中使用絕對路徑的警告。這用於警告意外使用絕對路徑,這在參考非可攜式本機系統標頭時有時很危險。

--proxy-to-worker

[連結] 在 worker 中執行主要應用程式碼,將事件代理到其中並從其中輸出。如果發出 HTML,則會發出 .html 檔案,以及一個單獨的 .js 檔案,其中包含要在 worker 中執行的 JavaScript。如果發出 JavaScript,目標檔案名稱會包含要在主要執行緒上執行的部分,而第二個副檔名為「.worker.js」的 .js 檔案將包含 worker 部分。

--emrun

[連結] 使產生的輸出能夠感知 emrun 命令列工具。這允許在透過 emrun 執行產生的應用程式時捕獲 stdoutstderrexit(returncode)。(這會啟用 EXIT_RUNTIME=1,允許以傳回碼傳遞正常執行階段結束。)

--cpuprofiler

[連結] 在產生的頁面上嵌入一個簡單的 CPU 分析器。使用它來執行粗略的互動式效能分析。

--memoryprofiler

[連結] 在產生的頁面上嵌入記憶體配置追蹤器。使用它來分析應用程式對 Emscripten HEAP 的使用情況。

--threadprofiler

[連結] 在產生的頁面上嵌入執行緒活動分析器。使用它來分析以多執行緒建置 (-pthread) 為目標時應用程式對 pthreads 的使用情況。

--em-config <path>

[一般] 指定 .emscripten 組態檔案的位置。如果未指定,emscripten 將首先在 emscripten 目錄本身中搜尋 .emscripten,然後在用戶的主目錄 (~/.emscripten) 中搜尋。可以使用 EM_CONFIG 環境變數來覆寫此設定。

--valid-abspath <path>

[編譯+連結] 註解允許的絕對路徑,我們不應該對其發出警告(通常會警告絕對包含路徑,因為它們可能參考本機系統標頭等,我們在交叉編譯時需要避免)。

-o <target>

[連結] 在連結可執行檔時,target 檔案名稱副檔名定義要產生的輸出類型

  • <name> .js : JavaScript(如果發出 WebAssembly,則為 + 單獨的 <name>.wasm 檔案)。(預設)

  • <name> .mjs : ES6 JavaScript 模組(如果發出 WebAssembly,則為 + 單獨的 <name>.wasm 檔案)。

  • <name> .html : HTML + 單獨的 JavaScript 檔案(<name>.js;如果發出 WebAssembly,則為 + 單獨的 <name>.wasm 檔案)。

  • <name> .wasm : 沒有 JavaScript 支援程式碼的 WebAssembly(「獨立 Wasm」;這會啟用 STANDALONE_WASM)。

這些規則僅在連結時套用。當編譯為物件程式碼時(請參閱下面的 -c),輸出檔案的名稱無關緊要。

-c

[編譯] 告知 emcc 發出一個物件檔案,然後可以將其與其他物件檔案連結以產生可執行檔。

--output_eol windows|linux

[連結] 指定要為輸出的文字檔案產生的行尾。如果傳遞「–output_eol windows」,則最終輸出檔案中將包含 Windows rn 行尾。使用「–output_eol linux」,最終產生的檔案將使用 Unix n 行尾寫入。

--cflags

[其他] 列印出 emcc 會傳遞給 clang,將原始碼編譯成物件形式的標誌。您可以使用它來自行調用 clang,然後在這些輸出上執行 emcc,僅用於最終的連結+轉換為 JS。

環境變數

emcc 會受到數個環境變數的影響,如下所列

  • EMMAKEN_JUST_CONFIGURE [其他]

  • EMCC_AUTODEBUG [編譯+連結]

  • EMCC_CFLAGS [編譯+連結]

  • EMCC_CORES [一般]

  • EMCC_DEBUG [一般]

  • EMCC_DEBUG_SAVE [一般]

  • EMCC_FORCE_STDLIBS [連結]

  • EMCC_ONLY_FORCED_STDLIBS [連結]

  • EMCC_LOCAL_PORTS [編譯+連結]

  • EMCC_STDERR_FILE [一般]

  • EMCC_CLOSURE_ARGS [連結] 要傳遞給 Closure Compiler 的參數

  • EMCC_STRICT [一般]

  • EMCC_SKIP_SANITY_CHECK [一般]

  • EM_IGNORE_SANITY [一般]

  • EM_CONFIG [一般]

  • EM_LLVM_ROOT [編譯+連結]

  • _EMCC_CCACHE [一般] 內部設定,當與 ccache 編譯器前端整合時,emsdk 會將其設定為 1

emcc.py 中搜尋 'os.environ',以查看這些變數是如何使用的。其中最有趣的是 EMCC_DEBUG,它會強制編譯器將其建置和暫存檔案轉儲到一個臨時目錄中,以便審閱。