mirror of
https://github.com/cocos/cocos-engine.git
synced 2026-09-07 00:02:53 +08:00
148 lines
5.5 KiB
TypeScript
148 lines
5.5 KiB
TypeScript
import { CocosParams, NativePackTool } from "../base/default";
|
|
import * as fs from 'fs-extra';
|
|
import * as ps from 'path';
|
|
import * as os from 'os';
|
|
import { cchelper, toolHelper, Paths } from "../utils";
|
|
import { cocosConfig } from "../cocosConfig";
|
|
import { spawn } from "child_process";
|
|
|
|
export interface IWindowsParam {
|
|
targetPlatform: 'x64';
|
|
vsVersion: string;
|
|
}
|
|
|
|
export class WindowsPackTool extends NativePackTool {
|
|
params!: CocosParams<IWindowsParam>;
|
|
|
|
async create() {
|
|
await this.copyCommonTemplate();
|
|
await this.copyPlatformTemplate();
|
|
await this.generateCMakeConfig();
|
|
await this.excuteCocosTemplateTask();
|
|
|
|
await this.encrypteScripts();
|
|
return true;
|
|
}
|
|
|
|
async generate() {
|
|
const nativePrjDir = this.paths.nativePrjDir;
|
|
|
|
const cmakePath = ps.join(this.paths.platformTemplateDirInPrj, 'CMakeLists.txt');
|
|
if (!fs.existsSync(cmakePath)) {
|
|
throw new Error(`CMakeLists.txt not found in ${cmakePath}`);
|
|
}
|
|
|
|
if (!fs.existsSync(nativePrjDir)) {
|
|
cchelper.makeDirectoryRecursive(nativePrjDir);
|
|
}
|
|
|
|
let generateArgs: string[] = [];
|
|
if (!fs.existsSync(ps.join(nativePrjDir, 'CMakeCache.txt'))) {
|
|
const vsVersion = this.getCmakeGenerator();
|
|
// const g = '';
|
|
if (vsVersion) {
|
|
const optlist = cocosConfig.cmake.windows.generators.filter((x) => x.V === vsVersion);
|
|
if (optlist.length > 0) {
|
|
generateArgs.push(`-G"${optlist[0].G}"`);
|
|
}
|
|
if (Number.parseInt(vsVersion) <= 2017) {
|
|
generateArgs.push('-A', this.params.platformParams.targetPlatform);
|
|
}
|
|
} else {
|
|
generateArgs = generateArgs.concat(await this.windowsSelectCmakeGeneratorArgs());
|
|
}
|
|
|
|
}
|
|
this.appendCmakeCommonArgs(generateArgs);
|
|
await toolHelper.runCmake([`-S"${cchelper.fixPath(this.paths.platformTemplateDirInPrj)}"`, `-B"${cchelper.fixPath(this.paths.nativePrjDir)}"`].concat(generateArgs));
|
|
return true;
|
|
}
|
|
|
|
async make() {
|
|
const nativePrjDir = this.paths.nativePrjDir;
|
|
await toolHelper.runCmake(['--build', `"${cchelper.fixPath(nativePrjDir)}"`, '--config', this.params.debug ? 'Debug' : 'Release', '--', '-verbosity:quiet']);
|
|
return true;
|
|
}
|
|
|
|
async windowsSelectCmakeGeneratorArgs(): Promise<string[]> {
|
|
|
|
console.log(`selecting visual studio generator ...`);
|
|
const visualstudioGenerators = cocosConfig.cmake.windows.generators;
|
|
|
|
const testProjDir = await fs.mkdtemp(ps.join(os.tmpdir(), 'cmakeTest_'));
|
|
const testCmakeListsPath = ps.join(testProjDir, 'CMakeLists.txt');
|
|
const testCppFile = ps.join(testProjDir, 'test.cpp');
|
|
{
|
|
const cmakeContent = `
|
|
cmake_minimum_required(VERSION 3.8)
|
|
set(APP_NAME test-cmake)
|
|
project(\${APP_NAME} CXX)
|
|
add_library(\${APP_NAME} test.cpp)
|
|
`;
|
|
const cppSrc = `
|
|
#include<iostream>
|
|
int main(int argc, char **argv)
|
|
{
|
|
std::cout << "Hello World" << std::endl;
|
|
return 0;
|
|
}
|
|
`;
|
|
await fs.writeFile(testCmakeListsPath, cmakeContent);
|
|
await fs.writeFile(testCppFile, cppSrc);
|
|
}
|
|
|
|
const tryRunCmakeWithArguments = (args: string[], workdir: string) => {
|
|
return new Promise<boolean>((resolve, reject) => {
|
|
const cp = spawn(Paths.cmakePath, args, {
|
|
cwd: workdir,
|
|
env: process.env,
|
|
shell: true,
|
|
});
|
|
cp.on('close', (code, sig) => {
|
|
if (code !== 0) {
|
|
resolve(false);
|
|
return;
|
|
}
|
|
resolve(true);
|
|
});
|
|
});
|
|
};
|
|
const availableGenerators: string[] = [];
|
|
for (const cfg of visualstudioGenerators) {
|
|
const nativePrjDir = ps.join(testProjDir, `build_${cfg.G.replace(/ /g, '_')}`);
|
|
const args: string[] = [`-S"${testProjDir}"`, `-G"${cfg.G}"`, `-B"${nativePrjDir}"`];
|
|
args.push('-A', this.params.platformParams.targetPlatform);
|
|
await fs.mkdir(nativePrjDir);
|
|
if (await tryRunCmakeWithArguments(args, nativePrjDir)) {
|
|
availableGenerators.push(cfg.G);
|
|
break;
|
|
}
|
|
await cchelper.removeDirectoryRecursive(nativePrjDir);
|
|
}
|
|
await cchelper.removeDirectoryRecursive(testProjDir);
|
|
|
|
const ret: string[] = [];
|
|
if (availableGenerators.length === 0) {
|
|
return []; // use cmake default option -G
|
|
}
|
|
const opt = visualstudioGenerators.filter((x) => x.G === availableGenerators[0])[0];
|
|
ret.push('-A', this.params.platformParams.targetPlatform);
|
|
console.log(` using ${opt.G}`);
|
|
return ret;
|
|
}
|
|
|
|
getCmakeGenerator() {
|
|
return this.params.platformParams.vsVersion || '';
|
|
}
|
|
|
|
async run(): Promise<boolean> {
|
|
const executableDir = ps.join(this.paths.nativePrjDir, this.params.debug ? 'Debug' : 'Release')
|
|
const executableName = `${this.params.projectName}.exe`;
|
|
if (!fs.existsSync(ps.join(executableDir, executableName))) {
|
|
throw new Error(`[windows run] '${executableName}' is not found within ' + ${executableDir}!`);
|
|
}
|
|
await cchelper.runCmd(executableName, [], false, executableDir);
|
|
return true;
|
|
}
|
|
}
|