Emscripten + CMakeLists.txt 将 C++ 项目编译成 WebAssembly(.wasm)/js,并编译 Html 测试

背景:Web 端需要使用已有的 C++ 库(使用 CMake 编译),需要将 C++ 项目编译成 WebAssembly(.wasm) 供 js 调用。

上篇文章《Mac 上安装 Emscripten》 已讲解如何安装配置 Emscripten 环境。

本篇文章主要讲解如何将基于 CMakeLists 配置的 C++ 项目编译成 WebAssembly 库来供 Web 前端使用。编译结果会生成 .wasm、.js,测试代码会生成 .wasm、.js、.html。

一、构建基于 CMakeList 的 C++ 库及测试 Demo 工程

目录结构如下:

比如 test_lib 就是我们原有的 C++ 库,这里测试简单写了个数学库,包含加法函数和减法函数。我们最终需要提供 libtest_lib.wasm 前端同学用。main.cpp 是自己用来测试 libtest_lib.wasm 的。所有涉及的代码及编译脚本在本文末尾。

二、编译项目库及测试 Demo

执行脚本 ./build_web.sh 记得给执行权限:chmod +x build_web.sh
脚本主要执行以下操作:

emcmake cmake -B build/web
emmake make
emcc libtest_lib.a -o libtest_lib.js

编译输出结果如下:
在这里插入图片描述

输出的 test_lib 库,在 cmake_demo/build/libs/web 目录下

输出的测试 demo,在 cmake_demo/build/web 目录下

三、测试

3.1 启动 Server

要在本地浏览器测试 .wasm 需要启动 server,否则报错,具体原因上篇文章《Mac 上安装 Emscripten》 有说明。

进入到 cmake_demo/build/web 所在目录执行 python -m http.server 9090 启动服务。

3.2 在浏览器测试

在浏览器地址栏输入:

http://localhost:9090/test_main.html

可以看到如下结果:
与 main.cpp 里的函数调用预期结果一致。

四、所有涉及的代码及编译脚本

math_test.h 代码如下:
只有两个函数:test_add、test_sub

/*** Author: AlanWang4523.* Date: 2023/10/31 16:08.* Mail: alanwang4523@gmail.com*/#ifndef CMAKEDEMO_MATH_TEST_H
#define CMAKEDEMO_MATH_TEST_H#ifdef __cplusplus
extern "C" {
#endifint test_add(int a, int b);
int test_sub(int a, int b);#ifdef __cplusplus
}
#endif#endif //CMAKEDEMO_MATH_TEST_H

math_test.cpp 代码如下:

/*** Author: AlanWang4523.* Date: 2023/10/31 16:08.* Mail: alanwang4523@gmail.com*/#include "math_test.h"#ifdef __cplusplus
extern "C" {
#endifint test_add(int a, int b) {return a + b;
}int test_sub(int a, int b) {return a - b;
}#ifdef __cplusplus
}
#endif

test_lib/CMakeLists.txt 代码如下:

include_directories(./)
include_directories(inc)
AUX_SOURCE_DIRECTORY(src DIR_TONE_CHANGE_SRCS)
add_library(test_lib ${DIR_TONE_CHANGE_SRCS})

math.cpp 代码如下:

#include <iostream>
#include "test_lib/inc/math_test.h"int main(int argc, const char * argv[]) {std::cout << "Hello AlanWang4523\n";int ret = test_add(1, 2);std::cout << "test_add: 1 + 2 = " << ret << "\n" ;ret = test_sub(3, 2);std::cout << "test_sub: 3 - 2 = " << ret << "\n" ;return 0;
}

CMakeLists.txt 代码如下:

cmake_minimum_required(VERSION 3.6)
project(test_main)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_CXX_STANDARD 11)include_directories(./ test_lib test_lib/inc)
add_subdirectory(test_lib)set(CMAKE_EXECUTABLE_SUFFIX ".html") # 编译生成.htmladd_executable(test_main main.cpp)
target_link_libraries(test_main test_lib)

build_web.sh 编译脚本如下:

