Emscripten之編譯專案

2021-10-01 06:16:25 字數 2974 閱讀 7239

在c專案中引入外部依賴,通常有兩種方法:引入庫源**、使用靜/動態庫。因為emscripten做的工作主要是將c**編譯成asm.js或者webassembly,所以對於emscripten編譯的c專案而言,也是可以使用以上兩種方法新增依賴。接下來將以在ubuntu16.04 x64系統下使用emscripten編譯faac專案為例進行講解。

faac是基於c編寫的開源庫,是目前較成熟的aac音訊編碼器。假設以下程式test.cc需要使用faac的依賴:

#include

#include

"faac.h"

intmain()

程式中開啟了faac編碼器,獲取將取樣率為8000hz、單聲道的pcm音訊資料編碼為一幀aac資料時所需要輸入的位元組數inputsample。

之前我們也有提到在專案中引入外部依賴庫的方法,接下來我們分別使用兩種方法引入依賴庫,再使用emscripten編譯成webassembly模組。

2.1 引入原始檔

使用這種方法,需要將faac中include資料夾下的faac.h、faaccfg.h和libfaac檔案下的c檔案和標頭檔案拷貝至專案中。然後執行以下指令進行編譯,即在test.cc後新增faac庫引入的所有c檔案:

emcc test.cc bitstream.c fft.c frame.c blockswitch.c util.c channels.c filtbank.c tns.c quantize.c huff2.c huffdata.c stereo.c -s allow_memory_growth=1 -o test.html
在預設設定下,emscripten堆一經初始化,記憶體容量就固定了,無法再擴容。而某些程式在執行時需要的記憶體容量在不同情況下可能有很大的波動。為了滿足某些極端需求而將total_memory設定得非常高無疑是非常浪費的,為此,emscripten提供了可在執行時擴大記憶體容量的模式,欲開啟該模式,需要在編譯時增加-s allow_memory_growth=1引數。faac編碼需要的較大記憶體,故此處編譯增加了上述選項。

在可變記憶體模式下,使用malloc等函式分配記憶體時,若可用空間不足,將引發emscripten堆擴容。擴容時,記憶體中原有的資料會被拷入擴容後的記憶體空間中,因此擴容並不會導致資料丟失或位址變更。

可變記憶體雖然提供了很多便利,但當編譯目標為asm.js時,可變記憶體模式會影響效能。然而可擴容的記憶體是webassembly的自有特性,當編譯目標為wasm時,使用可變記憶體模式非常高效,不會影響執行效能,因此在編譯為webassembly時,可變記憶體是推薦用法。

2.2 引入靜/動態庫

正常情況下,gcc編譯含有makefile的專案通常使用以下命令:

./configure

make

若需要將編譯後的動態庫或靜態庫註冊入系統中,還需執行以下命令:

make

install

使用emscripten編譯專案的步驟也是類似的,但是需要使用emcc替換gcc編譯器。emscripten中提供了emconfigure指令為c++編譯器和c編譯器設定合理的環境變數。使用emscripten指令替換以上編譯指令,有:

emcongiure ./configure

emmake make

sudo

make

install

aclocal

autoheader

autoconf

automake

emcongiure ./configure

emmake make

sudo

make

install

執行成功之後,在usr/local/lib目錄下可以看到生成了

libfaac.a libfaac.la libfaac.so libfaac.so.0 libfaac.so.0.0.0
這裡些就是emscripten編譯生成的包含llvm bitcode的檔案。將編譯生成的libfaac.a檔案新增到test專案中,目錄結構如下:

執行以下命令,即可將含有faac庫依賴的專案編譯成webassembly:

emcc test.cc libfaac.a -s allow_memory_growth=1 -o test.html
開啟兩次編譯生成的test.html,輸出結果是一致的。

注意:雖然使用./configre與make也能生成libfaac.a等檔案,但是這些檔案是不含llvm bitcode的,執行emcc時會報錯:

emcc:warning: *** is not a vaild input file

shared:error: no input files

note that input files without a known suffix are ignored, make sure your input files end with one of: (

'.c', '.c', '.i', '.cpp', '.cxx', '.cc', '.c++', '.cpp', '.cxx', '.cc', '.c++', '.ii', '.m', '.mi', '.mm', '.mii', '/dev/null', '.bc', '.o', '.obj', '.lo', '.dylib', '.so', '.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.h', '.hxx', '.hpp', '.hh'

)

至於使用哪一種方法,因人而異。對於比較大型的專案,個人還是比較建議使用makefile的方法進行編譯,有興趣的小夥伴可以了解以下如何生成makefile檔案。

安裝Emscripten編譯環境

1.各類安裝工具讓它一鍵安裝 sudo apt update sudo apt install vim openssh server git curl wget tar unzip sudo apt install build essential python cmake default jre 2...

vue入門之編譯專案

好記性不如爛筆頭,最近又開始學習vue了,編譯的過程中遇到幾個小坑,特此一記。首先說一下vue專案如何編譯,其實很簡單,cd到專案資料夾,然後執行命令 npm run build不過npm命令通常很慢,我們可以使用 的映象以及cnpm命令 cnpm install cnpm g上面是安裝或者公升級,...

編譯android專案

編譯整個源 需要比較長的時間。在系統的根目錄下有個makefile檔案,直接使用make就可以了。也可以先修改許可權,然後直接使用make。ken ken data android sudo chmod r ken ken ken data android make ken ken data and...