web assembly 初體驗

383494發表於2024-10-20

License: CC BY-NC-SA 4.0

我寫了一個程式,可以在各個平臺執行嗎?

可以,用跨平臺庫。

如何做到“不用下載,點選即玩”呢?

做成網頁。

但是它已經用 c/cpp(或其他程式語言,此處用 c/cpp 舉例)寫完了……

Web Assembly,啟動!

Web Assembly 是什麼

這是一段介紹

省流:

WebAssembly 是一種新的編碼方式,可以在現代的 Web 瀏覽器中執行——它是一種低階的類組合語言,具有緊湊的二進位制格式,可以接近原生的效能執行,併為諸如 C/C++、C# 和 Rust 等語言提供編譯目標,以便它們可以在 Web 上執行。

如何將 c/cpp 程式碼編譯為 Web Assembly

emscripten 是一個類似 clang 的編譯工具鏈,支援 SDL 等庫。

這裡是 SDL Wiki 對於 emscripten 支援的一段介紹,總結了一下大概就是下面兩點:

  1. 檔案開頭 include 所需的庫。

    #ifdef __EMSCRIPTEN__
    #include <emscripten.h>
    #endif
    
  2. 寫一個 main loop,但不要真的 loop 了。

    extern bool game_is_still_running;
    
    static void mainloop(void)   /* this will run often, possibly at the monitor's refresh rate */
    {
    	if (!game_is_still_running) {
    		// deinitialize_the_game();
    		#ifdef __EMSCRIPTEN__
    		emscripten_cancel_main_loop();  /* this should "kill" the app. */
    		#else
    		exit(0);
    		#endif
    	}
    
    	// check_for_new_input();
    	// think_about_stuff();
    	// draw_the_next_frame();
    }
    
    void main(void)
    {
    	// initialize_the_game();
    	#ifdef __EMSCRIPTEN__
    	emscripten_set_main_loop(mainloop, 0, 1);
    	#else
    	while (1) { mainloop(); }
    	#endif
    }
    

編譯使用 emcc foo.c 即可。

下面是一些踩坑/注意事項/提醒。

  • 用 emscripten 編譯 SDL 程式時要帶 -sUSE_SDL=2 引數,首次執行時會從 github 上下載 SDL2 的相關資源,如果網不好可能要等幾分鐘然後隨機斷連
  • 加入 -o index.html 引數可以直接輸出網頁,但輸出的網頁不能直接開啟。
    • 如果嘗試直接開啟可能會一直在載入中。
    • 正確的方法是搭一個本地測試伺服器,可以看這裡
    • 省流:進入 index.html 所在的資料夾,然後 python3 -m http.server.