forked from LeenkxTeam/LNXSDK
292 lines
12 KiB
JavaScript
292 lines
12 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Project = exports.Target = exports.Library = void 0;
|
|
const child_process = require("child_process");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const log = require("./log");
|
|
const ProjectFile_1 = require("./ProjectFile");
|
|
class Library {
|
|
}
|
|
exports.Library = Library;
|
|
class Target {
|
|
constructor(baseTarget, backends) {
|
|
this.baseTarget = baseTarget;
|
|
this.backends = backends;
|
|
}
|
|
}
|
|
exports.Target = Target;
|
|
function contains(main, sub) {
|
|
main = path.resolve(main);
|
|
sub = path.resolve(sub);
|
|
if (process.platform === 'win32') {
|
|
main = main.toLowerCase();
|
|
sub = sub.toLowerCase();
|
|
}
|
|
return sub.indexOf(main) === 0 && sub.slice(main.length)[0] === path.sep;
|
|
}
|
|
class Project {
|
|
constructor(name) {
|
|
this.icon = null;
|
|
this.name = name;
|
|
this.safeName = name.replace(/[^A-z0-9\-\_]/g, '-');
|
|
this.version = '1.0';
|
|
this.sources = [];
|
|
this.defines = ['hxcpp_smart_strings'];
|
|
this.cdefines = [];
|
|
this.cflags = [];
|
|
this.cppflags = [];
|
|
this.parameters = [];
|
|
this.scriptdir = Project.scriptdir;
|
|
this.libraries = [];
|
|
this.localLibraryPath = 'Libraries';
|
|
this.assetMatchers = [];
|
|
this.shaderMatchers = [];
|
|
this.customTargets = new Map();
|
|
this.stackSize = 0;
|
|
this.windowOptions = {};
|
|
this.targetOptions = {
|
|
html5: {},
|
|
flash: {},
|
|
android: {},
|
|
android_native: {},
|
|
ios: {},
|
|
xboxOne: {},
|
|
playStation4: {},
|
|
switch: {},
|
|
xboxSeriesXS: {},
|
|
playStation5: {},
|
|
stadia: {}
|
|
};
|
|
}
|
|
getSafeName() {
|
|
return this.safeName;
|
|
}
|
|
async addProject(projectDir) {
|
|
if (!path.isAbsolute(projectDir)) {
|
|
projectDir = path.join(this.scriptdir, projectDir);
|
|
}
|
|
if (!fs.existsSync(path.join(projectDir, 'khafile.js')) && (fs.existsSync(path.join(projectDir, 'kincfile.js')) || fs.existsSync(path.join(projectDir, 'korefile.js')) || fs.existsSync(path.join(projectDir, 'kfile.js')))) {
|
|
this.libraries.push({
|
|
libpath: projectDir,
|
|
libroot: projectDir
|
|
});
|
|
}
|
|
else {
|
|
let project = await (0, ProjectFile_1.loadProject)(projectDir, 'khafile.js', Project.platform);
|
|
this.assetMatchers = this.assetMatchers.concat(project.assetMatchers);
|
|
this.sources = this.sources.concat(project.sources);
|
|
this.shaderMatchers = this.shaderMatchers.concat(project.shaderMatchers);
|
|
this.defines = this.defines.concat(project.defines);
|
|
this.cdefines = this.cdefines.concat(project.cdefines);
|
|
this.cflags = this.cflags.concat(project.cflags);
|
|
this.cppflags = this.cppflags.concat(project.cppflags);
|
|
this.parameters = this.parameters.concat(project.parameters);
|
|
this.libraries = this.libraries.concat(project.libraries);
|
|
if (this.icon === null && project.icon !== null)
|
|
this.icon = path.join(projectDir, project.icon);
|
|
for (let customTarget of project.customTargets.keys()) {
|
|
this.customTargets.set(customTarget, project.customTargets.get(customTarget));
|
|
}
|
|
// windowOptions and targetOptions are ignored
|
|
}
|
|
}
|
|
unglob(str) {
|
|
const globChars = ['\\@', '\\!', '\\+', '\\*', '\\?', '\\(', '\\[', '\\{', '\\)', '\\]', '\\}'];
|
|
str = str.replace(/\\/g, '/');
|
|
for (const char of globChars) {
|
|
str = str.replace(new RegExp(char, 'g'), char);
|
|
}
|
|
return str;
|
|
}
|
|
getBaseDir(str) {
|
|
// replace \\ to / if next char is not glob
|
|
str = str.replace(/\\([^@!+*?{}()[\]]|$)/g, '/$1');
|
|
// find non-globby path part
|
|
const globby = /[^\\][@!+*?{}()[\]]/;
|
|
while (globby.test(str)) {
|
|
str = path.posix.dirname(str);
|
|
}
|
|
str = this.removeGlobEscaping(str);
|
|
if (!str.endsWith('/'))
|
|
str += '/';
|
|
return str;
|
|
}
|
|
removeGlobEscaping(str) {
|
|
return str.replace(/\\([@!+*?{}()[\]]|$)/g, '$1');
|
|
}
|
|
/**
|
|
* Add all assets matching the match glob relative to the directory containing the current khafile.
|
|
* Asset types are infered from the file suffix.
|
|
* Glob syntax is very simple, the most important patterns are * for anything and ** for anything across directories.
|
|
*/
|
|
addAssets(match, options) {
|
|
if (!options)
|
|
options = {};
|
|
if (!path.isAbsolute(match)) {
|
|
let base = this.unglob(path.resolve(this.scriptdir));
|
|
if (!base.endsWith('/'))
|
|
base += '/';
|
|
// if there is no nameBaseDir: extract relative assets path from match
|
|
const baseName = options.nameBaseDir == null ? this.getBaseDir(match) : options.nameBaseDir;
|
|
match = path.posix.join(base, match.replace(/\\/g, '/'));
|
|
options.baseDir = path.posix.join(this.removeGlobEscaping(base), baseName);
|
|
}
|
|
else {
|
|
options.baseDir = this.getBaseDir(match);
|
|
}
|
|
this.assetMatchers.push({ match: match, options: options });
|
|
}
|
|
addSources(source) {
|
|
this.sources.push(path.resolve(path.join(this.scriptdir, source)));
|
|
}
|
|
/**
|
|
* Add all shaders matching the match glob relative to the directory containing the current khafile.
|
|
* Glob syntax is very simple, the most important patterns are * for anything and ** for anything across directories.
|
|
*/
|
|
addShaders(match, options) {
|
|
if (!options)
|
|
options = {};
|
|
if (!path.isAbsolute(match)) {
|
|
let base = this.unglob(path.resolve(this.scriptdir));
|
|
if (!base.endsWith('/')) {
|
|
base += '/';
|
|
}
|
|
match = base + match.replace(/\\/g, '/');
|
|
}
|
|
this.shaderMatchers.push({ match: match, options: options });
|
|
}
|
|
addDefine(define) {
|
|
this.defines.push(define);
|
|
}
|
|
addCDefine(define) {
|
|
this.cdefines.push(define);
|
|
}
|
|
addCFlag(flag) {
|
|
this.cflags.push(flag);
|
|
}
|
|
addCppFlag(flag) {
|
|
this.cppflags.push(flag);
|
|
}
|
|
addParameter(parameter) {
|
|
this.parameters.push(parameter);
|
|
}
|
|
addTarget(name, baseTarget, backends) {
|
|
this.customTargets.set(name, new Target(baseTarget, backends));
|
|
}
|
|
addLibrary(library) {
|
|
this.addDefine(library);
|
|
let self = this;
|
|
function findLibraryDirectory(name) {
|
|
if (path.isAbsolute(name)) {
|
|
return { libpath: name, libroot: name };
|
|
}
|
|
// Tries to load the default library from inside the kha project.
|
|
// e.g. 'Libraries/wyngine'
|
|
let libpath = path.join(self.scriptdir, self.localLibraryPath, name);
|
|
if (fs.existsSync(libpath) && fs.statSync(libpath).isDirectory()) {
|
|
let dir = path.resolve(libpath);
|
|
return { libpath: dir, libroot: dir };
|
|
}
|
|
// If the library couldn't be found in Libraries folder, try
|
|
// looking in the haxelib folders.
|
|
// e.g. addLibrary('hxcpp') => '/usr/lib/haxelib/hxcpp/3,2,193'
|
|
try {
|
|
libpath = path.join(child_process.execSync('haxelib config', { encoding: 'utf8' }).trim(), name.replace(/\./g, ','));
|
|
}
|
|
catch (error) {
|
|
if (process.env.HAXEPATH) {
|
|
libpath = path.join(process.env.HAXEPATH, 'lib', name.toLowerCase());
|
|
}
|
|
}
|
|
if (fs.existsSync(libpath) && fs.statSync(libpath).isDirectory()) {
|
|
if (fs.existsSync(path.join(libpath, '.dev'))) {
|
|
libpath = fs.readFileSync(path.join(libpath, '.dev'), 'utf8');
|
|
if (!path.isAbsolute(libpath)) {
|
|
libpath = path.resolve(libpath);
|
|
}
|
|
return { libpath: libpath, libroot: libpath };
|
|
}
|
|
else if (fs.existsSync(path.join(libpath, '.current'))) {
|
|
// Get the latest version of the haxelib path,
|
|
// e.g. for 'hxcpp', latest version '3,2,193'
|
|
let current = fs.readFileSync(path.join(libpath, '.current'), 'utf8');
|
|
return { libpath: path.join(libpath, current.replace(/\./g, ',')), libroot: libpath };
|
|
}
|
|
}
|
|
// check relative path
|
|
if (fs.existsSync(path.resolve(name))) {
|
|
let libpath = path.resolve(name);
|
|
return { libpath: libpath, libroot: libpath };
|
|
}
|
|
// Show error if library isn't found in Libraries or haxelib folder
|
|
log.error('Error: Library ' + name + ' not found.');
|
|
log.error('Add it to the \'Libraries\' subdirectory of your project. You may also install it via haxelib but that\'s less cool.');
|
|
throw 'Library ' + name + ' not found.';
|
|
}
|
|
let libInfo = findLibraryDirectory(library);
|
|
let dir = libInfo.libpath;
|
|
if (dir !== '') {
|
|
for (let elem of this.libraries) {
|
|
if (elem.libroot === libInfo.libroot)
|
|
return '';
|
|
}
|
|
this.libraries.push({
|
|
libpath: dir,
|
|
libroot: libInfo.libroot
|
|
});
|
|
// If this is a haxelib library, there must be a haxelib.json
|
|
if (fs.existsSync(path.join(dir, 'haxelib.json'))) {
|
|
let options = JSON.parse(fs.readFileSync(path.join(dir, 'haxelib.json'), 'utf8'));
|
|
// If there is a classPath value, add that directory to be loaded.
|
|
// Otherwise, just load the current path.
|
|
if (options.classPath) {
|
|
// TODO find an example haxelib that has a classPath value
|
|
this.sources.push(path.join(dir, options.classPath));
|
|
}
|
|
else {
|
|
// e.g. '/usr/lib/haxelib/hxcpp/3,2,193'
|
|
this.sources.push(dir);
|
|
}
|
|
// If this haxelib has other library dependencies, add them too
|
|
if (options.dependencies) {
|
|
for (let dependency in options.dependencies) {
|
|
if (dependency.toLowerCase() !== 'kha') {
|
|
this.addLibrary(dependency);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// If there is no haxelib.json file, then just load the library
|
|
// by the Sources folder.
|
|
// e.g. Libraries/wyngine/Sources
|
|
if (!fs.existsSync(path.join(dir, 'Sources'))) {
|
|
log.info('Warning: No haxelib.json and no Sources directory found in library ' + library + '.');
|
|
}
|
|
this.sources.push(path.join(dir, 'Sources'));
|
|
}
|
|
if (fs.existsSync(path.join(dir, 'extraParams.hxml'))) {
|
|
let params = fs.readFileSync(path.join(dir, 'extraParams.hxml'), 'utf8');
|
|
for (let parameter of params.split('\n')) {
|
|
let param = parameter.trim();
|
|
if (param !== '') {
|
|
if (param.startsWith('-lib')) {
|
|
// (DK)
|
|
// - '-lib xxx' is for linking a library via haxe, it forces the use of the haxelib version
|
|
// - this should be handled by khamake though, as it tracks the dependencies better (local folder or haxelib)
|
|
log.info('Ignoring ' + dir + '/extraParams.hxml "' + param + '"');
|
|
}
|
|
else {
|
|
this.addParameter(param);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.addShaders(dir + '/Sources/Shaders/**', {});
|
|
}
|
|
return dir;
|
|
}
|
|
}
|
|
exports.Project = Project;
|
|
//# sourceMappingURL=Project.js.map
|