#!/bin/sh# @Time    : 2023-10-31 16:59
# @Author  : AlanWang
# @FileName: build_web.shOUTPUT_LIBS="./build/libs/web"function build_for_webassembly() {BUILD_DIR="./build/web"PRE_EXE_DIR=$(pwd)echo ${PRE_EXE_DIR}emcmake cmake \-H"./" \-B"${BUILD_DIR}" \-DCMAKE_LIBRARY_OUTPUT_DIRECTORY="./build/web/libs/" \-DCMAKE_BUILD_TYPE="Release"cd ${BUILD_DIR}emmake makecd ${PRE_EXE_DIR}mkdir -p ${OUTPUT_LIBS}/mv ${PRE_EXE_DIR}/lib/* ${OUTPUT_LIBS}/
#	rm -r ./build/webTARGET_NAME=""for file in $(ls ${OUTPUT_LIBS})doif [ "${file##*.}" == "a" ]; thenTARGET_NAME=${file%.*}breakfidoneecho "AlanTest::=====>>TARGET_NAME: ${TARGET_NAME}"emcc -s ALLOW_MEMORY_GROWTH=1 ${OUTPUT_LIBS}/${TARGET_NAME}.a -o ${OUTPUT_LIBS}/${TARGET_NAME}.js
}build_for_webassembly

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/175850.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gitee 发行版

Gitee 发行版 1、Gitee 发行版管理2、项目仓库中创建发行版本3、项目中导入3.1 gradle配置3.2 dependencies执行正常&#xff0c;包没有下载 1、Gitee 发行版管理 Gitee 发行版&#xff08;Release&#xff09;管理 2、项目仓库中创建发行版本 按照Gitee官网操作就行 3、项目…

PCIe 访问 EP 配置空间,空间映射详解,BDF 计算偏移

访问 EP 的配置空间方法 内存映射IO 访问 内存访问配置空间 前置知识 PCIe 设备的寻址是按照 BDF 即 Bus-Device-Function 来组织的。访问某个设备则需要根据BDF计算偏移地址。 两种不同的内存访问配置空间方法 类 xilinx&#xff0c;基地址 偏移地址访问 // linux-5.10\…

http1,https,http2,http3总结

1.HTTP 当我们浏览网页时&#xff0c;地址栏中使用最多的多是https://开头的url&#xff0c;它与我们所学的http协议有什么区别&#xff1f; http协议又叫超文本传输协议&#xff0c;它是应用层中使用最多的协议&#xff0c; http与我们常说的socket有什么区别吗&#xff1f; …

【ARM 嵌入式 C 入门及渐进 10 -- 冒泡排序 选择排序 插入排序 快速排序 归并排序 堆排序 比较介绍】

文章目录 排序算法小结排序算法C实现排序方法的稳定性 排序算法小结 C语言中常用的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。下面我们来一一介绍&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a;冒泡排序是通过比较相邻…

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…

MWeb Pro for Mac:博客生成编辑器,助力你的创作之旅

在当今数字化时代&#xff0c;博客已经成为了许多人记录生活、分享知识和表达观点的重要渠道。而要打造一个专业、美观且易于管理的博客&#xff0c;选择一款强大的博客生成编辑器至关重要。今天&#xff0c;我向大家推荐一款备受好评的Mac软件——MWeb Pro。 MWeb Pro是一款专…

flutter深研

https://www.douyin.com/video/7020336319058627853 关闭系统风扇 在 Windows 操作系统上安装和配置 Flutter 开发环境 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 下载Git - Downloading Package 推荐使用迅雷下载 系统配置要求 要想安装和运行 Flutter&#xf…

使用FastAPI部署Ultralytics YOLOv5模型

YOLO是You Only Look Once(你只看一次)的缩写&#xff0c;它具有识别图像中的物体的非凡能力&#xff0c;在日常应用中会经常被使用。所以在本文中&#xff0c;我们将介绍如何使用FastAPI的集成YOLOv5&#xff0c;这样我们可以将YOLOv5做为API对外提供服务。 Python有几个web框…

如何将 ruby 打包类似于jdk在另一台相同架构的机器上面开箱即用

需求 目前工作中使用到了ruby作为java 项目的中转语言&#xff0c;但是部署ruby的时候由于环境的不同会出现安装依赖包失败的问题&#xff0c;如何找到一种开箱即用的方式类似于java 中的jdk内置jvm这种方式 解决 TruffleRuby 完美解决问题&#xff0c;TruffleRuby 是使用 T…

基于STC系列单片机实现外部中断0控制按键调节定时器0产生PWM(脉宽调制)的功能

