Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
343 changes: 343 additions & 0 deletions kmake/src/Exporters/MesonExporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
import { Project } from 'kmake/Project';
import { Platform } from 'kmake/Platform';
import * as path from 'path';
import { Exporter } from 'kmake/Exporters/Exporter';

export class MesonExporter extends Exporter {
constructor(options: any) {
super(options);
}

async exportSolution(project: Project, from: string, to: string, platform: string, vrApi: any, options: any): Promise<void> {
let name = project.getSafeName();

this.writeFile(path.resolve(to, 'meson.build'));

let includeDirs = [...project.getIncludeDirs()];

let systemOs = '';
if (platform === Platform.Windows || platform === Platform.WindowsApp) {
systemOs = 'windows';
} else if (platform === Platform.OSX) {
systemOs = 'macos';
} else if (platform === Platform.iOS) {
systemOs = 'ios';
} else if (platform === Platform.tvOS) {
systemOs = 'tvos';
} else if (platform === Platform.Linux) {
systemOs = 'linux';
} else if (platform === Platform.Android) {
systemOs = 'android';
}

if (includeDirs.length > 0) {
this.p('kore_inc_dirs = include_directories(');
for (let i = 0; i < includeDirs.length; i++) {
const inc = this.nicePath(from, to, includeDirs[i]);
const comma = i === includeDirs.length - 1 ? '' : ',';
this.p(' \'' + inc.replace(/\\/g, '/') + '\'' + comma, 1);
}
this.p(')');
this.p();
}

let defineArgs: string[] = [];
if (project.getDefines().length > 0) {
for (const def of project.getDefines()) {
if (def.config && def.config.toLowerCase() === 'debug' && !options.debug) {
continue;
}
if (def.config && def.config.toLowerCase() === 'release' && options.debug) {
continue;
}
defineArgs.push('-D' + def.value);
}
}
if (!options.debug) {
defineArgs.push('-DNDEBUG');
}

if (project.cFlags.length > 0 || defineArgs.length > 0) {
this.p('kore_c_args = [');

for (const flag of project.cFlags) {
this.p(' \'' + flag + '\',', 1);
}

for (const def of defineArgs) {
this.p(' \'' + def + '\',', 1);
}

this.p(']');
this.p();
}

if (project.cppFlags.length > 0 || defineArgs.length > 0) {
this.p('kore_cpp_args = [');
for (const flag of project.cppFlags) {
this.p(' \'' + flag + '\',', 1);
}
for (const def of defineArgs) {
this.p(' \'' + def + '\',', 1);
}
this.p(']');
this.p();
}

let sourceFiles = project.getFiles().filter(file => {
if (file.options && file.options.nocompile) {
return false;
}

for (let exclude of project.excludes) {
if (project.matches(file.file, exclude)) {
console.log(`Excluding file ${file.file} due to exclude pattern: ${exclude}`);
return false;
}
}

const ext = path.extname(file.file).toLowerCase();
let validExtensions = ['.c', '.cpp', '.cc', '.cxx'];
if (platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) {
validExtensions.push('.m', '.mm');
}
return validExtensions.includes(ext);
});

let metalFiles = project.getFiles().filter(file => {
if (file.options && file.options.nocompile) {
return false;
}
const ext = path.extname(file.file).toLowerCase();
return ext === '.metal';
});

let headerFiles = project.getFiles().filter(file => {
const ext = path.extname(file.file).toLowerCase();
return ['.h', '.hpp', '.hxx'].includes(ext);
});

if (sourceFiles.length > 0) {
this.p('sources = [');

for (const fileObj of sourceFiles) {
const relativePath = this.nicePath(from, to, fileObj.file);
this.p(' \'' + relativePath.replace(/\\/g, '/') + '\',', 1);
}

this.p(']');
this.p();
}

let allFiles = [];
if (sourceFiles.length > 0) {
allFiles.push('sources');
}

if (allFiles.length > 0) {
this.p('target_files = ' + allFiles.join(' + '));
this.p();
}

if (platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) {
this.p('add_languages(\'objc\', native: false)');
this.p();

if (defineArgs.length > 0) {
this.p('kore_objc_args = [');
this.p(' \'-fobjc-arc\',', 1);
this.p(']');
this.p();
}
}

if (project.getLibs().length > 0) {
this.p('dependencies = [');
for (const lib of project.getLibs()) {
this.p(' dependency(\'' + lib + '\'),', 1);
}
this.p(']');
this.p();
}

if (project.subProjects.length > 0) {
this.p('subproject_targets = [');
for (const subproject of project.subProjects) {
this.p(' \'' + subproject + '\',', 1);
}
this.p(']');
this.p();
}

if ((platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) && metalFiles.length > 0) {
this.p('metal_compiler = find_program(\'xcrun\')');
this.p();

for (let i = 0; i < metalFiles.length; i++) {
const metalFile = metalFiles[i];
const relativePath = this.nicePath(from, to, metalFile.file);
const baseName = path.basename(metalFile.file, '.metal');

this.p(baseName + '_air = custom_target(\'' + baseName + '_air\',');
this.p(' output: \'' + baseName + '.air\',', 1);
this.p(' input: \'' + relativePath.replace(/\\/g, '/') + '\',', 1);
this.p(' command: [metal_compiler, \'-sdk\', \'macosx\', \'metal\', \'-c\', \'@INPUT@\', \'-o\', \'@OUTPUT@\'],', 1);
this.p(' build_by_default: true', 1);
this.p(')');
this.p();

this.p(baseName + '_metallib = custom_target(\'' + baseName + '_metallib\',');
this.p(' output: \'' + baseName + '.metallib\',', 1);
this.p(' input: ' + baseName + '_air,', 1);
this.p(' command: [metal_compiler, \'-sdk\', \'macosx\', \'metallib\', \'@INPUT@\', \'-o\', \'@OUTPUT@\'],', 1);
this.p(' build_by_default: true', 1);
this.p(')');
this.p();
}
}

let executableName = project.getSafeName();
if (project.getExecutableName()) {
executableName = project.getExecutableName();
}

let targetArgs = [];
if (allFiles.length > 0) {
targetArgs.push('target_files');
}

if (includeDirs.length > 0) {
targetArgs.push('include_directories : kore_inc_dirs');
}

if (project.cFlags.length > 0 || defineArgs.length > 0) {
targetArgs.push('c_args : kore_c_args');
}
if (project.cppFlags.length > 0 || defineArgs.length > 0) {
targetArgs.push('cpp_args : kore_cpp_args');
}
if ((platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) && defineArgs.length > 0) {
targetArgs.push('objc_args : [kore_objc_args] + kore_c_args');
}

if (project.getLibs().length > 0) {
targetArgs.push('dependencies : dependencies');
}

if (project.subProjects.length > 0) {
targetArgs.push('link_with : subproject_targets');
}

targetArgs.push('install : false');

if (project.linkerFlags.length > 0) {
this.p('link_args = [');
for (const flag of project.linkerFlags) {
this.p(' \'' + flag + '\',', 1);
}
this.p(']');
this.p();
targetArgs.push('link_args : kore_link_args');
}

if (options.lib) {
this.p(executableName + ' = library(\'' + executableName + '\',');
} else if (options.dynlib) {
this.p(executableName + ' = shared_library(\'' + executableName + '\',');
} else {
this.p('executable(\'' + executableName + '\',');
}

for (let i = 0; i < targetArgs.length; i++) {
const comma = i === targetArgs.length - 1 ? '' : ',';
this.p(' ' + targetArgs[i] + comma, 1);
}
this.p(')');

this.closeFile();
}

private mapCStandard(std: string): string {
switch (std) {
case 'c90':
case 'c89':
case 'iso9899:1990':
return 'c89';
case 'gnu90':
case 'gnu89':
return 'gnu89';
case 'c99':
case 'c9x':
case 'iso9899:1999':
return 'c99';
case 'gnu99':
case 'gnu9x':
return 'gnu99';
case 'c11':
case 'c1x':
case 'iso9899:2011':
return 'c11';
case 'gnu11':
case 'gnu1x':
return 'gnu11';
case 'c17':
case 'c18':
case 'iso9899:2017':
case 'iso9899:2018':
return 'c17';
case 'gnu17':
case 'gnu18':
return 'gnu17';
case 'c2x':
case 'c23':
return 'c2x';
case 'gnu2x':
case 'gnu23':
return 'gnu2x';
default:
return 'c99';
}
}

private mapCppStandard(std: string): string {
switch (std) {
case 'c++03':
case 'c++98':
case 'gnu++03':
case 'gnu++98':
return 'c++03';
case 'c++11':
case 'c++0x':
case 'gnu++11':
case 'gnu++0x':
return 'c++11';
case 'c++14':
case 'c++1y':
case 'gnu++14':
case 'gnu++1y':
return 'c++14';
case 'c++17':
case 'c++1z':
case 'gnu++17':
case 'gnu++1z':
return 'c++17';
case 'c++20':
case 'c++2a':
case 'gnu++20':
case 'gnu++2a':
return 'c++20';
case 'c++23':
case 'c++2b':
case 'gnu++23':
case 'gnu++2b':
return 'c++23';
case 'c++26':
case 'c++2c':
case 'gnu++26':
case 'gnu++2c':
return 'c++26';
default:
return 'c++17';
}
}
}
2 changes: 1 addition & 1 deletion kmake/src/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ export class Project {
sha.update(json ? 'true' : 'false');
sha.update(debug ? 'true' : 'false');
sha.update(platform);

return sha.digest('hex');
}

