MacOS Exporter

This commit is contained in:
Gorochu
2026-05-26 23:58:46 -07:00
parent 555ec72358
commit a62696783c
5 changed files with 138 additions and 5 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,83 @@
import { Exporter } from 'kmake/Exporters/Exporter';
import { Options } from 'kmake/Options';
import { Platform } from 'kmake/Platform';
import { Project } from 'kmake/Project';
import { Compiler } from 'kmake/Compiler';
import * as fs from 'kmake/fsextra';
import * as path from 'path';
import { NinjaExporter } from 'kmake/Exporters/NinjaExporter';
import { MakeExporter } from 'kmake/Exporters/MakeExporter';
import { CLionExporter } from 'kmake/Exporters/CLionExporter';
import { CompilerCommandsExporter } from 'kmake/Exporters/CompileCommandsExporter';
export class MacOSExporter extends Exporter {
ninja: NinjaExporter;
make: MakeExporter;
clion: CLionExporter;
compileCommands: CompilerCommandsExporter;
constructor(options: any) {
super(options);
let linkerFlags = '-pthread';
if (options.lib) {
linkerFlags += ' -static';
}
let outputExtension = '';
if (options.lib) {
outputExtension = '.a';
}
else if (options.dynlib) {
outputExtension = '.dylib';
}
this.ninja = new NinjaExporter(options, this.getCCompiler(), this.getCPPCompiler(), '', '', linkerFlags, outputExtension);
this.make = new MakeExporter(options, this.getCCompiler(), this.getCPPCompiler(), '', '', linkerFlags, outputExtension);
this.clion = new CLionExporter(options);
this.compileCommands = new CompilerCommandsExporter(options);
}
async exportSolution(project: Project, from: string, to: string, platform: string, vrApi: any, options: any) {
// Debug: log .m files before export
console.log('MacOSExporter: Total files:', project.getFiles().length);
for (let fileobject of project.getFiles()) {
if (fileobject.file.endsWith('.m') || fileobject.file.endsWith('.mm')) {
console.log('MacOSExporter: Found .m file:', fileobject.file);
}
}
this.ninja.exportSolution(project, from, to, platform, vrApi, options);
this.make.exportSolution(project, from, to, platform, vrApi, options);
this.clion.exportSolution(project, from, to, platform, vrApi, options);
this.compileCommands.exportSolution(project, from, to, platform, vrApi, options);
}
getCCompiler(): string {
switch (Options.compiler) {
case Compiler.Default:
case Compiler.Clang:
return 'clang';
case Compiler.GCC:
return 'gcc';
case Compiler.Custom:
return Options.ccPath;
default:
throw 'Unsupported compiler ' + Options.compiler;
}
}
getCPPCompiler(): string {
switch (Options.compiler) {
case Compiler.Default:
case Compiler.Clang:
return 'clang++';
case Compiler.GCC:
return 'g++';
case Compiler.Custom:
return Options.cxxPath;
default:
throw 'Unsupported compiler ' + Options.compiler;
}
}
}

View File