#define uchar unsigned char//自定义无符号字符型为uchar #define uint unsigned int//自定义无符号整数型为uint sbit PwmOut P1^0;//位定义脉宽调制输出为单片机P1.0脚 uchar PwmTimeCount;//声明脉宽调制时间计数变量 uchar PwmDutyCycle;//声明脉宽调制占空比变量 void Ti…

Apache服务的搭建与配置(超详细版)

前言 Apache是一种常见的Web服务器软件&#xff0c;广泛用于Linux和其他UNIX操作系统上。它是自由软件&#xff0c;可以通过开放源代码的方式进行自由分发和修改。Apache提供了处理静态和动态内容的能力&#xff0c;而且还支持多种编程语言和脚本&#xff0c;如PHP、Python和P…

python数据可视化

内容主要介绍了python模块matplotlib即seaborn数据可视化 matplotlib模块通过import matplotlib.pyplot as plt生成图形&#xff0c;如生成图形没展示&#xff0c;可调用plt.show()方法展示图形&#xff1b; 对于颜色属性设置&#xff0c;既可以使用十六进制颜色表达(#7777aa…

cdrx8和2020哪个版本更好用?有什么区别

经过多年的发展&#xff0c;cdr推出了很多优秀的版本&#xff0c;并顺应时代的发展更新了多项功能。随着cdr推出的软件版本增多&#xff0c;小伙伴们可选择的产品也在增多&#xff0c;那么该怎么选择呢&#xff1f;本文会给大家介绍cdrx8和2020的区别&#xff0c;CDRX8和2020哪…

Pytorch 猫狗识别案例

猫狗识别数据集https://download.csdn.net/download/Victor_Li_/88483483?spm1001.2014.3001.5501 训练集图片路径 测试集图片路径 训练代码如下 import torch import torchvision import matplotlib.pyplot as plt import torchvision.models as models import torch.nn as…

基于静电放电算法的无人机航迹规划-附代码

基于静电放电算法的无人机航迹规划 文章目录 基于静电放电算法的无人机航迹规划1.静电放电搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用静电放电算法来优化无人机航迹规划。 …

0基础学习PyFlink——用户自定义函数之UDF

大纲 标量函数入参并非表中一行&#xff08;Row&#xff09;入参是表中一行&#xff08;Row&#xff09;alias PyFlink中关于用户定义方法有&#xff1a; UDF&#xff1a;用户自定义函数。UDTF&#xff1a;用户自定义表值函数。UDAF&#xff1a;用户自定义聚合函数。UDTAF&…

1400*C. Team(模拟构造)

Problem - 401C - Codeforces 解析&#xff1a; 因为0不能相邻&#xff0c;所以0之间最少 n-1 个位置&#xff0c;最多 n1 个位置&#xff0c;如果 m<n-1显然不符题意。 并且1最多连续两个&#xff0c;所以 m>2*n2 同样不符题意。 其余情况构造即可 #include<bits/st…

【嵌入式】【GIT】如何迁移老的GIF到新的仓库时使用LFS功能并保持LOG不变

一、正常迁移流程 假设有仓库 ssh://old/buildroot-201902 需要迁移到新的仓库 ssh://old/buildroot-201902时,我们可以使用以下命令来完成: # 下载老的仓库 git clone ssh://old/buildroot-201902 # 向新的仓库上传所有的tags git push ssh://new/buildroot-201902 --tag…

【网络安全】Seeker内网穿透追踪定位

Seeker追踪定位对方精确位置 前言一、kali安装二、seeker定位1、ngrok平台注册2、获取一次性邮箱地址3、ngrok平台登录4、ngrok下载5、ngrok令牌授权6、seeker下载7、运行seeker定位8、运行隧道开启监听9、伪装链接10、用户点击&#xff08;获取定位成功&#xff09;11、利用经…

Rust-虽然9天过去了,结果是没有结果(Docker容器的端口映射问题)

​ 这篇文章收录于Rust 实战专栏。这个专栏中的相关代码来自于我开发的笔记系统。它启动于是2023年的9月14日。相关技术栈目前包括&#xff1a;Rust&#xff0c;Javascript。关注我&#xff0c;我会通过这个项目的开发给大家带来相关实战技术的分享。 前言 上上周了吧&#xf…