Files
smart_wasm/scripts/build.ps1
2026-06-01 15:55:59 +08:00

395 lines
13 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# build.ps1 - 智能 WASM 构建脚本
param(
[switch]$Clean,
[switch]$Serve,
[switch]$Test,
[string]$BuildType = "Release"
)
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host " 智能 JSON-WASM 项目构建系统 " -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""
# 1. 设置环境变量
$EmsdkPath = "E:\emsdk"
if (-not (Test-Path $EmsdkPath)) {
Write-Host "[错误] 未找到 Emscripten" -ForegroundColor Red
Write-Host "请确保 Emscripten 安装在: $EmsdkPath" -ForegroundColor Yellow
exit 1
}
# 设置 PATH
$env:PATH = "$EmsdkPath\upstream\emscripten;$env:PATH"
Write-Host "[✓] 设置 Emscripten 环境" -ForegroundColor Green
# 2. 清理旧构建
if ($Clean) {
Write-Host "[ ] 清理构建文件..." -ForegroundColor Cyan
Remove-Item -Path "build", "public/wasm" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "[✓] 清理完成" -ForegroundColor Green
}
# 3. 创建目录
New-Item -Path "build", "public/wasm" -ItemType Directory -Force | Out-Null
# 4. 编译 WASM
Write-Host "[ ] 编译智能 WASM 模块..." -ForegroundColor Cyan
$startTime = Get-Date
# 编译命令 - 使用当前真实业务模块源码
$compileResult = emcc `
src/KinematicsWebAPI.cpp `
src/main.cpp `
src/Robot.cpp `
src/spc_core.cpp `
src/QuadrupedRobotSimulation/RobotConfig.cpp `
src/QuadrupedRobotSimulation/BaseClass.cpp `
src/QuadrupedRobotSimulation/KinematicsSimulation.cpp `
src/QuadrupedRobotSimulation/CompleteJsonExporter.cpp `
src/QuadrupedRobotSimulation/KinematicsReverse.cpp `
src/QuadrupedRobotSimulation/KinematicsHelper.cpp `
src/QuadrupedRobotSimulation/SharedGeometry.cpp `
src/FourBarMechanism/CrankSliderMechanism.cpp `
src/FourBarMechanism/CrankRockingBlockMechanism_Forward.cpp `
src/FourBarMechanism/CrankRockingBlockMechanism_Inverse.cpp `
src/FourBarMechanism/FourBarMechanism.cpp `
src/FourBarMechanism/SliderCrankMechanism.cpp `
src/RobotManager.cpp `
src/utils.cpp `
src/math_utils.cpp `
src/smart_json_wrapper.cpp `
src/kdl_parser/src/kdl_parser.cpp `
src/kdl_parser/src/joint.cpp `
src/kdl_parser/src/link.cpp `
src/kdl_parser/src/model.cpp `
src/kdl_parser/src/pose.cpp `
src/kdl_parser/src/tinystr.cpp `
src/kdl_parser/src/tinyxml.cpp `
src/kdl_parser/src/tinyxml2.cpp `
src/kdl_parser/src/tinyxmlerror.cpp `
src/kdl_parser/src/tinyxmlparser.cpp `
src/kdl_parser/src/twist.cpp `
src/kdl_parser/src/world.cpp `
-I./inc `
-I./inc/QuadrupedRobotSimulation `
-I./inc/FourBarMechanism `
-I./inc/SharedGeometry `
-I./src/kdl_parser/include `
-I./KDL/install_wasm/include `
-I./Eigen3 `
-I./Eigen3/eigen3 `
-L./KDL/install_wasm/lib `
-lorocos-kdl `
-std=c++17 `
-s WASM=1 `
-s EXPORTED_FUNCTIONS='["_init_func","_func","_smart_process_json","_smart_get_function_list","_smart_get_function_info","_smart_test_match","_smart_get_version","_smart_free_string","_wasm_malloc","_wasm_free","_malloc","_free","_add","_subtract","_multiply","_divide","_fibonacci","_create_buffer","_destroy_buffer","_compute_sum","_get_greeting","_main"]' `
-s EXPORTED_RUNTIME_METHODS='["UTF8ToString","stringToUTF8","lengthBytesUTF8","ccall","cwrap","HEAPU8","HEAP8","HEAPF32","HEAPF64","allocateUTF8"]' `
-s MODULARIZE=1 `
-s EXPORT_NAME='createSmartMathModule' `
-s ALLOW_MEMORY_GROWTH=1 `
-s ENVIRONMENT='web,node,worker' `
-s ASSERTIONS=1 `
-s DISABLE_EXCEPTION_CATCHING=0 `
-s INITIAL_MEMORY=67108864 `
-s MAXIMUM_MEMORY=268435456 `
-s STACK_SIZE=5242880 `
-s USE_PTHREADS=0 `
-O3 `
-Wno-deprecated-literal-operator `
-o public/wasm/smart_math.js 2>&1
$endTime = Get-Date
$duration = ($endTime - $startTime).TotalSeconds
if ($LASTEXITCODE -ne 0) {
Write-Host "[✗] 编译失败" -ForegroundColor Red
Write-Host $compileResult -ForegroundColor Red
exit 1
}
Write-Host "[✓] 编译完成" -ForegroundColor Green
# 5. 检查生成的文件
$jsFile = Get-Item "public/wasm/smart_math.js" -ErrorAction SilentlyContinue
$wasmFile = Get-Item "public/wasm/smart_math.wasm" -ErrorAction SilentlyContinue
if (-not $jsFile -or -not $wasmFile) {
Write-Host "[✗] 未找到生成文件" -ForegroundColor Red
exit 1
}
$jsSize = $jsFile.Length / 1KB
$wasmSize = $wasmFile.Length / 1KB
# 6. 显示构建结果
Write-Host ""
Write-Host "🎉 构建成功!" -ForegroundColor Green
Write-Host ("" * 50) -ForegroundColor DarkGray
Write-Host "📦 生成文件:" -ForegroundColor White
Write-Host "├─ smart_math.js ($($jsSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host "└─ smart_math.wasm ($($wasmSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host ""
Write-Host "✨ 功能特性:" -ForegroundColor White
Write-Host "├─ ✅ 机器人正逆解业务接口 (func/init_func)" -ForegroundColor Gray
Write-Host "├─ ✅ SPC / 四足机器人 / 连杆机构业务接口" -ForegroundColor Gray
Write-Host "├─ ✅ 智能 JSON 数学测试接口" -ForegroundColor Gray
Write-Host "├─ ✅ Node / Web 双环境加载" -ForegroundColor Gray
Write-Host "├─ ✅ 与 Emscripten 内存管理兼容" -ForegroundColor Gray
Write-Host "└─ ✅ 批量回归测试可直接调用" -ForegroundColor Gray
Write-Host ""
Write-Host "📁 输出目录: $((Get-Location).Path)\public\wasm" -ForegroundColor Gray
Write-Host "⏱️ 编译耗时: $($duration.ToString('F2'))" -ForegroundColor Gray
Write-Host ""
# 7. 生成 JavaScript 包装器(可选)
Write-Host "[ ] 生成 JavaScript 包装器..." -ForegroundColor Cyan
$jsWrapper = @"
// Smart WASM JSON API JavaScript
class SmartWasmAPI {
constructor() {
this.module = null;
this.initialized = false;
}
async initialize() {
if (this.initialized) return;
// WASM
this.module = await createSmartMathModule();
this.initialized = true;
console.log('Smart WASM API ');
return this;
}
async initializeBusinessApi() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._init_func();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
async processBusinessRequest(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
responsePtr = this.module._func(requestPtr);
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(' JSON :', error);
throw error;
} finally {
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
// JSON
async processJsonRequest(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
// JSON WASM
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
// WASM
responsePtr = this.module._smart_process_json(requestPtr);
// JavaScript
const responseStr = this.module.UTF8ToString(responsePtr);
// JSON
return JSON.parse(responseStr);
} catch (error) {
console.error(' JSON :', error);
throw error;
} finally {
//
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async getFunctionList() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._smart_get_function_list();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async callFunction(funcName, params = {}) {
const request = {
req_cmd: funcName,
...params
};
return await this.processJsonRequest(request);
}
//
async testSmartMatch(jsonRequest) {
if (!this.initialized) {
await this.initialize();
}
let requestPtr = null;
let responsePtr = null;
try {
requestPtr = this.module.allocateUTF8(JSON.stringify(jsonRequest));
responsePtr = this.module._smart_test_match(requestPtr);
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (requestPtr) {
this.module._free(requestPtr);
}
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
//
async getVersion() {
if (!this.initialized) {
await this.initialize();
}
let responsePtr = null;
try {
responsePtr = this.module._smart_get_version();
const responseStr = this.module.UTF8ToString(responsePtr);
return JSON.parse(responseStr);
} catch (error) {
console.error(':', error);
throw error;
} finally {
if (responsePtr) {
this.module._smart_free_string(responsePtr);
}
}
}
// JSON
callMathFunction(name, ...args) {
if (!this.initialized) {
throw new Error('WASM ');
}
switch (name.toLowerCase()) {
case 'add':
return this.module._add(args[0] || 0, args[1] || 0);
case 'subtract':
return this.module._subtract(args[0] || 0, args[1] || 0);
case 'multiply':
return this.module._multiply(args[0] || 0, args[1] || 0);
case 'divide':
return this.module._divide(args[0] || 0, args[1] || 1);
case 'fibonacci':
return this.module._fibonacci(args[0] || 0);
default:
throw new Error(': ' + name);
}
}
}
//
if (typeof window !== 'undefined') {
window.SmartWasmAPI = SmartWasmAPI;
}
export default SmartWasmAPI;
"@
$jsWrapper | Out-File -FilePath "public/wasm/smart_api_wrapper.js" -Encoding UTF8
Write-Host "[✓] 生成 JavaScript 包装器" -ForegroundColor Green
# 8. 本地测试(可选)
if ($Test) {
Write-Host "[ ] 运行本地测试..." -ForegroundColor Cyan
try {
node --version 2>&1 | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host "[ ] 执行 WASM 回归测试..." -ForegroundColor Cyan
node scripts/run_wasm_tests.js
}
} catch {
Write-Host "[!] 本地测试跳过(需要 Node.js" -ForegroundColor Yellow
}
}
# 9. 启动开发服务器(可选)
if ($Serve) {
Write-Host "[ ] 启动开发服务器..." -ForegroundColor Cyan
Write-Host " 访问: http://localhost:8080/smart_test.html" -ForegroundColor Yellow
Write-Host " 按 Ctrl+C 停止服务器" -ForegroundColor Yellow
Write-Host ""
Set-Location "public"
python -m http.server 8080
}
Write-Host ""
Write-Host "🚀 使用提示:" -ForegroundColor White
Write-Host "├─ 在 VS Code 中按 F5 启动调试" -ForegroundColor Gray
Write-Host "├─ 使用 Ctrl+Shift+B 快速构建" -ForegroundColor Gray
Write-Host "├─ 查看 public/wasm/smart_api_wrapper.js 了解 JavaScript API 使用" -ForegroundColor Gray
Write-Host "└─ 运行 \`npm run serve\` 启动开发服务器" -ForegroundColor Gray
Write-Host ""