emscripten 安裝與使用, 讓C語言出如今前端

下載安裝

官方推薦方式,先下載 emsdk:html

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# 下載並安裝最新的 SDK 工具.
./emsdk install latest

# 爲當前用戶激活最新的 SDK. (寫入 .emscripten 配置文件)
./emsdk activate latest

# 激活當前 PATH 環境變量
source ./emsdk_env.sh
注意
在Windows上運行 emsdk,而不是 ./emsdk和, emsdk_env.bat而不是。 source ./emsdk_env.sh

會安裝sdk-release-upstream, node.js, 等,由於是從
https://storage.googleapis.com/ 上下載相應的軟件包,若是您因網絡緣由不能直接訪問這個域名,則可能須要設置代理下載。前端

安裝驗證

確保已下載並安裝Emscripten(執行此操做的確切方法取決於您的操做系統:Linux,Windows或Mac)。node

Emscripten使用Emscripten編譯器前端(emcc)進行訪問。該腳本調用了構建代碼所需的全部其餘工具,而且能夠代替_gcc_或_clang_等標準編譯器。在命令行上使用./emcc或調用它./em++git

$ emcc --version
emcc (Emscripten gcc/clang-like replacement) 1.40.1 
...

編譯

接下來就能夠編譯代碼啦。
來個萬年不變的Hello world試試:github

#include<stdio.h>

void main(){
  printf("Hello world!");
}

能夠比較分別以
第一種狀況:web

emcc hello.c

和,第二種狀況:shell

emcc -O2 hello.c -o hello.wasm

進行編譯,感覺一下差別。npm

第一種狀況下

編譯默認會生成一個2500多行的JavaScript文件 a.out.js和一個可反編譯成文本wat格式的近1萬行代碼的 a.out.wasm 文件. 是太了點,不過不用怕,後面咱們會告訴你如何讓他們變小。api

a.out.js是一坨膠水,用來在不一樣條件下爲wasm搭建一個執行環境。先無論他到底是啥,先試試運行看看:瀏覽器

node a.out.js

惋惜,沒有人跟你問世界好,相反,向你拋出一團警告:

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默認狀況下不會退出運行時,這是web狀況下期待的方式,主程序main雖然運行結束了,但模塊沒有退出,靜態變量能夠保持在內存中,不釋放。同時標準 I/O 緩衝區沒有被flush,也就沒有看到 Hello world!

聽人勸, 加參數再編譯:

emcc hello.c -s EXIT_RUNTIME=1

而後再用node.js運行:

node a.out.js
Hello world!

出現了期待的 Hello world! 再也不出嚇人警告了。

估計你會問,我編譯的是hello.c,爲啥出來的是 a.out.js?
這還真有點歷史傳統的味道,你能夠把 a.out 理解成彙編輸出(assembler output)。這種 *nix 操做系統下的可執行文件也稱做 a.out 格式(試比較 ELF 格式)。

若是你看着不爽的話,能夠指定本身名字,下面咱們就看看如何指定本身的名字。

第二種狀況

emcc有兩個經常使用的編譯參數,大小歐(O,o), 大歐 O 指定優化級別,小歐 o 指定輸出文件和類型。

優化級別有 -O0, -O1, -O2, -O3 -Os這五種級別。不指定是爲 -O0, 即沒有優化,開發時通常指定爲 -O0 或 -O1, 這樣編譯速度快,調試方便。 正式發佈時能夠是 -O2 或 -O3,這時代碼會優化,執行更快。-Os 不光是執行快,同時優化大小,可生成更小的執行文件。

emcc 小歐 o 選項指定輸出文件類型有: js,wasm 和 html。

讓咱們來試試生成html:

emcc -o hello.html hello.c

這回會生成三個文件: hello.html, hello.js, hello.wasm

在當前目錄下執行 live-server

live-server

若是你機器上沒有 live-server, 能夠用 npm install live-server來安裝。

live-server 會啓動一個web服務器,默認監聽本機的8080端口,並自動打開瀏覽器:

image

點擊hello.html:
image

顯示了兩個黑窟窿頁面,個人Hello world! 呢?

好吧,頁面也有頁面的怪癖,printf打印時,一樣由於沒有刷新緩衝區,沒有看到咱們的Hello world, 增長編譯選項:

emcc hello.c -o hello.html -s EXIT_RUNTIME=1

CTRL+C 停掉 live-server, 從新編譯,再啓 live-server, 再刷頁面:

image

好的,咱們的 Hello world! 熠熠生輝,是那麼的可愛!

咱們經歷了什麼?

咱們安裝了 emscripten 編譯工具鏈,把 C 語言寫的代碼分別移植到了 Node.js的命令行和 Web 頁面各本身執行了一下。

誰說 C 語言不能作前端來着?

不過,眼下還看不出這麼折騰有啥用,就讓我帶一塊兒搞個能說明問題的用例吧?

你保持關注,我保持更新!學習 WebAssembly 正當時!

相關文章
相關標籤/搜索