132 lines
3.9 KiB
JavaScript
Raw Normal View History

2024-02-03 21:07:53 -05:00
#!/usr/bin/env node
import * as path from 'node:path';
import * as fs from 'node:fs';
2025-01-03 10:20:33 -05:00
import { info, err, run, createDir, getScriptsDir } from './lib/util.mjs';
2025-01-03 08:25:09 -05:00
import { parseOptions, Enum, Architectures } from './lib/options.mjs';
2024-02-03 21:07:53 -05:00
2025-01-03 08:25:09 -05:00
// CMake Options
const cmakeArgPrefix = '-D';
const cmakeArgSeparator = '=';
const cmakeOptions = new Map();
function parseCMakeOption(arg) {
if (arg === null) {
// Usage Text
return `${cmakeArgPrefix}var${cmakeArgSeparator}value...`;
} else if (arg.startsWith(cmakeArgPrefix)) {
2024-02-03 21:07:53 -05:00
// Pass Build Option To CMake
2024-12-22 03:34:31 -05:00
let parsedArg = arg.substring(cmakeArgPrefix.length);
2025-01-03 08:25:09 -05:00
const parts = parsedArg.split(cmakeArgSeparator);
2024-12-22 03:34:31 -05:00
if (parts.length !== 2) {
2024-02-03 21:07:53 -05:00
err('Unable To Parse Build Option: ' + arg);
}
2024-12-22 03:34:31 -05:00
const name = parts[0];
const value = parts[1];
2024-02-03 21:07:53 -05:00
if (!/^[a-zA-Z_]+$/.test(name) || name.length === 0) {
err('Invalid Build Option Name: ' + name);
}
2025-01-03 08:25:09 -05:00
cmakeOptions.set(name, value);
return true;
2024-02-03 21:07:53 -05:00
} else {
2025-01-03 08:25:09 -05:00
// Unknown Option
return false;
2024-02-03 21:07:53 -05:00
}
}
2025-01-03 08:25:09 -05:00
// Options
2025-01-03 10:20:33 -05:00
const PackageTypes = new Enum([
'None',
'AppImage',
'Flatpak'
]);
2025-01-03 08:25:09 -05:00
const options = parseOptions([
['packageType', PackageTypes],
['architecture', Architectures]
], [
'clean',
'install',
'debug'
], parseCMakeOption);
// Check Options
if (options.packageType === PackageTypes.Flatpak && options.architecture !== Architectures.Host) {
err('Flatpak Builds Do Not Support Custom Toolchains');
2024-02-03 21:07:53 -05:00
}
2025-01-03 08:25:09 -05:00
if (options.packageType === PackageTypes.AppImage && options.install) {
err('AppImages Cannot Be Installed');
2024-02-04 00:36:58 -05:00
}
2024-02-03 21:07:53 -05:00
2025-01-03 08:25:09 -05:00
// Folders
2025-01-03 10:20:33 -05:00
const __dirname = getScriptsDir();
2025-01-03 08:25:09 -05:00
const root = path.join(__dirname, '..');
let build = path.join(root, 'build');
let out = path.join(root, 'out');
// Update Build Directory
function specializeDir(dir) {
// Use Unique Folder For Build Type
return path.join(dir, options.packageType.name, options.architecture.name);
}
build = specializeDir(build);
// Update Output Directory
const useOutRoot = options.packageType === PackageTypes.AppImage;
if (!useOutRoot) {
out = specializeDir(out);
}
// Print Directories
function printDir(name, dir) {
info(name + ' Directory: ' + dir);
}
printDir('Build', build);
printDir('Output', out);
// Configure CMake Options
function setupPackageTypeOption(type) {
cmakeOptions.set(`MCPI_IS_${type.name.toUpperCase()}_BUILD`, options.packageType === type ? 'ON' : 'OFF');
}
setupPackageTypeOption(PackageTypes.AppImage);
setupPackageTypeOption(PackageTypes.Flatpak);
const toolchainOption = 'CMAKE_TOOLCHAIN_FILE';
if (options.architecture !== Architectures.Host) {
cmakeOptions.set(toolchainOption, path.join(root, 'cmake', 'toolchain', options.architecture.name + '-toolchain.cmake'));
2024-02-03 21:07:53 -05:00
} else {
2025-01-03 08:25:09 -05:00
cmakeOptions.delete(toolchainOption);
2024-02-03 21:07:53 -05:00
}
// Make Build Directory
2025-01-03 08:25:09 -05:00
createDir(build, options.clean);
if (!options.install) {
createDir(out, !useOutRoot);
2024-02-03 21:07:53 -05:00
}
// Run CMake
2024-12-22 03:34:31 -05:00
const configure = ['cmake', '-GNinja Multi-Config'];
2025-01-03 08:25:09 -05:00
cmakeOptions.forEach((value, key) => {
configure.push(cmakeArgPrefix + key + cmakeArgSeparator + value);
2024-02-04 01:31:41 -05:00
});
2025-01-03 08:25:09 -05:00
configure.push('-S', root, '-B', build);
2024-12-22 03:34:31 -05:00
run(configure);
2024-02-03 21:07:53 -05:00
// Build
2025-01-03 08:25:09 -05:00
const configArg = ['--config', options.debug ? 'Debug' : 'Release'];
run(['cmake', '--build', build, ...configArg]);
2024-02-03 21:07:53 -05:00
// Package
2025-01-03 08:25:09 -05:00
if (options.packageType !== PackageTypes.AppImage) {
if (!options.install) {
2024-02-03 21:07:53 -05:00
process.env.DESTDIR = out;
}
2025-01-03 08:25:09 -05:00
run(['cmake', '--install', build, ...configArg]);
2024-02-03 21:07:53 -05:00
} else {
2025-01-03 08:25:09 -05:00
run(['cmake', '--build', build, '--target', 'package', ...configArg]);
2024-02-04 00:36:58 -05:00
// Copy Generated Files
const files = fs.readdirSync(build);
for (const file of files) {
if (file.includes('.AppImage')) {
info('Copying: ' + file);
const src = path.join(build, file);
const dst = path.join(out, file);
fs.copyFileSync(src, dst);
}
}
2024-02-03 21:07:53 -05:00
}