Ubuntu 18.04 下 emscripten SDK 的安裝

Ubuntu 18.04 下 emscripten SDK 的安裝
http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html#installation-instructionshtml

須要環境
清華安裝源 https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu
$ sudo apt update
$ sudo apt install vim openssh-server git curl wget tar unzip
$ sudo apt install build-essential python cmake default-jrenode

下載源
$ cd ~
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
更新最新版本
$ ./emsdk updatepython

安裝最新的SDK
安裝期間會檢查並自動下載缺失的llvm、clang、node、emscripten和sdk等,根據提示會顯示下載的壓縮包網址和本地的目錄,
若是下載期間發生錯誤,沒法下載到本地,能夠用wget等工具手動下載,放到提示的本地目錄(emsdk/zips)裏,再次運行這條命令

固然手動下載好,而後複製到zips也是能夠的
$ mkdir ~/emsdk/zips
$ mv ~/clang-e1.38.4.tar.gz ~/emsdk/zips/
$ mv ~/llvm-e1.38.4.tar.gz ~/emsdk/zips/
$ mv ~/node-v8.9.1-linux-x64.tar.xz ~/emsdk/zips/
$ mv ~/emscripten-llvm-e1.38.4.tar.gz ~/emsdk/zips/
$ mv ~/1.38.4.tar.gz ~/emsdk/zips/
$ ./emsdk install latest
$ rm ~/emsdk/zips/*

$ ./emsdk install latest
請耐心等待編譯完成。
爲當前用戶配置~/.emscripten文件
$ ./emsdk activate latestlinux

查看安裝列表,安裝binaryen
$ ./emsdk list
./emsdk install binaryen-tag-1.38.4-64bit
./emsdk activate binaryen-tag-1.38.4-64bitc++

爲當前會話配置環境變量
$ cd ~/emsdk
$ source ./emsdk_env.sh
$ cd ~/emsdk
$ ./emsdk listgit

查看版本
$ emcc --version
$ em++ --versiongithub

備份
$ cd ~
$ tar cvzf emsdk.tar.gz emsdkcanvas

卸載
$ ./emsdk uninstall <tool/sdk name>
徹底卸載,刪除這個目錄便可。ubuntu

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
官方教程的例子
http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~vim

emcc 用於編譯c/c++源程序,簡單格式以下:
$ emcc -O2 hello_world.cpp -s WASM=1 -o hello_world.html
(1)優化方案:詳細見 http://kripken.github.io/emscripten-site/docs/tools_reference/emcc.html#emcc-o2
指定 -O0 或者不指定優化方案,即不優化。
指定 -O1 簡單優化,優化asm.js,LLVM -O1,移除掉運行時輸出和異常捕獲等,如printf、puts等代碼。
指定 -O2 相似O1,而後會壓縮js,LLVM -O3,適合release
指定 -O3 相似O2,進一步壓縮js,推薦release
指定 -Os 相似O3,進一步優化bitcode生成和js代碼尺寸
指定 -Oz 相似Os,更進一步優化代碼
(2)鍵值開關:-s OPTION=value
默認WASM=1,若是純js,請設置WASM=0
(3)-o xxx.html
會輸出xxx.html,不然會輸出a.out.js和a.out.wasm
(4)更詳細的指令見 emcc --help 和 http://kripken.github.io/emscripten-site/docs/tools_reference/emcc.html


---------------------------
例子1:編譯hello, world程序
---------------------------
$ source ~/emsdk/emsdk_env.sh
$ mkdir ~/tests
$ cd ~/tests
$ vim hello_world.c

1 #include <stdio.h>
2 
3 int main() { 4   printf("hello, world!\n"); 5   return 0; 6 }

 

$ emcc hello_world.c
耐心等待,會生成a.out.js,若是發生錯誤,能夠用-v選項編譯,輸出更多的調試信息。
$ ls -al
total 160
drwxrwxr-x 2 bob bob 4096 6月 1 14:37 .
drwxr-xr-x 19 bob bob 4096 6月 1 14:38 ..
-rw-rw-r-- 1 bob bob 101699 6月 1 14:37 a.out.js
-rw-rw-r-- 1 bob bob 45389 6月 1 14:37 a.out.wasm
-rw-rw-r-- 1 bob bob 75 6月 1 14:35 hello_world.c
$ node a.out.js
hello, world!

經過上面的生成文件,會發現同時生成了wasm,可是有的瀏覽器不支持wasm,須要指定 -s WASM=0
接下來分別生成支持wasm和不支持wasm的狀況,同時生成html
$ emcc hello_world.c -o hello.html
$ emcc hello_world.c -s WASM=0 -o hello_nowasm.html
$ ls -al
total 816K
drwxrwxr-x 2 bob bob 4.0K 6月 1 14:54 .
drwxr-xr-x 19 bob bob 4.0K 6月 1 14:54 ..
-rw-rw-r-- 1 bob bob 100K 6月 1 14:37 a.out.js
-rw-rw-r-- 1 bob bob 45K 6月 1 14:37 a.out.wasm
-rw-rw-r-- 1 bob bob 101K 6月 1 14:54 hello.html
-rw-rw-r-- 1 bob bob 100K 6月 1 14:54 hello.js
-rw-rw-r-- 1 bob bob 101K 6月 1 14:54 hello_nowasm.html
-rw-rw-r-- 1 bob bob 298K 6月 1 14:54 hello_nowasm.js
-rw-rw-r-- 1 bob bob 45K 6月 1 14:54 hello.wasm
-rw-rw-r-- 1 bob bob 75 6月 1 14:35 hello_world.c
分別生成了:
第一組:hello.html, hello.js, hello.wasm
第二組:hello_nowasm.html, hello_nowasm.js
能夠用一個httpserver啓動,而後用瀏覽器測試兩個頁面的效果
$ python -m SimpleHTTPServer 8080
注:wasm的是不支持file:///方式直接打開。


附:wasm的瀏覽器支持狀況
https://caniuse.com/#search=wasm


----------------------------
例子2:SDL API顯示到<canvas>
----------------------------
$ cd ~/tests
$ vim hello_world_sdl.cpp

 1 #include <stdio.h>
 2 #include <SDL/SDL.h>
 3 
 4 #ifdef __EMSCRIPTEN__  5 #include <emscripten.h>
 6 #endif
 7 
 8 extern "C" int main(int argc, char** argv) {  9   printf("hello, world!\n"); 10 
11  SDL_Init(SDL_INIT_VIDEO); 12   SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE); 13 
14 #ifdef TEST_SDL_LOCK_OPTS 15   EM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; SDL.defaults.opaqueFrontBuffer = false;"); 16 #endif
17 
18   if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); 19   for (int i = 0; i < 256; i++) { 20     for (int j = 0; j < 256; j++) { 21 #ifdef TEST_SDL_LOCK_OPTS 22       // Alpha behaves like in the browser, so write proper opaque pixels.
23       int alpha = 255; 24 #else
25       // To emulate native behavior with blitting to screen, alpha component is ignored. Test that it is so by outputting 26       // data (and testing that it does get discarded)
27       int alpha = (i+j) % 255; 28 #endif
29       *((Uint32*)screen->pixels + i * 256 + j) = SDL_MapRGBA(screen->format, i, j, 255-i, alpha); 30  } 31  } 32   if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); 33  SDL_Flip(screen); 34 
35   printf("you should see a smoothly-colored square - no sharp lines but the square borders!\n"); 36   printf("and here is some text that should be HTML-friendly: amp: |&| double-quote: |\"| quote: |'| less-than, greater-than, html-like tags: |<cheez></cheez>|\nanother line.\n"); 37 
38  SDL_Quit(); 39 
40   return 0; 41 }

 

保存後,可刪除其餘多餘的文件
$ rm `ls|grep -v hello_world_sdl.cpp`
編譯
$ emcc hello_world_sdl.cpp -o hello_sdl.html
$ ls -al
total 396
drwxrwxr-x 2 bob bob 4096 6月 1 15:40 .
drwxr-xr-x 19 bob bob 4096 6月 1 15:41 ..
-rw-rw-r-- 1 bob bob 102842 6月 1 15:40 hello_sdl.html
-rw-rw-r-- 1 bob bob 233934 6月 1 15:40 hello_sdl.js
-rw-rw-r-- 1 bob bob 46133 6月 1 15:40 hello_sdl.wasm
-rw-rw-r-- 1 bob bob 1385 6月 1 15:33 hello_world_sdl.cpp


-------------------
例子3:文件打開操做
-------------------
$ cd ~/tests
$ rm *
$ vim hello_world_file.cpp

 1 #include <stdio.h>
 2 int main() {  3   FILE *file = fopen("hello_world_file.txt", "rb");  4   if (!file) {  5     printf("cannot open file\n");  6     return 1;  7  }  8   while (!feof(file)) {  9     char c = fgetc(file); 10     if (c != EOF) { 11  putchar(c); 12  } 13  } 14  fclose (file); 15   return 0; 16 }

 

$ cat<<EOF>hello_world_file.txt
==
This data has been read from a file.
The file is readable as if it were at the same location in the filesystem, including directories, as in the local filesystem where you compiled the source.
==
EOF
$ emcc hello_world_file.cpp -o hello_file.html --preload-file hello_world_file.txt
$ ls -al
total 408
drwxrwxr-x 2 bob bob 4096 6月 1 15:53 .
drwxr-xr-x 19 bob bob 4096 6月 1 15:53 ..
-rw-rw-r-- 1 bob bob 199 6月 1 15:53 hello_file.data
-rw-rw-r-- 1 bob bob 102843 6月 1 15:53 hello_file.html
-rw-rw-r-- 1 bob bob 234871 6月 1 15:53 hello_file.js
-rw-rw-r-- 1 bob bob 50317 6月 1 15:53 hello_file.wasm
-rw-rw-r-- 1 bob bob 280 6月 1 15:52 hello_world_file.cpp
-rw-rw-r-- 1 bob bob 199 6月 1 15:53 hello_world_file.txt
注意那個.data文件,查看文件內容就是hello_world_file.txt的內容
$ cat hello_file.data
==
This data has been read from a file.
The file is readable as if it were at the same location in the filesystem, including directories, as in the local filesystem where you compiled the source.
==

 

相關文章
相關標籤/搜索