【CXX-Qt】2.1.1 为 WebAssembly 构建
CXX-Qt 及其编写的应用程序可以编译为 WebAssembly,但存在一些限制。以下是关于如何为 WASM 目标构建的详细说明。
你需要安装 Qt for WebAssembly。下一篇将展示已测试的版本。
此外,如果尚未完成,请从此处克隆 emsdk git 仓库。
使用正确的版本
用于构建 CXX-Qt 及其程序的 Emscripten 版本应与用于构建 Qt for WebAssembly 的版本匹配。这是因为 Emscripten 不保证不同版本之间的 ABI 兼容性,因此使用不同版本不能保证完全正常工作,甚至可能根本无法工作。
以下是相关的 Qt 和 Emscripten 版本,以及它们当前是否与 CXX-Qt for WebAssembly 兼容:
| Qt 版本 | Emscripten 版本 |
|---|---|
| 6.2 | 2.0.14 |
| 6.3 | 3.0.0 |
| 6.4 | 3.1.14 |
| 6.5 | 3.1.25 |
| 6.6 | 3.1.37 |
设置 emsdk
确定要使用的 Qt 和 Emscripten 版本后,导航到 emsdk 仓库的根目录并运行以下命令:
$ ./emsdk install <emscripten 版本>
$ ./emsdk activate <emscripten 版本>
$ source ./emsdk_env.sh
例如,如果你要使用 Qt 6.4,对应的 Emscripten 版本是 3.1.14,因此第一条命令将是:
$ ./emsdk install 3.1.14
在 Windows 上,第三步(设置环境变量,类似于 Unix 环境中的 source 命令)是不必要的,因为所需的环境设置已经完成。
工具链
使用 CMake 配置时,需要将 CMAKE_TOOLCHAIN_FILE 变量设置为正确的工具链文件。例如,如果在 WebAssembly 上使用 Qt 6.4.2,工具链文件通常位于 /path/to/Qt/6.4.2/wasm_32/lib/cmake/Qt6/qt.toolchain.cmake。这将设置 CMake 使用正确的 Qt 路径、编译器、链接器等。
通常,这不需要手动完成。使用与所选 Qt WASM 版本捆绑的 qt-cmake 二进制文件将自动为你设置工具链文件。
例如,如果使用 Qt 6.4.2:
$ /path/to/Qt/6.4.2/wasm_32/bin/qt-cmake -B build .
然而,在 Qt 6.3 及以下版本中,捆绑的 CMake 版本为 3.22,而 CXX-Qt 至少需要 3.24 版本。对于这些 Qt 版本,需要使用更新的 CMake 二进制文件进行配置,因此需要将 CMAKE_TOOLCHAIN_FILE 传递给 cmake 命令。
如果使用不同的 CMake 二进制文件,请执行以下操作:
$ cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/qt.toolchain.cmake -B build .
对于 Qt 6.5 或更高版本,请使用 wasm_singlethread 工具链。对于早于 6.5 的版本,请使用 wasm_32。
Qt 6.5 及更高版本中提供的 wasm_multithread 工具链目前不受支持。更多信息请参阅本页底部的“已知问题”部分。
为 WebAssembly 编译项目
要为使用 CXX-Qt crate 的项目构建 WebAssembly,请首先按照“使用正确的版本”和“设置 emsdk”部分中的说明进行操作。
CMakeLists.txt
在为 wasm 编译 CXX-Qt 项目时,必须将 Rust 目标设置为 wasm32-unknown-emscripten,并且项目必须配置为使用 POSIX 线程。确保你已经通过 rustup target add wasm32-unknown-emscripten 安装了 Emscripten 目标。
set(Rust_CARGO_TARGET wasm32-unknown-emscripten)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
使用 CMake 时,add_executable 在针对 wasm 时不会输出 HTML 文件。为了渲染 HTML 文件,必须使用 qt_add_executable 代替。假设项目有一个 CMake 标志 BUILD_WASM 用于切换 wasm 和本地构建,可以编写以下内容:
if(BUILD_WASM)qt_add_executable(${APP_NAME} ${SOURCE_FILES})
else()add_executable(${APP_NAME} ${SOURCE_FILES})
endif()
配置、构建和运行
按照“工具链”部分中的说明配置构建目录。
现在,在构建目录上运行 cmake --build 以编译和链接项目。这可以是任何 CMake 二进制文件;此处使用操作系统包即可:
$ cmake --build build
然后可以像这样运行构建的应用程序:
$ emrun ./build/path/to/<appname>.html
从源代码编译 CXX-Qt WASM
如果你是从源代码编译 CXX-Qt,工作流程类似。首先,按照“使用正确的版本”和“设置 emsdk”部分中的说明进行操作。
CXX-Qt 仓库根目录中的 CMakeLists.txt 文件有一个选项 BUILD_WASM,用于切换 WebAssembly 构建。只需使用正确的 emsdk 和工具链编译并将此选项设置为 ON,即可为 WebAssembly 构建库和示例。
构建
在继续之前,请阅读“工具链”部分。然后导航到 CXX-Qt 仓库的根目录。
如果使用与 Qt for WebAssembly 捆绑的 qt-cmake 二进制文件,请运行以下命令来配置 CXX-Qt:
$ /path/to/qt-cmake -DBUILD_WASM=ON -B build .
如果使用不同的 CMake 二进制文件,请执行以下操作:
$ <cmake 二进制文件> -DCMAKE_TOOLCHAIN_FILE=/path/to/qt.toolchain.cmake -DBUILD_WASM=ON -B build .
最后,在配置的构建目录上运行 cmake --build 以编译和链接项目及示例。这可以是任何 CMake 二进制文件;此处使用操作系统包即可:
$ cmake --build build
然后可以像这样运行 qml_minimal 示例:
$ emrun ./build/examples/qml_minimal/example_qml_minimal.html
可用的示例
并非所有示例当前都支持 WASM 构建。
| 示例 | 是否可用 |
|---|---|
| qml-minimal-no-cmake | ❌ 不可用 |
| demo_threading | ❌ 不可用 |
| qml_features | ✅ 可用 |
| qml_minimal | ✅ 可用 |
更多信息请参阅本页底部的“已知问题”部分。
已知问题
wasm_multithread 工具链
CXX-Qt 目前无法使用 wasm_multithread 版本的 Qt 构建。
wasm-ld: error: --shared-memory is disallowed by qml_minimal-e6f36338b0e1fa5c.17g6vcid2nczsjj0.rcgu.o because it was not compiled with 'atomics' or 'bulk-memory' features.
此问题与 libc crate 中的 pthread 有关。手动使用 -pthread 编译 cxx 和 libc crate 可能会解决此问题。
仅使用 cargo 构建
示例 qml-minimal-no-cmake 无法使用 cargo 为 WebAssembly 构建,尝试在没有 cmake 的情况下使用 cargo 构建将无法工作。这是由于 libc crate 的上游问题,它不支持 wasm 并可能导致构建失败。
cannot find function `pthread_kill` in crate `libc`
demo_threading 示例
示例 demo_threading 无法为 WebAssembly 构建,这是由于 async-std 的上游问题,它不支持 wasm。在 Linux 上,观察到的构建失败是由于 socket2 使用其 unix.rs 文件来针对 Unix 环境而不是 wasm 环境,导致来自 unix.rs 的错误消息如下:
error[E0433]: failed to resolve: use of undeclared type `IovLen`
socket2 是 async-io 的依赖项,而 async-io 又是 async-std 的依赖项。
有关在 async-std 的 GitHub 仓库中支持 wasm 的讨论正在进行中,进展可以在此处跟踪。
相关文章:
【CXX-Qt】2.1.1 为 WebAssembly 构建
CXX-Qt 及其编写的应用程序可以编译为 WebAssembly,但存在一些限制。以下是关于如何为 WASM 目标构建的详细说明。 你需要安装 Qt for WebAssembly。下一篇将展示已测试的版本。 此外,如果尚未完成,请从此处克隆 emsdk git 仓库。 使用正确…...
AUTOSAR Communication Services - COM:(二)COM的常见API用法整理
备注:COM-API常用用法整理,持续更新 一、用户I-PDU发送回调中,指定发送对应DBC的信号值 boolean Rte_COMIPduCallout_signal(PduIdType id, PduInfoType *ptr) {static uint8 ucCheckSum 0;// Calculate checksumif (ucCheckSum > 15)u…...
掌握些许 IPv6 要点,windows 远程桌面安全便利两相宜!
掌握这些要点,Windows 远程桌面安全便利两相宜! 在日常办公中,许多人会用到 Windows 系统的远程桌面功能。但在实际使用时,会遇到内网计算机难以通过运营商的动态 ip 与多层 NAT 向互联网暴露端口的技术问题,和计算机…...
Spring Boot整合Apache BookKeeper教程
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 Spring Boot整合Apache BookKeeper教程 1. 简介 Apache BookKeeper 是一个高性能、持久化的分布式日志存储系统,适用于需要强一致性和高吞吐量的…...
【Linux进程】——进程的程序地址空间
目录 前言 1.程序地址空间 1.1区域划分 1.2程序地址空间的本质 1.3程序地址空间分配原则 2.数据寻找 2.1补充:进程挂起 结语 前言 在Linux系统的神秘世界里,进程就像是一个个小工匠,各自忙碌地完成着不同的任务。你是否想过ÿ…...
边缘云原生操作系统的设计与思考
资料来源:火山引擎-开发者社区 边缘云行业现状和发展历程 从 06 年 AWS 推出 EC2 、S3 到今天已经过去了 18 年,云计算早已不是一个新鲜词汇,从当前业务来看,我们能看到云计算从中心到中心边缘的发展趋势,为什么会有 这…...
Jenkins muti-configuration-project 中调用pipeline project
Jenkins muti-configuration-project 中调用pipeline project 解决方案示例练习1. 多配置项目设置:2. 触发器配置:3. Pipeline 项目 Jenkinsfile: 解决方案 创建多配置项目: 在 Jenkins 中创建一个新的多配置项目。在“配置矩阵…...
Gdiplus(也就是GDI+)使用
篇一: Gdiplus(也就是GDI)使用步骤: 1.包括相应的头文件及引入相应的lib #include <GdiPlus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus;//如果没有using namespace Gdiplus;就需要添加“命名空间作用域符” …...
AI学习——卷积神经网络(CNN)入门
作为人类,我们天生擅长“看”东西:一眼就能认出猫狗、分辨红绿灯、读懂朋友的表情……但计算机的“眼睛”最初是一片空白。直到卷积神经网络(CNN)的出现,计算机才真正开始理解图像。今天,我们就用最通俗的…...
双指针算法-day14(分组循环)
1.最长奇偶子数组 题目 解析 分组循环模板: 简单来说: 第一步:指针遍历找到满足条件的开头下标,并用 start i 记录开头;第二步:指针不断右移寻找满足条件的最长子数组;第三步:更新…...
Linux基础开发工具--gdb的使用
目录 安装准备: 1. 背景 2. 开始使用 3. 做一个Linux第一个小程序-进度条 安装准备: 对于gdb的学习使用,为了方便大家学习,我建议大家先安装一个cgdb进行学习,这样方便观察操作与学习gdb。 用以下…...
垃圾回收算法(Garbage Collection)深度解析
垃圾回收算法(Garbage Collection)深度解析 核心思想 垃圾回收核心目标: 定位存活对象 、回收死亡对象可达性分析算法、空间复用优化 生死判定原理 可达性分析法(Reachability Analysis) 通过GC Roots(…...
基于Matlab实现语音识别算法(源码+数据)
语音识别技术是现代信息技术中的一个重要领域,特别是在人机交互、智能设备、智能家居、自动驾驶等多个领域有着广泛应用。MATLAB作为一种强大的数值计算和数据可视化环境,因其易用性和丰富的库支持,常被用来实现复杂的算法,包括语…...
RabbitMQ的高级特性介绍(一)
消息确认机制 ⽣产者发送消息之后, 到达消费端之后, 可能会有以下情况: a. 消息处理成功 b. 消息处理异常 RabbitMQ向消费者发送消息之后, 就会把这条消息删掉, 那么第二种情况, 就会造成消息丢失。 那么如何确保消费端已经成功接收了, 并正确处理了呢? 为了保证消息从队列…...
QML开发入门1--安装QT6.8和新建第一个QtQuickApplication
1.下载在线安装工具 qt-online-installer-windows-x64-4.8.1.exe 2.安装 注:可能官网qt安装很慢。需要使用国内镜像源。推荐阿里镜像 qt-online-installer-windows-x64-4.8.1.exe --mirror https://mirrors.aliyun.com/qt3.配置QT关键配置 3.1 无法编译 注&#…...
指令系统2(Load/Store 指令)
一. Load/Store 指令 1. 前变址 前变址指令是在读取或存储数据时,先根据基址寄存器(Rn)与偏移量(offset)计算出有效地址,再进行数据操作。相关指令及示例如下: LDR R0, [R1, #4]:从…...
【实战案例】用STAR+3W模型拆解电商支付系统设计文档
各位开发者朋友,上次分享了结构化写作的黄金公式后,很多同学反馈需要更具象的落地方法。今天通过真实电商支付系统案例,手把手教你用STAR3W模型写出可执行的设计文档! 结构化写作的「黄金公式」 STAR原则 3W模型 Situation&…...
C#使用SnsPictureBox.dll绘制点,线段、圆、折线、多边形、测量尺等多种图形。
CSDN下载地址:https://download.csdn.net/download/sns1991sns/87726867 gitee下载地址:https://gitee.com/linsns/SnsPictrueBox 支持2种绘制方式:响应式和等待式。 一、使用响应式绘制图形 1、在窗口构造函数里添加绘制图形的完成响应函数 public…...
如何让节卡机器人精准对点?
如何让节卡机器人精准对点? JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏:控制柜管理,机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…...
文转语音好用的平台
一、国外平台推荐 第一梯队:全球头部服务 Amazon Polly(AWS) 特点:支持 70语言/方言,提供神经语音(NTTS)和标准语音,可克隆声音(Voice Designer)。平台&…...
常见JavaScript页面部分内容显示/隐藏设置总结
项目中经常遇到通过js判断对页面中某一部分进行显示/隐藏设置的场景,经常使用的是display,有时也会使用visibility、opacity,为此,特意查询了相关内容,对其进行了一下汇总记录下: 除了 display,…...
在 Spring Boot 中调用 AnythingLLM 的发消息接口
整体逻辑: 自建系统的web UI界面调用接口: 1.SpringBoot接口:/anything/chatMessageAnything 2.调用anythingLLM - 调用知识库deepseek r1 . Windows Installation ~ AnythingLLMhttps://docs.anythingllm.com/installation-desktop/windows http://localhost:3…...
TextView、AppCompatTextView和MaterialTextView该用哪一个?Android UI 组件发展史与演进对照表
在 Android 开发中,UI 组件一直在不断演进,从最初的原生组件,到 Support Library(AppCompat 兼容库),再到如今的 Material Design 组件。这篇文章将梳理 Android UI 组件的发展历史,并提供详细的…...
[GHCTF 2025]Popppppp[pop链构造] [php原生类的利用] [双md5加密绕过]
题目 <?php error_reporting(0);class CherryBlossom {public $fruit1;public $fruit2;public function __construct($a) {$this->fruit1 $a;}function __destruct() {echo $this->fruit1;}public function __toString() {$newFunc $this->fruit2;return $new…...
2025.3.20总结
阅读:《时间贫穷》第二章,里面讲到,运动,多行善事,体验自然,都会增强自我效能感,是对抗时间焦虑的强有力的方式。 花时间运动是值得的,公司每周三都是运动周,把运动视作…...
Tr0ll2靶机详解
一、主机发现 arp-scan -l靶机ip:192.168.55.164 二、端口扫描、漏洞扫描、目录枚举、指纹识别 2.1端口扫描 nmap --min-rate 10000 -p- 192.168.55.164发现21端口的ftp服务开启 以UDP协议进行扫描 使用参数-sU进行UDP扫描 nmap -sU --min-rate 10000 -p- 19…...
制造业数字化转型,汽车装备制造企业数字化转型案例,智能制造数字化传统制造业数字化制造业数字化转型案例
《某制造业企业信息化整体解决方案》PPT展示了一个汽车装备企业的整体信息化解决方案,阐述了该企业的业务特点和现状,主要包括按订单生产、多级计划和产品跟踪等,分析了信息化建设的主要困难,如信息管理手工化、过程数据追溯困难、…...
PyTorch模型转ONNX例子
参考:(optional) Exporting a Model from PyTorch to ONNX and Running it using ONNX Runtime — PyTorch Tutorials 2.6.0cu124 documentation import numpy as np import torch.utils.model_zoo as model_zoo import torch.onnx import torch.nn as nn import t…...
科技云报到:AI Agent打了个响指,商业齿轮加速转动
科技云报到原创。 3月16日,百度旗下文心大模型4.5和文心大模型X1正式发布。目前,两款模型已在文心一言官网上线,免费向用户开放。 同时,文心大模型4.5已上线百度智能云千帆大模型平台,企业用户和开发者登录即可调用AP…...
【蓝桥杯python研究生组备赛】005 数学与简单DP
题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…...