Expand Down
8 changes: 6 additions & 2 deletions kmake/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { XCodeExporter } from 'kmake/Exporters/XCodeExporter';
import { VSCodeExporter } from 'kmake/Exporters/VSCodeExporter';
import { FreeBSDExporter } from 'kmake/Exporters/FreeBSDExporter';
import { JsonExporter } from 'kmake/Exporters/JsonExporter';
import { MesonExporter } from 'kmake/Exporters/MesonExporter';
import { Compiler } from 'kmake/Compiler';
import { Architecture } from 'kmake/Architecture';

Expand Down Expand Up @@ -415,7 +416,7 @@ function compileKong(project: Project, from: string, to: string, platform: strin

if (compilerPath !== '') {
let api = graphicsApi(platform);

to = path.join(to, 'Kong-' + platform + '-' + api);
fs.ensureDirSync(to);

Expand Down Expand Up @@ -623,6 +624,9 @@ async function exportKoremakeProject(from: string, to: string, platform: string,
else if (options.json) {
exporter = new JsonExporter(options);
}
else if (options.meson) {
exporter = new MesonExporter(options);
}
else if (platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) exporter = new XCodeExporter(options);
else if (platform === Platform.Android) exporter = new AndroidExporter(options);
else if (platform === Platform.Emscripten) exporter = new EmscriptenExporter(project, options);
Expand Down Expand Up @@ -682,7 +686,7 @@ async function exportKoremakeProject(from: string, to: string, platform: string,
log.error('Could not write korepath file');
}
}

const hash = project.createHash(options.vscode, options.json, options.debug, platform);
let oldHash = null;
try {
Expand Down
Loading