electron集成C++编译环境

背景

由于对 C++ 不够熟悉,加之现有信息资源有限,在尝试将 Electron 应用与 C++ 运行环境集成的过程中如同摸石头过河。如果您在阅读下文时发现任何不妥之处,请不吝赐教。

集成

windows

1. 下载免安装C++环境包

在mingw-w64中找到符合的免安装包;

www.mingw-w64.org/downloads/

github.com/skeeto/w64d...

解压后的内容,如下图所示;

试验了下,通过w64devkit.exe可以成功将cpp文件编程成exe文件,并执行输出"Hello world";

将w64devkit复制到Electron项目内,至此环境的准备工作已经完成;

2. 通过node将用用户输入的内容生成cpp文件

javascript 复制代码
// 通过fs将数据写入到filepath(cpp文件)中
fs.writeFile(filepath, data, (err, res) => {
})

3. 通过node调用child_process执行命令编译CPP文件

关键在于需要将上面准备好的C++环境,加入到当前spawn的执行环境中;

javascript 复制代码
// 设置子进程的环境变量,将 W64DevKit 的 bin 文件夹添加到 PATH
const w64devkitDir = path.resolve(__dirname, '../cpp_bin');

const customEnv = Object.assign({}, process.env, {
  PATH: `${w64devkitDir}\bin;${process.env.PATH}`,
  Path: `${w64devkitDir}\bin;${process.env.Path}`,
})

spawn(`g++`, ['-o', outputFile, sourceFile], { 
  cwd: process.cwd(), // 使用当前工作目录
  env: customEnv // 设置自定义环境变量
});

编译后得到exe文件;

4. 执行exe文件,并进行数据交互与回显

javascript 复制代码
// exe 为上一步骤生成的exe文件
this.exe = spawn(exe);

this.exe.stdout.on('data', (data) => {
 // 处理数据,在界面进行回显
 // PS: 可能需要decode以下,否则会乱码:new TextDecoder().decode(data);
})

// 监听用户在终端的输入,进行交互
cinExe(e, data) {
  this.exe.stdin.write(`${data}\n`);
}

至此,编译C++的核心已基本完成,剩下的只需要在electron通过xterm实现伪终端,react-ace实现编辑器,即可进行业务交互,从而实现本地编译了;

Mac

Mac大致思路与Windows相似,某些细节稍微有区别;

1. 下载免安装C++环境包

Mac不同版本的系统,需要使用不同版本的免安装C++环境包;

hpc.sourceforge.net/

因此先需要将这些资源下载到自己的云端存储;

在electron中通过获取用户的设备信息,对系统型号进行判断;

c 复制代码
// 获取系统版本号
const darwinVersion = parseInt(os.release().split('.')[0], 10);

// 系统版本 => 系统名字 的映射
const versionMap = {
  // ...
  18: 'Mojave', // 10.14
  19: 'Catalina', // 10.15
  // macOS Big Sur (11.0) 以及之后的版本号与 Darwin 版本号一致
  20: 'Big Sur', // 11.0
  21: 'Monterey', // 12.0
  // ...
}

// 获取芯片类型
exec('sysctl -a | grep machdep.cpu.brand_string', (error, stdout, stderr) => {
    if (error || stderr) {
      // error
    }
    
    let processorType = 'Unknown';
    if (stdout.includes("Apple M1")) {
      processorType = "M1";
    } else if (stdout.includes("Apple M2")) {
      processorType = "M2";
    } else if (stdout.includes("Apple M3")) {
      processorType = "M3";
    } else if (stdout.includes("Intel")) {
      processorType = "Intel";
    }
  });
})

// 通过系统名字,以及芯片类型,既可下载对应的C++环境进行使用了

2. 通过node将用用户输入的内容生成cpp文件

与windows类似,不赘述;

3. 通过node调用child_process执行命令编译CPP文件

与windows类似,区别在于需要修改DYLD_LIBRARY_PATH指向lib库;

javascript 复制代码
// 设置子进程的环境变量,将 W64DevKit 的 bin 文件夹添加到 PATH
const w64devkitDir = path.resolve(__dirname, '../cpp_bin');

const customEnv = Object.assign({}, process.env, {
  PATH: `${w64devkitDir}\bin;${process.env.PATH}`,
  Path: `${w64devkitDir}\bin;${process.env.Path}`,
  DYLD_LIBRARY_PATH: `${w64devkitDir}/lib:${process.env.DYLD_LIBRARY_PATH}`,
})

const currentGcc = `${w64devkitDir}/bin/g++`;
spawn(currentGcc, ['-o', outputFile, sourceFile], { 
  cwd: process.cwd(), // 使用当前工作目录
  env: customEnv // 设置自定义环境变量
});

编译后得到exe文件;

4. 执行exe文件,并进行数据交互与回显

与windows类似,不赘述;

5. xcode

在 macOS 上,许多这样的系统级开发头文件随 Xcode 的 Command Line Tools 一同安装;这些工具包提供 macOS 系统级的编译器和一些标准库的头文件等资源;若未安装这些工具包,可能会导致无法编译;

csharp 复制代码
# 确认是否有安装
xcode-select -p

# 若没有安装,则通过以下命令进行安装
xcode-select --install
相关推荐
wljy16 小时前
二、进制状态转换
linux·运维·服务器·c语言·c++
云泽8086 小时前
笔试算法 -位运算篇(二):从唯一字符到消失数字
c++·算法·位运算
繁华落尽,倾城殇?7 小时前
[C++11] : atomic,nullptr,default/delete,enum class
开发语言·c++·c++11·nullptr·atomic·enum class·default/delete
代码村新手7 小时前
C++-二叉搜索树
开发语言·c++
智者知已应修善业8 小时前
【51单片机8位数码管动态显示日期小数点风格】2023-11-13
c++·经验分享·笔记·算法·51单片机
智者知已应修善业8 小时前
【51单片机有三个LED 分别第一个灯闪三下 再到第二个灯又闪三下 再到第三个灯又闪三下 就这样循环程序】2023-11-16
c++·经验分享·笔记·算法·51单片机
玖釉-12 小时前
二叉树展开为链表:从先序遍历到原地指针重排
c++·windows·算法·leetcode·链表
Mister西泽12 小时前
C++ Primer Plus 第六版 编程练习题及详细答案
开发语言·c++·学习·visual studio
Qt程序员12 小时前
从上电到系统就绪:ARM+U-Boot 嵌入式 Linux 启动流程
linux·运维·c++·内核·设备树·嵌入式·ram
cany100013 小时前
C++ -- lambda捕获
c++