@ -33,6 +33,27 @@ export class MakeExporter extends Exporter {
} }
async exportSolution(project: Project, from: string, to: string, platform: string, vrApi: any, options: any) { async exportSolution(project: Project, from: string, to: string, platform: string, vrApi: any, options: any) {
let mFiles = [
path.join(from, 'Kinc/Backends/System/Apple/Sources/kinc/backend/appleunit.m'),
path.join(from, 'Kinc/Backends/System/macOS/Sources/kinc/backend/macosunit.m'),
path.join(from, 'Kinc/Backends/System/macOS/Sources/kinc/backend/system.m.h'),
path.join(from, 'Kinc/Backends/System/macOS/Sources/kinc/backend/BasicOpenGLView.m.h'),
path.join(from, 'Kinc/Backends/System/macOS/Sources/kinc/backend/display.m.h'),
path.join(from, 'Kinc/Backends/System/macOS/Sources/kinc/backend/mouse.m.h')
];
for (let mFile of mFiles) {
let found = false;
for (let fileobject of project.getFiles()) {
if (fileobject.file === mFile) {
found = true;
break;
}
}
if (!found) {
project.files.push({file: mFile, options: null, projectDir: from, projectName: project.name});
}
}
let objects: any = {}; let objects: any = {};
let ofiles: any = {}; let ofiles: any = {};
let outputPath = path.resolve(to, options.buildPath); let outputPath = path.resolve(to, options.buildPath);
@ -40,7 +61,7 @@ export class MakeExporter extends Exporter {
for (let fileobject of project.getFiles()) { for (let fileobject of project.getFiles()) {
let file = fileobject.file; let file = fileobject.file;
if (file.endsWith('.cpp') || file.endsWith('.c') || file.endsWith('.cc') || file.endsWith('.s') || file.endsWith('.S')) { if (file.endsWith('.cpp') || file.endsWith('.c') || file.endsWith('.cc') || file.endsWith('.s') || file.endsWith('.S') || file.endsWith('.m') || file.endsWith('.mm') || file.endsWith('.m.h')) {
if (fileobject.options && fileobject.options.nocompile) { if (fileobject.options && fileobject.options.nocompile) {
continue; continue;
} }
@ -192,7 +213,7 @@ export class MakeExporter extends Exporter {
for (let fileobject of project.getFiles()) { for (let fileobject of project.getFiles()) {
let file = fileobject.file; let file = fileobject.file;
if (file.endsWith('.c') || file.endsWith('.cpp') || file.endsWith('.cc') || file.endsWith('.s') || file.endsWith('.S')) { if (file.endsWith('.c') || file.endsWith('.cpp') || file.endsWith('.cc') || file.endsWith('.s') || file.endsWith('.S') || file.endsWith('.m') || file.endsWith('.mm') || file.endsWith('.m.h')) {
if (fileobject.options && fileobject.options.nocompile) { if (fileobject.options && fileobject.options.nocompile) {
continue; continue;
} }
@ -215,6 +236,14 @@ export class MakeExporter extends Exporter {
compiler = this.cCompiler; compiler = this.cCompiler;
flags = ''; flags = '';
} }
else if (file.endsWith('.m') || file.endsWith('.m.h')) {
compiler = this.cCompiler;
flags = '$(CPPFLAGS)';
}
else if (file.endsWith('.mm')) {
compiler = this.cppCompiler;
flags = '$(CPPFLAGS)';
}
this.p('\t' + compiler + ' ' + optimization + ' $(INC) $(DEF) -MD ' + flags + ' -c ' + realfile + ' -o ' + name + '.o'); this.p('\t' + compiler + ' ' + optimization + ' $(INC) $(DEF) -MD ' + flags + ' -c ' + realfile + ' -o ' + name + '.o');
} }

View File

@ -516,7 +516,8 @@ export class Project {
} }
matches(text: string, pattern: string) { matches(text: string, pattern: string) {
const regexstring = pattern.replace(/\./g, '\\.').replace(/\*\*/g, '.?').replace(/\*/g, '[^/]*').replace(/\?/g, '*'); //const regexstring = pattern.replace(/\./g, '\\.').replace(/\*\*/g, '.?').replace(/\*/g, '[^/]*').replace(/\?/g, '*');
const regexstring = pattern.replace(/\./g, '\\.').replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*').replace(/\?/g, '.');
const regex = new RegExp('^' + regexstring + '$', 'g'); const regex = new RegExp('^' + regexstring + '$', 'g');
return regex.test(text); return regex.test(text);
} }

View File

@ -11,6 +11,8 @@ import { VisualStudioVersion } from 'kmake/VisualStudioVersion';
import { Exporter } from 'kmake/Exporters/Exporter'; import { Exporter } from 'kmake/Exporters/Exporter';
import { AndroidExporter } from 'kmake/Exporters/AndroidExporter'; import { AndroidExporter } from 'kmake/Exporters/AndroidExporter';
import { LinuxExporter } from 'kmake/Exporters/LinuxExporter'; import { LinuxExporter } from 'kmake/Exporters/LinuxExporter';
import { MacOSExporter } from 'kmake/Exporters/MacOSExporter';
import { MakeExporter } from 'kmake/Exporters/MakeExporter';
import { EmscriptenExporter } from 'kmake/Exporters/EmscriptenExporter'; import { EmscriptenExporter } from 'kmake/Exporters/EmscriptenExporter';
import { WasmExporter } from 'kmake/Exporters/WasmExporter'; import { WasmExporter } from 'kmake/Exporters/WasmExporter';
import { VisualStudioExporter } from 'kmake/Exporters/VisualStudioExporter'; import { VisualStudioExporter } from 'kmake/Exporters/VisualStudioExporter';
@ -628,7 +630,22 @@ async function exportKoremakeProject(from: string, to: string, platform: string,
else if (options.meson) { else if (options.meson) {
exporter = new MesonExporter(options); exporter = new MesonExporter(options);
} }
else if (platform === Platform.iOS || platform === Platform.OSX || platform === Platform.tvOS) exporter = new XCodeExporter(options); else if (platform === Platform.OSX) {
// Use MakeExporter directly for macOS to ensure .m files are compiled
let linkerFlags = '-pthread';
if (options.lib) {
linkerFlags += ' -static';
}
let outputExtension = '';
if (options.lib) {
outputExtension = '.a';
}
else if (options.dynlib) {
outputExtension = '.dylib';
}
exporter = new MakeExporter(options, 'clang', 'clang++', '', '', linkerFlags, outputExtension);
}
else if (platform === Platform.iOS || platform === Platform.tvOS) exporter = new XCodeExporter(options);
else if (platform === Platform.Android) exporter = new AndroidExporter(options); else if (platform === Platform.Android) exporter = new AndroidExporter(options);
else if (platform === Platform.Emscripten) exporter = new EmscriptenExporter(project, options); else if (platform === Platform.Emscripten) exporter = new EmscriptenExporter(project, options);
else if (platform === Platform.Wasm) exporter = new WasmExporter(options); else if (platform === Platform.Wasm) exporter = new WasmExporter(options);
@ -1067,7 +1084,10 @@ export async function run(options: any, loglog: any): Promise<string> {
else if (isPlatform(options, Platform.FreeBSD)) { else if (isPlatform(options, Platform.FreeBSD)) {
make = child_process.spawn('make', [], { cwd: path.join(options.to, options.buildPath) }); make = child_process.spawn('make', [], { cwd: path.join(options.to, options.buildPath) });
} }
else if (isPlatform(options, Platform.OSX) || isPlatform(options, Platform.iOS) || isPlatform(options, Platform.tvOS)) { else if (isPlatform(options, Platform.OSX)) {
make = child_process.spawn('make', [], { cwd: path.join(options.to, options.buildPath) });
}
else if (isPlatform(options, Platform.iOS) || isPlatform(options, Platform.tvOS)) {
let xcodeOptions = ['-configuration', options.debug ? 'Debug' : 'Release', '-project', solutionName + '.xcodeproj', '-quiet']; let xcodeOptions = ['-configuration', options.debug ? 'Debug' : 'Release', '-project', solutionName + '.xcodeproj', '-quiet'];
if (isPlatform(options, Platform.iOS)) { if (isPlatform(options, Platform.iOS)) {