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
 |