Files
Kmake/lib/internal/main/run_main_module.js
2026-05-26 23:36:42 -07:00

461 lines
10 KiB
JavaScript

'use strict';
const {
RegExpPrototypeExec,
} = primordials;
const {
prepareMainThreadExecution,
markBootstrapComplete,
} = require('internal/process/pre_execution');
const { getOptionValue } = require('internal/options');
const { emitExperimentalWarning } = require('internal/util');
//const isEntryURL = getOptionValue('--entry-url');
const mainEntry = prepareMainThreadExecution(false); //(!isEntryURL);
markBootstrapComplete();
// Necessary to reset RegExp statics before user code runs.
RegExpPrototypeExec(/^/, '');
//if (isEntryURL) {
// emitExperimentalWarning('--entry-url');
//}
//require('internal/modules/cjs/loader').Module.runMain(mainEntry);
const os = require('os');
let defaultTarget = '';
if (os.platform() === 'linux') {
defaultTarget = 'linux';
}
else if (os.platform() === 'win32') {
defaultTarget = 'windows';
}
else if (os.platform() === 'freebsd') {
defaultTarget = 'freebsd';
}
else {
defaultTarget = 'osx';
}
let options = [
{
full: 'from',
value: true,
description: 'Location of your project',
metavar: 'file',
default: '.'
},
{
full: 'to',
value: true,
metavar: 'file',
description: 'Build location',
default: 'build'
},
{
full: 'target',
short: 't',
value: true,
description: 'Target platform',
default: defaultTarget
},
{
full: 'vr',
value: true,
description: 'Target VR device',
default: 'none'
},
{
full: 'pch',
description: 'Use precompiled headers for C++ targets',
value: false
},
{
full: 'intermediate',
description: 'Intermediate location for object files.',
value: true,
default: '',
hidden: true
},
{
full: 'graphics',
short: 'g',
description: 'Graphics API to use',
value: true,
default: 'default'
},
{
full: 'arch',
description: 'Target architecture for compilation',
value: true,
default: 'default'
},
{
full: 'audio',
short: 'a',
description: 'Audio API to use',
value: true,
default: 'default'
},
{
full: 'visualstudio',
short: 'v',
description: 'Version of Visual Studio to use',
value: true,
default: 'vs2022'
},
{
full: 'compile',
description: 'Compile executable',
value: false
},
{
full: 'run',
description: 'Run executable',
value: false
},
{
full: 'update',
description: 'Update Kore and its submodules',
value: false
},
{
full: 'debug',
description: 'Compile in debug mode',
value: false
},
{
full: 'server',
description: 'Run local HTTP server for html5 target',
value: false
},
{
full: 'port',
description: 'Running port for the server',
metavar: 'n',
value: true,
default: 8080
},
{
full: 'noshaders',
description: 'Do not compile shaders',
value: false
},
{
full: 'kore',
short: 'k',
description: 'Location of Kore directory',
metavar: 'dir',
value: true,
default: ''
},
{
full: 'init',
description: 'Initialize a Kore project inside the current directory',
value: false
},
{
full: 'name',
description: 'Project name to use when initializing a project',
value: true,
default: 'Project'
},
{
full: 'kfile',
value: true,
description: 'Name of your kfile',
metavar: 'file',
default: 'kfile.js'
},
{
full: 'compiler',
value: true,
description: 'Use a specific compiler',
metavar: 'file',
default: 'default'
},
{
full: 'onlyshaders',
value: false,
description: 'Compile only shaders'
},
{
full: 'nosigning',
value: false,
description: 'Disable code signing for iOS'
},
{
full: 'lib',
value: false,
description: 'Compile to a static library'
},
{
full: 'dynlib',
value: false,
description: 'Compile to a dynamic library'
},
{
full: 'vscode',
value: false,
description: 'Create a vscode project (used automatically by the vscode Kore extension)'
},
{
full: 'tolang',
value: true,
description: 'Export IDL specified in kfile to wrapper for specified language'
},
{
full: 'json',
value: false,
description: 'Export a JSON file that describes the project'
},
{
full: 'stdout',
value: false,
description: 'Output to stdout instead of to a file. Currently only applies to --json.'
},
{
full: 'cores',
value: true,
description: 'Specify how many cores are used (by default all available cores are used)',
metavar: 'n'
},
{
full: 'nosymlinks',
value: false,
description: 'Do not follow symbolic links when searching for files'
},
{
full: 'outputintermediatespirv',
value: false,
description: 'Write the intermediate spirv generated by glslang to a file - useful for debugging shader-problems'
},
{
full: 'cc',
value: true,
description: 'Custom path to C compiler (Currently only available on Linux)',
metavar: 'file',
default: ''
},
{
full: 'cxx',
value: true,
description: 'Custom path to CPP compiler (Currently only available on Linux)',
metavar: 'file',
default: ''
},
{
full: 'ar',
value: true,
description: 'Custom path to ar (Currently only available on Linux)',
metavar: 'file',
default: ''
},
{
full: 'strip',
value: true,
description: 'Custom path to strip',
metavar: 'file',
default: ''
},
{
full: 'meson',
value: false,
description: 'Export a meson build file'
},
{
// this is parsed and removed in src/node_main.cc
full: 'dev',
value: true,
description: 'Use the JavaScript from the kmake repo that path points to',
metavar: 'path',
default: ''
},
{
full: 'open',
value: false,
description: 'Open the created project in its default application (usually your IDE)'
},
{
full: 'option',
value: true,
description: 'Pass multiple options to the kfile',
metavar: 'k,k=v',
default: {}
}
];
let parsedOptions = {
};
function printHelp() {
console.log('kmake options:');
for (let o in options) {
let option = options[o];
if (option.hidden) continue;
var begin = option.short ? `-${option.short},` : ' ';
begin += ` --${option.full}`;
if (option.value) begin += ` <${option.metavar ?? 'name'}>`;
var end = option.default ? ` (default: ${option.default})` : '';
console.log(` ${begin.padEnd(26)} ${option.description}${end}`);
}
}
for (let o in options) {
let option = options[o];
if (option.value) {
parsedOptions[option.full] = option.default;
}
else {
parsedOptions[option.full] = false;
}
}
let args = process.argv;
for (let i = 1; i < args.length; ++i) {
let arg = args[i];
if (arg[0] === '-') {
if (arg[1] === '-') {
if (arg.substr(2) === 'help') {
printHelp();
process.exit();
}
let found = false;
for (let o in options) {
let option = options[o];
if (arg.substr(2) === option.full) {
found = true;
if (option.value) {
++i;
if (option.full == 'option') {
let optionKey = args[i];
let optionValue = option.value;
let optionKeyEqualIndex = optionKey.indexOf("=");
if (optionKeyEqualIndex != -1) {
optionValue = optionKey.substring(optionKeyEqualIndex+1, optionKey.length);
optionKey = optionKey.substring(0, optionKeyEqualIndex);
}
parsedOptions[option.full][optionKey] = optionValue;
}
else {
parsedOptions[option.full] = args[i];
}
}
else {
parsedOptions[option.full] = true;
}
}
}
if (!found) throw 'Option ' + arg + ' not found.';
}
else {
if (arg[1] === 'h') {
printHelp();
process.exit();
}
if (arg.length !== 2) throw 'Wrong syntax for option ' + arg + ' (maybe try -' + arg + ' instead).';
let found = false;
for (let o in options) {
let option = options[o];
if (option.short && arg[1] === option.short) {
found = true;
if (option.value) {
++i;
if (option.full == 'option') {
let optionKey = args[i];
let optionValue = option.value;
let optionKeyEqualIndex = optionKey.indexOf("=");
if (optionKeyEqualIndex != -1) {
optionValue = optionKey.substring(optionKeyEqualIndex+1, optionKey.length);
optionKey = optionKey.substring(0, optionKeyEqualIndex);
}
parsedOptions[option.full][optionKey] = optionValue;
}
else {
parsedOptions[option.full] = args[i];
}
}
else {
parsedOptions[option.full] = true;
}
}
}
if (!found) throw 'Option ' + arg + ' not found.';
}
}
else {
parsedOptions.target = arg.toLowerCase();
}
}
if (parsedOptions.run) {
parsedOptions.compile = true;
}
const logInfo = (text, newline) => {
if (newline) {
console.log(text);
}
else {
process.stdout.write(text);
}
};
const logError = (text, newline) => {
if (newline) {
console.error(text);
}
else {
process.stderr.write(text);
}
};
function runKmake() {
global.__dirname = require('path').dirname(process.execPath);
const promise = require('kmake/main').run(parsedOptions, { info: logInfo, error: logError });
promise
.then(() => {
console.log('Done.');
process.exit();
})
.catch(err => {
console.log('Error: ' + err);
process.exit(1);
});
}
function runServer() {
global.__dirname = require('path').dirname(process.execPath);
const promise = require('kmake/server').run(parsedOptions, { info: logInfo, error: logError });
promise
.then(() => {
})
.catch(err => {
console.log('Error: ' + err);
process.exit(1);
});
}
if (parsedOptions.init) {
console.log('Initializing Kore project.\n');
require('kmake/init').run(parsedOptions.name, parsedOptions.from, parsedOptions.projectfile);
process.exit();
}
else if (parsedOptions.server) {
runServer();
}
else if (parsedOptions.update) {
console.log('Updating everything...');
require('child_process').spawnSync('git', ['pull', 'origin', 'master'], { stdio: 'inherit', stderr: 'inherit' });
require('child_process').spawnSync('git', ['submodule', 'update', '--init', '--recursive'], { stdio: 'inherit', stderr: 'inherit' });
}
else {
runKmake();
}