73 lines
3.6 KiB
JavaScript
73 lines
3.6 KiB
JavaScript
import { chmod, cp, mkdir, rm, writeFile } from 'node:fs/promises'
|
||
import { arch, platform } from 'node:os'
|
||
import { join, resolve } from 'node:path'
|
||
import { spawnSync } from 'node:child_process'
|
||
|
||
const root = resolve(import.meta.dirname, '..')
|
||
const native = join(root, 'connector', 'native')
|
||
const releaseRoot = join(root, 'release', 'connector')
|
||
const commonSources = [
|
||
'json.cpp', 'encoding.cpp', 'zip.cpp', 'config.cpp', 'platform_common.cpp',
|
||
'process_posix.cpp', 'process_windows.cpp', 'workspace.cpp', 'http_server.cpp',
|
||
'connector_service.cpp',
|
||
].map((name) => join(native, name))
|
||
|
||
function run(command, args) {
|
||
const result = spawnSync(command, args, { cwd: root, stdio: 'inherit', shell: false })
|
||
if (result.error) throw result.error
|
||
if (result.status !== 0) throw new Error(`${command} 构建失败(退出码 ${result.status})`)
|
||
}
|
||
|
||
async function buildMac() {
|
||
const packageDir = join(releaseRoot, `macos-${arch()}`)
|
||
const app = join(packageDir, 'Spine粒子连接器.app')
|
||
const executable = join(app, 'Contents', 'MacOS', 'SpineParticleConnector')
|
||
await rm(packageDir, { recursive: true, force: true })
|
||
await mkdir(join(app, 'Contents', 'MacOS'), { recursive: true })
|
||
await mkdir(join(app, 'Contents', 'Resources'), { recursive: true })
|
||
run(process.env.CXX || 'clang++', [
|
||
'-std=c++17', '-O2', '-Wall', '-Wextra', '-Werror', '-fobjc-arc',
|
||
...commonSources, join(native, 'app_macos.mm'),
|
||
'-framework', 'AppKit', '-framework', 'Foundation', '-o', executable,
|
||
])
|
||
await chmod(executable, 0o755)
|
||
await writeFile(join(app, 'Contents', 'Info.plist'), `<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0"><dict>
|
||
<key>CFBundleDisplayName</key><string>Spine粒子连接器</string>
|
||
<key>CFBundleExecutable</key><string>SpineParticleConnector</string>
|
||
<key>CFBundleIdentifier</key><string>com.spineparticle.connector</string>
|
||
<key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
|
||
<key>CFBundleName</key><string>Spine粒子连接器</string>
|
||
<key>CFBundlePackageType</key><string>APPL</string>
|
||
<key>CFBundleShortVersionString</key><string>2.0.0</string>
|
||
<key>CFBundleVersion</key><string>2.0.0</string>
|
||
<key>LSMinimumSystemVersion</key><string>11.0</string>
|
||
<key>NSHighResolutionCapable</key><true/>
|
||
</dict></plist>
|
||
`, 'utf8')
|
||
await cp(join(root, 'connector', 'DISTRIBUTION.md'), join(packageDir, '使用说明.md'))
|
||
console.log(`已生成 macOS 应用:${app}`)
|
||
}
|
||
|
||
async function buildWindows() {
|
||
const packageDir = join(releaseRoot, `windows-${arch()}`)
|
||
const executable = join(packageDir, 'Spine粒子连接器.exe')
|
||
await rm(packageDir, { recursive: true, force: true })
|
||
await mkdir(packageDir, { recursive: true })
|
||
const compiler = process.env.CXX || 'cl.exe'
|
||
if (/cl(?:\.exe)?$/i.test(compiler)) {
|
||
run(compiler, ['/nologo', '/std:c++17', '/O2', '/EHsc', '/utf-8', '/W4', ...commonSources, join(native, 'app_windows.cpp'),
|
||
'/link', '/SUBSYSTEM:WINDOWS', `'/OUT:${executable}'`.replaceAll("'", ''), 'ws2_32.lib', 'comdlg32.lib', 'user32.lib', 'gdi32.lib'])
|
||
} else {
|
||
run(compiler, ['-std=c++17', '-O2', '-Wall', '-Wextra', '-Werror', ...commonSources, join(native, 'app_windows.cpp'),
|
||
'-municode', '-mwindows', '-lws2_32', '-lcomdlg32', '-o', executable])
|
||
}
|
||
await cp(join(root, 'connector', 'DISTRIBUTION.md'), join(packageDir, '使用说明.md'))
|
||
console.log(`已生成 Windows 应用:${executable}`)
|
||
}
|
||
|
||
if (platform() === 'darwin') await buildMac()
|
||
else if (platform() === 'win32') await buildWindows()
|
||
else throw new Error('桌面连接器 App 当前支持 macOS 和 Windows')
|