下載安裝
官方推薦方式码荔,先下載 emsdk:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# 下載并安裝最新的 SDK 工具.
./emsdk install latest
# 為當(dāng)前用戶激活最新的 SDK. (寫入 .emscripten 配置文件)
./emsdk activate latest
# 激活當(dāng)前 PATH 環(huán)境變量
source ./emsdk_env.sh
注意
在Windows上運(yùn)行emsdk
,而不是./emsdk
和号涯,emsdk_env.bat
而不是目胡。source ./emsdk_env.sh
會(huì)安裝sdk-release-upstream, node.js, 等锯七,因?yàn)槭菑?br> https://storage.googleapis.com/ 上下載相應(yīng)的軟件包链快,如果您因網(wǎng)絡(luò)原因不能直接訪問(wèn)這個(gè)域名,則可能需要設(shè)置代理下載眉尸。
安裝驗(yàn)證
確保已下載并安裝Emscripten(執(zhí)行此操作的確切方法取決于您的操作系統(tǒng):Linux域蜗,Windows或Mac)。
Emscripten使用Emscripten編譯器前端(emcc)進(jìn)行訪問(wèn)噪猾。該腳本調(diào)用了構(gòu)建代碼所需的所有其他工具霉祸,并且可以代替gcc或clang等標(biāo)準(zhǔn)編譯器。在命令行上使用./emcc
或調(diào)用它./em++
袱蜡。
$ emcc --version
emcc (Emscripten gcc/clang-like replacement) 1.40.1
...
編譯
接下來(lái)就可以編譯代碼啦丝蹭。
來(lái)個(gè)萬(wàn)年不變的Hello world試試:
#include<stdio.h>
void main(){
printf("Hello world!");
}
可以比較分別以
第一種情況:
emcc hello.c
和,第二種情況:
emcc -O2 hello.c -o hello.wasm
進(jìn)行編譯坪蚁,感受一下差異奔穿。
第一種情況下
編譯默認(rèn)會(huì)生成一個(gè)2500多行的JavaScript文件 a.out.js
和一個(gè)可反編譯成文本wat格式的近1萬(wàn)行代碼的 a.out.wasm
文件. 大是太大了點(diǎn),不過(guò)不用怕敏晤,后面我們會(huì)告訴你如何讓他們變小贱田。
a.out.js
是一坨膠水,用來(lái)在不同條件下為wasm搭建一個(gè)執(zhí)行環(huán)境嘴脾。先不管他究竟是啥男摧,先試試運(yùn)行看看:
node a.out.js
可惜,沒(méi)有人跟你問(wèn)世界好,相反耗拓,向你拋出一團(tuán)警告:
stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.
(this may also be due to not including full filesystem support - try building with -s FORCE_FILESYSTEM=1)
這一坨英文的意思是拇颅,編譯出的wasm默認(rèn)情況下不會(huì)退出運(yùn)行時(shí),這是web情況下期待的方式乔询,主程序main雖然運(yùn)行結(jié)束了蔬蕊,但模塊沒(méi)有退出,靜態(tài)變量可以保持在內(nèi)存中哥谷,不釋放岸夯。同時(shí)標(biāo)準(zhǔn) I/O 緩沖區(qū)沒(méi)有被flush,也就沒(méi)有看到 Hello world!
聽(tīng)人勸们妥, 加上參數(shù)再編譯:
emcc hello.c -s EXIT_RUNTIME=1
然后再用node.js
運(yùn)行:
node a.out.js
Hello world!
出現(xiàn)了期待的 Hello world! 不再出嚇人的警告了猜扮。
估計(jì)你會(huì)問(wèn),我編譯的是hello.c
监婶,為啥出來(lái)的是 a.out.js
?
這還真有點(diǎn)歷史傳統(tǒng)的味道旅赢,你可以把 a.out 理解成匯編輸(assembler output)。這種*nix操作系統(tǒng)下的可執(zhí)行文件也稱作 a.out格式(試比較 ELF 格式)惑惶。
如果你看著不爽的話煮盼,可以指定自己的名字,下面我們就看看如何指定自己的名字带污。
第二種情況
emcc有兩個(gè)常用的編譯參數(shù)僵控,大小歐(O,o), 大歐 O 指定優(yōu)化級(jí)別,小歐 o 指定輸出文件和類型鱼冀。
優(yōu)化級(jí)別有 -O0, -O1, -O2, -O3 -Os這五種級(jí)別报破。不指定是為 -O0, 即沒(méi)有優(yōu)化,開(kāi)發(fā)時(shí)一般指定為 -O0 或 -O1千绪, 這樣編譯速度快充易,調(diào)試方便。 正式發(fā)布時(shí)可以是 -O2 或 -O3荸型,這時(shí)代碼會(huì)優(yōu)化盹靴,執(zhí)行更快。-Os 不光是執(zhí)行快瑞妇,同時(shí)優(yōu)化大小稿静,可生成更小的執(zhí)行文件。
emcc 小歐 o 選項(xiàng)指定輸出文件類型有 js踪宠,wasm 和 html自赔。
讓我們來(lái)試試生成html:
emcc -o hello.html hello.c
這回會(huì)生成三個(gè)文件: hello.html, hello.js, hello.wasm
在當(dāng)前目錄下執(zhí)行 live-server
live-server
如果你機(jī)器上沒(méi)有 live-server, 可以用 npm install live-server
來(lái)安裝。
live-server 會(huì)啟動(dòng)一個(gè)web服務(wù)器柳琢,監(jiān)聽(tīng)本機(jī)的8080端口绍妨,并自動(dòng)打開(kāi)瀏覽器:
點(diǎn)擊hello.html:
顯示了兩個(gè)黑窟窿頁(yè)面润脸,我的Hello world!
呢?
好吧他去,頁(yè)面也有頁(yè)面的怪癖毙驯,printf
打印時(shí),同樣因?yàn)闆](méi)有刷新緩沖區(qū)灾测,沒(méi)有看到我們的Hello world, 增加編譯選項(xiàng):
emcc hello.c -o hello.html -s EXIT_RUNTIME=1
<kbd>CTRL</kbd>+<kbd>C</kbd> 停掉 live-server, 重新編譯爆价,再啟 live-server, 再刷頁(yè)面:
好的,我們的 Hello world! 熠熠生輝媳搪,是那么的可愛(ài)铭段!
我們經(jīng)歷了什么?
我們安裝了 emscripten 編譯工具鏈秦爆,把 C 語(yǔ)言寫的代碼分別移植到了 Node.js的命令行和 Web 頁(yè)面各自己執(zhí)行了一下序愚。
誰(shuí)說(shuō) C 語(yǔ)言不能做前端來(lái)著?
不過(guò)等限,眼下還看不出這么折騰有啥用爸吮,就讓我?guī)б黄鸶銈€(gè)能說(shuō)明問(wèn)題的用例吧?
你保持關(guān)注望门,我保持更新形娇!
學(xué)習(xí) WebAssembly 正當(dāng)時(shí)!