安装QT for webasm

.\MaintenanceTool.exe --mirror https://mirror.nju.edu.cn/qt/ 

克隆emsdk

git clone https://github.com/emscripten-core/emsdk.git

进入目录,执行指令配置emsdk

安装指定版本,博主的qt是6.7.2,实测最新版本(4.x)无法兼容,因此使用3.x
./emsdk install 3.1.51
./emsdk activate 3.1.51 --permanent 
. ./emsdk_env.ps1

CMake工具链配置

{
      "name": "wasm-emscripten",
      "displayName": "wasm-emscripten",
      "binaryDir": "${sourceDir}/out/build/wasm-emscripten",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "CMAKE_TOOLCHAIN_FILE": "C:/Qt/6.7.2/wasm_multithread/lib/cmake/Qt6/qt.toolchain.cmake",
        "QT_CHAINLOAD_TOOLCHAIN_FILE": "G:/dev_programs/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
        "EMSDK": "G:/dev_programs/emsdk",
        "Qt6_DIR": "C:/Qt/6.7.2/wasm_multithread/lib/cmake/Qt6",
        "CMAKE_DEPENDS_USE_COMPILER": false,
        "CMAKE_C_DEPENDS_USE_COMPILER": false,
        "CMAKE_CXX_DEPENDS_USE_COMPILER": false
      },
      "environment": {
        "EM_CONFIG": "G:/dev_programs/emsdk/.emscripten",
        "EMSDK": "G:/dev_programs/emsdk",
        "EMSDK_NODE": "G:/dev_programs/emsdk/node/22.16.0_64bit/bin/node.exe",
        "EMSDK_PYTHON": "G:/dev_programs/emsdk/python/3.13.3_64bit/python.exe",
        "EMSCRIPTEN": "G:/dev_programs/emsdk/upstream/emscripten",
        "PATH": "G:/dev_programs/emsdk;G:/dev_programs/emsdk/upstream/emscripten;G:/dev_programs/emsdk/upstream/bin;G:/dev_programs/emsdk/node/22.16.0_64bit/bin;$penv{PATH}"
      },
      "inherits": [
        "Qt-Default"
      ]
    },

为项目添加中文字体

webasm默认不支持中文,会显示方框,此时你需要添加自己的字体。

参考代码:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    int fontId = QFontDatabase::addApplicationFont(":/fonts/yahei.ttf");
    if (fontId != -1)
    {
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
        if (!fontFamilies.isEmpty())
        {
            QFont font(fontFamilies.at(0));
            a.setFont(font);
        }
    }
    skaScreen w;
    w.show();
    return a.exec();
}

部署上线

需要使用http服务器,开启跨域功能,如nginx等

受到限制,仅兼容https、localhost http。无法兼容公网http。

需要在nginx的server块中添加配置:

server {
    省略。
    add_header Cross-Origin-Opener-Policy same-origin;
    add_header Cross-Origin-Embedder-Policy require-corp;
}

所需最小文件

编译输出文件夹中会有很多文件,以下是所需最少的文件:

  • 项目名.html

  • qtloader.js

  • qtlogo.svg

  • 项目名.js

  • 项目名.wasm

  • 项目名.worker.js

将文件复制到http服务器后,记得把项目名.html改为index.html

踩坑记录

提示-s DEMANGLE_SUPPORT=1错误:

解决方法:降低emsdk版本,重新执行第一步骤

报错 '"CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS-NOTFOUND"' is not recognized as an internal or external command

解决方法:降低cmake版本,如降低到3.20

报错Undefined symbol: eglGetProcAddress()

解决方法:cmake添加:

if(EMSCRIPTEN)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s GL_ENABLE_GET_PROC_ADDRESS")
endif()

报错wasm-ld : error : --shared-memory is disallowed

解决方法:cmake添加:

if(EMSCRIPTEN)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_PTHREADS=1 -matomics -mbulk-memory")
endif()

nginx中配置了跨域但是还是报错Application exit (SharedArrayBuffer is not defined)

受到限制,仅兼容https、localhost http。无法兼容公网http。