"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XCodeExporter = void 0; const Exporter_1 = require("kmake/Exporters/Exporter"); const Icon = require("kmake/Icon"); const Platform_1 = require("kmake/Platform"); const fs = require("kmake/fsextra"); const path = require("path"); const child_process = require("child_process"); const crypto = require("crypto"); function uuidv4() { return crypto.randomUUID(); } // not quite uuid v5 but close enough function uuidv5(path, namespace) { const hash = crypto.createHash('sha1'); hash.update(namespace); hash.update(path); const value = hash.digest('hex'); return value.substring(0, 8) + '-' + value.substring(8, 12) + '-' + value.substring(12, 16) + '-' + value.substring(16, 20) + '-' + value.substring(20, 32); } function contains(a, b) { return a.indexOf(b) !== -1; } function newId() { return uuidv4().toUpperCase(); } function newPathId(path) { return uuidv5(path, '7448ebd8-cfc8-4f45-8b3d-5df577ceea6d').toUpperCase(); } function getDir(file) { if (file.file.indexOf('/') >= 0) { let dir = file.file.substr(0, file.file.lastIndexOf('/')); return path.join(file.projectName, path.relative(file.projectDir, dir)).replace(/\\/g, '/'); } else { return file.projectName; } } class Directory { constructor(dirname) { this.dirname = dirname; this.id = newPathId(dirname); } getName() { return this.dirname; } getLastName() { if (this.dirname.indexOf('/') < 0) return this.dirname; return this.dirname.substr(this.dirname.lastIndexOf('/') + 1); } getId() { return this.id; } } class File { constructor(filename, dir, options) { this.filename = filename; this.dir = dir; this.buildid = newPathId(dir + filename + '_buildid'); this.fileid = newPathId(dir + filename + '_fileid'); this.options = options; } getBuildId() { return this.buildid; } getFileId() { return this.fileid; } isBuildFile() { const buildFileType = this.filename.endsWith('.c') || this.filename.endsWith('.cpp') || this.filename.endsWith('.m') || this.filename.endsWith('.mm') || this.filename.endsWith('.cc') || this.filename.endsWith('.s') || this.filename.endsWith('S') || this.filename.endsWith('.metal') || this.filename.endsWith('.storyboard'); if (buildFileType) { if (this.options && this.options.nocompile) { return false; } } return buildFileType; } getName() { return this.filename; } getLastName() { if (this.filename.indexOf('/') < 0) return this.filename; return this.filename.substr(this.filename.lastIndexOf('/') + 1); } getDir() { return this.dir; } toString() { return this.getName(); } } class Framework { constructor(name) { this.name = name; this.buildid = newPathId(name + '_buildid'); this.fileid = newPathId(name + '_fileid'); this.localPath = null; } toString() { if (this.name.indexOf('.') < 0) return this.name + '.framework'; else return this.name; } getBuildId() { return this.buildid.toString().toUpperCase(); } getFileId() { return this.fileid.toString().toUpperCase(); } } function findDirectory(dirname, directories) { for (let dir of directories) { if (dir.getName() === dirname) { return dir; } } return null; } function addDirectory(dirname, directories) { let dir = findDirectory(dirname, directories); if (dir === null) { dir = new Directory(dirname); directories.push(dir); while (dirname.indexOf('/') >= 0) { dirname = dirname.substr(0, dirname.lastIndexOf('/')); addDirectory(dirname, directories); } } return dir; } class XCodeExporter extends Exporter_1.Exporter { constructor(options) { super(options); } exportWorkspace(to, project) { const dir = path.resolve(to, project.getSafeName() + '.xcodeproj', 'project.xcworkspace'); fs.ensureDirSync(dir); this.writeFile(path.resolve(to, project.getSafeName() + '.xcodeproj', 'project.xcworkspace', 'contents.xcworkspacedata')); this.p(''); this.p(''); this.p(''); this.p(''); this.p(''); this.closeFile(); } open(project, to) { child_process.spawn('open', [path.resolve(to, project.getSafeName() + '.xcodeproj')], { detached: true, shell: true }); } async exportSolution(project, from, to, platform, vrApi, options) { const xdir = path.resolve(to, project.getSafeName() + '.xcodeproj'); fs.ensureDirSync(xdir); this.exportWorkspace(to, project); let icons = []; class IconImage { constructor(idiom, size, scale, background = undefined) { this.idiom = idiom; this.size = size; this.scale = scale; this.background = background; } } if (platform === Platform_1.Platform.iOS) { icons.push(new IconImage('iphone', 20, 2)); icons.push(new IconImage('iphone', 20, 3)); icons.push(new IconImage('iphone', 29, 2)); icons.push(new IconImage('iphone', 29, 3)); icons.push(new IconImage('iphone', 40, 2)); icons.push(new IconImage('iphone', 40, 3)); icons.push(new IconImage('iphone', 60, 2)); icons.push(new IconImage('iphone', 60, 3)); icons.push(new IconImage('ipad', 20, 1)); icons.push(new IconImage('ipad', 20, 2)); icons.push(new IconImage('ipad', 29, 1)); icons.push(new IconImage('ipad', 29, 2)); icons.push(new IconImage('ipad', 40, 1)); icons.push(new IconImage('ipad', 40, 2)); icons.push(new IconImage('ipad', 76, 1)); icons.push(new IconImage('ipad', 76, 2)); icons.push(new IconImage('ipad', 83.5, 2)); icons.push(new IconImage('ios-marketing', 1024, 1, 0x000000ff)); } else { icons.push(new IconImage('mac', 16, 1)); icons.push(new IconImage('mac', 16, 2)); icons.push(new IconImage('mac', 32, 1)); icons.push(new IconImage('mac', 32, 2)); icons.push(new IconImage('mac', 128, 1)); icons.push(new IconImage('mac', 128, 2)); icons.push(new IconImage('mac', 256, 1)); icons.push(new IconImage('mac', 256, 2)); icons.push(new IconImage('mac', 512, 1)); icons.push(new IconImage('mac', 512, 2)); } const iconsdir = path.resolve(to, 'Images.xcassets', 'AppIcon.appiconset'); fs.ensureDirSync(iconsdir); this.writeFile(path.resolve(to, 'Images.xcassets', 'AppIcon.appiconset', 'Contents.json')); this.p('{'); this.p('"images" : [', 1); for (let i = 0; i < icons.length; ++i) { const icon = icons[i]; this.p('{', 2); this.p('"idiom" : "' + icon.idiom + '",', 3); this.p('"size" : "' + icon.size + 'x' + icon.size + '",', 3); this.p('"filename" : "' + icon.idiom + icon.scale + 'x' + icon.size + '.png",', 3); this.p('"scale" : "' + icon.scale + 'x"', 3); if (i === icons.length - 1) this.p('}', 2); else this.p('},', 2); } this.p('],', 1); this.p('"info" : {', 1); this.p('"version" : 1,', 2); this.p('"author" : "xcode"', 2); this.p('}', 1); this.p('}'); this.closeFile(); // const black = 0xff; for (let i = 0; i < icons.length; ++i) { const icon = icons[i]; await Icon.exportPng(project.icon, path.resolve(to, 'Images.xcassets', 'AppIcon.appiconset', icon.idiom + icon.scale + 'x' + icon.size + '.png'), icon.size * icon.scale, icon.size * icon.scale, icon.background, from); } let plistname = ''; let files = []; let directories = []; for (let fileobject of project.getFiles()) { let filename = fileobject.file; if (filename.endsWith('.plist')) plistname = filename; let dir = addDirectory(getDir(fileobject), directories); let file = new File(filename, dir, fileobject.options); files.push(file); } if (plistname.length === 0) throw 'no plist found'; let frameworks = []; for (let lib of project.getLibs()) { frameworks.push(new Framework(lib)); } let targetOptions = { bundle: 'tech.kode.$(PRODUCT_NAME:rfc1034identifier)', version: '1.0', build: '1', organizationName: 'the Kore Development Team', developmentTeam: '' }; if (project.targetOptions && project.targetOptions.ios) { let userOptions = project.targetOptions.ios; if (userOptions.bundle) targetOptions.bundle = userOptions.bundle; if (userOptions.version) targetOptions.version = userOptions.version; if (userOptions.build) targetOptions.build = userOptions.build; if (userOptions.organizationName) targetOptions.organizationName = userOptions.organizationName; if (userOptions.developmentTeam) targetOptions.developmentTeam = userOptions.developmentTeam; } const projectId = newPathId('_projectId'); const appFileId = newPathId('_appFileId'); const frameworkBuildId = newPathId('_frameworkBuildId'); const sourceBuildId = newPathId('_sourceBuildId'); const frameworksGroupId = newPathId('_frameworksGroupId'); const productsGroupId = newPathId('_productsGroupId'); const mainGroupId = newPathId('_mainGroupId'); const targetId = newPathId('_targetId'); const nativeBuildConfigListId = newPathId('_nativeBuildConfigListId'); const projectBuildConfigListId = newPathId('_projectBuildConfigListId'); const debugId = newPathId('_debugId'); const releaseId = newPathId('_releaseId'); const nativeDebugId = newPathId('_nativeDebugId'); const nativeReleaseId = newPathId('_nativeReleaseId'); const debugDirFileId = newPathId('_debugDirFileId'); const debugDirBuildId = newPathId('_debugDirBuildId'); const resourcesBuildId = newPathId('_resourcesBuildId'); const iconFileId = newPathId('_iconFileId'); const iconBuildId = newPathId('_iconBuildId'); // var iosIconFileIds = []; // var iosIconBuildIds = []; // for (var i = 0; i < iosIconNames.length; ++i) { // iosIconFileIds.push(newId()); // iosIconBuildIds.push(newId()); // } this.writeFile(path.resolve(to, project.getSafeName() + '.xcodeproj', 'project.pbxproj')); this.p('// !$*UTF8*$!'); this.p('{'); this.p('archiveVersion = 1;', 1); this.p('classes = {', 1); this.p('};', 1); this.p('objectVersion = 46;', 1); this.p('objects = {', 1); this.p(); this.p('/* Begin PBXBuildFile section */'); for (let framework of frameworks) { this.p(framework.getBuildId() + ' /* ' + framework.toString() + ' in Frameworks */ = {isa = PBXBuildFile; fileRef = ' + framework.getFileId() + ' /* ' + framework.toString() + ' */; };', 2); } this.p(debugDirBuildId + ' /* Deployment in Resources */ = {isa = PBXBuildFile; fileRef = ' + debugDirFileId + ' /* Deployment */; };', 2); for (let file of files) { if (file.isBuildFile()) { this.p(file.getBuildId() + ' /* ' + file.toString() + ' in Sources */ = {isa = PBXBuildFile; fileRef = ' + file.getFileId() + ' /* ' + file.toString() + ' */; };', 2); } } if (!options.lib && !options.dynlib) { this.p(iconBuildId + ' /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ' + iconFileId + ' /* Images.xcassets */; };', 2); } this.p('/* End PBXBuildFile section */'); this.p(); this.p('/* Begin PBXFileReference section */'); let executableName = project.getSafeName(); if (project.getExecutableName()) { executableName = project.getExecutableName(); } if (options.lib) { this.p(appFileId + ' /* ' + project.getSafeName() + '.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "' + executableName + '.a"; sourceTree = BUILT_PRODUCTS_DIR; };', 2); } else if (options.dynlib) { this.p(appFileId + ' /* ' + project.getSafeName() + '.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "' + executableName + '.dylib"; sourceTree = BUILT_PRODUCTS_DIR; };', 2); } else { this.p(appFileId + ' /* ' + project.getSafeName() + '.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "' + executableName + '.app"; sourceTree = BUILT_PRODUCTS_DIR; };', 2); } for (let framework of frameworks) { if (framework.toString().endsWith('.framework')) { // Local framework - a directory is specified if (framework.toString().indexOf('/') >= 0) { framework.localPath = path.resolve(from, framework.toString()); this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ' + framework.toString() + '; path = ' + framework.localPath + '; sourceTree = ""; };', 2); } // XCode framework else { this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ' + framework.toString() + '; path = System/Library/Frameworks/' + framework.toString() + '; sourceTree = SDKROOT; };', 2); } } else if (framework.toString().endsWith('.dylib')) { // Local dylib, e.g. V8 in Krom - a directory is specified if (framework.toString().indexOf('/') >= 0) { framework.localPath = path.resolve(from, framework.toString()); this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */ = {isa = PBXFileReference; lastKnownFileType = compiled.mach-o.dylib; name = ' + framework.toString() + '; path = ' + framework.localPath + '; sourceTree = ""; };', 2); } else { this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */ = {isa = PBXFileReference; lastKnownFileType = compiled.mach-o.dylib; name = ' + framework.toString() + '; path = usr/lib/' + framework.toString() + '; sourceTree = SDKROOT; };', 2); } } else { framework.localPath = path.resolve(from, framework.toString()); this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = ' + framework.toString() + '; path = ' + framework.localPath + '; sourceTree = ""; };', 2); } } this.p(debugDirFileId + ' /* Deployment */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Deployment; path = "' + path.resolve(from, project.getDebugDir()) + '"; sourceTree = ""; };', 2); for (let file of files) { let filetype = 'unknown'; let fileencoding = ''; if (file.getName().endsWith('.storyboard')) filetype = 'file.storyboard'; if (file.getName().endsWith('.plist')) filetype = 'text.plist.xml'; if (file.getName().endsWith('.h')) filetype = 'sourcecode.c.h'; if (file.getName().endsWith('.m')) filetype = 'sourcecode.c.objc'; if (file.getName().endsWith('.c')) filetype = 'sourcecode.c.c'; if (file.getName().endsWith('.cpp')) filetype = 'sourcecode.c.cpp'; if (file.getName().endsWith('.cc')) filetype = 'sourcecode.c.cpp'; if (file.getName().endsWith('.mm')) filetype = 'sourcecode.c.objcpp'; if (file.getName().endsWith('.s') || file.getName().endsWith('.S')) filetype = 'sourcecode.asm'; if (file.getName().endsWith('.metal')) { filetype = 'sourcecode.metal'; fileencoding = 'fileEncoding = 4; '; } if (!file.getName().endsWith('.DS_Store')) { this.p(file.getFileId() + ' /* ' + file.toString() + ' */ = {isa = PBXFileReference; ' + fileencoding + 'lastKnownFileType = ' + filetype + '; name = "' + file.getLastName() + '"; path = "' + path.resolve(from, file.toString()) + '"; sourceTree = ""; };', 2); } } if (!options.lib && !options.dynlib) { this.p(iconFileId + ' /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };', 2); } this.p('/* End PBXFileReference section */'); this.p(); this.p('/* Begin PBXFrameworksBuildPhase section */'); this.p(frameworkBuildId + ' /* Frameworks */ = {', 2); this.p('isa = PBXFrameworksBuildPhase;', 3); this.p('buildActionMask = 2147483647;', 3); this.p('files = (', 3); for (let framework of frameworks) { this.p(framework.getBuildId() + ' /* ' + framework.toString() + ' in Frameworks */,', 4); } this.p(');', 3); this.p('runOnlyForDeploymentPostprocessing = 0;', 3); this.p('};', 2); this.p('/* End PBXFrameworksBuildPhase section */'); this.p(); this.p('/* Begin PBXGroup section */'); this.p(mainGroupId + ' = {', 2); this.p('isa = PBXGroup;', 3); this.p('children = (', 3); if (!options.lib && !options.dynlib) { this.p(iconFileId + ' /* Images.xcassets */,', 4); } this.p(debugDirFileId + ' /* Deployment */,', 4); // p(solutionGroupId + " /* " + solution.getName() + " */,", 4); for (let dir of directories) { if (dir.getName().indexOf('/') < 0) this.p(dir.getId() + ' /* ' + dir.getName() + ' */,', 4); } this.p(frameworksGroupId + ' /* Frameworks */,', 4); this.p(productsGroupId + ' /* Products */,', 4); this.p(');', 3); this.p('sourceTree = "";', 3); this.p('};', 2); this.p(productsGroupId + ' /* Products */ = {', 2); this.p('isa = PBXGroup;', 3); this.p('children = (', 3); if (options.lib) { this.p(appFileId + ' /* ' + project.getSafeName() + '.a */,', 4); } else if (options.dynlib) { this.p(appFileId + ' /* ' + project.getSafeName() + '.dynlib */,', 4); } else { this.p(appFileId + ' /* ' + project.getSafeName() + '.app */,', 4); } this.p(');', 3); this.p('name = Products;', 3); this.p('sourceTree = "";', 3); this.p('};', 2); this.p(frameworksGroupId + ' /* Frameworks */ = {', 2); this.p('isa = PBXGroup;', 3); this.p('children = (', 3); for (let framework of frameworks) { this.p(framework.getFileId() + ' /* ' + framework.toString() + ' */,', 4); } this.p(');', 3); this.p('name = Frameworks;', 3); this.p('sourceTree = "";', 3); this.p('};', 2); for (let dir of directories) { this.p(dir.getId() + ' /* ' + dir.getName() + ' */ = {', 2); this.p('isa = PBXGroup;', 3); this.p('children = (', 3); for (let dir2 of directories) { if (dir2 === dir) continue; if (dir2.getName().startsWith(dir.getName())) { if (dir2.getName().substr(dir.getName().length + 1).indexOf('/') < 0) this.p(dir2.getId() + ' /* ' + dir2.getName() + ' */,', 4); } } for (let file of files) { if (file.getDir() === dir && !file.getName().endsWith('.DS_Store')) this.p(file.getFileId() + ' /* ' + file.toString() + ' */,', 4); } this.p(');', 3); if (dir.getName().indexOf('/') < 0) { this.p('path = ../;', 3); this.p('name = "' + dir.getLastName() + '";', 3); } else this.p('name = "' + dir.getLastName() + '";', 3); this.p('sourceTree = "";', 3); this.p('};', 2); } this.p('/* End PBXGroup section */'); this.p(); this.p('/* Begin PBXNativeTarget section */'); this.p(targetId + ' /* ' + project.getSafeName() + ' */ = {', 2); this.p('isa = PBXNativeTarget;', 3); this.p('buildConfigurationList = ' + nativeBuildConfigListId + ' /* Build configuration list for PBXNativeTarget "' + project.getSafeName() + '" */;', 3); this.p('buildPhases = (', 3); this.p(sourceBuildId + ' /* Sources */,', 4); this.p(frameworkBuildId + ' /* Frameworks */,', 4); this.p(resourcesBuildId + ' /* Resources */,', 4); this.p(');', 3); this.p('buildRules = (', 3); this.p(');', 3); this.p('dependencies = (', 3); this.p(');', 3); this.p('name = "' + project.getName() + '";', 3); this.p('productName = "' + project.getName() + '";', 3); if (options.lib) { this.p('productReference = ' + appFileId + ' /* ' + project.getSafeName() + '.a */;', 3); this.p('productType = "com.apple.product-type.library.static";', 3); } else if (options.dynlib) { this.p('productReference = ' + appFileId + ' /* ' + project.getSafeName() + '.dylib */;', 3); this.p('productType = "com.apple.product-type.library.dynamic";', 3); } else { this.p('productReference = ' + appFileId + ' /* ' + project.getSafeName() + '.app */;', 3); this.p('productType = "com.apple.product-type.' + (project.isCmd() ? 'tool' : 'application') + '";', 3); } this.p('};', 2); this.p('/* End PBXNativeTarget section */'); this.p(); this.p('/* Begin PBXProject section */'); this.p(projectId + ' /* Project object */ = {', 2); this.p('isa = PBXProject;', 3); this.p('attributes = {', 3); this.p('LastUpgradeCheck = 1230;', 4); this.p('ORGANIZATIONNAME = "' + targetOptions.organizationName + '";', 4); this.p('TargetAttributes = {', 4); this.p(targetId + ' = {', 5); this.p('CreatedOnToolsVersion = 6.1.1;', 6); if (targetOptions.developmentTeam) { this.p('DevelopmentTeam = ' + targetOptions.developmentTeam + ';', 6); } this.p('};', 5); this.p('};', 4); this.p('};', 3); this.p('buildConfigurationList = ' + projectBuildConfigListId + ' /* Build configuration list for PBXProject "' + project.getSafeName() + '" */;', 3); this.p('compatibilityVersion = "Xcode 3.2";', 3); this.p('developmentRegion = en;', 3); this.p('hasScannedForEncodings = 0;', 3); this.p('knownRegions = (', 3); this.p('en,', 4); this.p('Base,', 4); this.p(');', 3); this.p('mainGroup = ' + mainGroupId + ';', 3); this.p('productRefGroup = ' + productsGroupId + ' /* Products */;', 3); this.p('projectDirPath = "";', 3); this.p('projectRoot = "";', 3); this.p('targets = (', 3); this.p(targetId + ' /* ' + project.getSafeName() + ' */,', 4); this.p(');', 3); this.p('};', 2); this.p('/* End PBXProject section */'); this.p(); if (!options.lib && !options.dynlib) { this.p('/* Begin PBXResourcesBuildPhase section */'); this.p(resourcesBuildId + ' /* Resources */ = {', 2); this.p('isa = PBXResourcesBuildPhase;', 3); this.p('buildActionMask = 2147483647;', 3); this.p('files = (', 3); this.p(debugDirBuildId + ' /* Deployment in Resources */,', 4); this.p(iconBuildId + ' /* Images.xcassets in Resources */,', 4); this.p(');', 3); this.p('runOnlyForDeploymentPostprocessing = 0;', 3); this.p('};', 2); this.p('/* End PBXResourcesBuildPhase section */'); this.p(); } this.p('/* Begin PBXSourcesBuildPhase section */'); this.p(sourceBuildId + ' /* Sources */ = {', 2); this.p('isa = PBXSourcesBuildPhase;', 3); this.p('buildActionMask = 2147483647;', 3); this.p('files = (', 3); for (let file of files) { if (file.isBuildFile()) this.p(file.getBuildId() + ' /* ' + file.toString() + ' in Sources */,', 4); } this.p(');', 3); this.p('runOnlyForDeploymentPostprocessing = 0;'); this.p('};'); this.p('/* End PBXSourcesBuildPhase section */'); this.p(); // p("/* Begin PBXVariantGroup section */"); // p("E1FC77F013DAA40000D635AE /* InfoPlist.strings */ = {", 2); // p("isa = PBXVariantGroup;", 3); // p("children = (", 3); // p("E1FC77F113DAA40000D635AE /* en */,", 4); // p(");", 3); // p("name = InfoPlist.strings;", 3); // p("sourceTree = \"\";", 3); // p("};", 2); // p("E1FC77F913DAA40000D635AE /* MainWindow.xib */ = {", 2); // p("isa = PBXVariantGroup;", 3); // p("children = (", 3); // p("E1FC77FA13DAA40000D635AE /* en */,", 4); // p(");", 3); // p("name = MainWindow.xib;", 3); // p("sourceTree = \"\";", 3); // p("};", 2); // p("E1FC780613DAA40000D635AE /* TestViewController.xib */ = {", 2); // p("isa = PBXVariantGroup;", 3); // p("children = (", 3); // p("E1FC780713DAA40000D635AE /* en */,", 4); // p(");", 3); // p("name = TestViewController.xib;", 3); // p("sourceTree = \"\";", 3); // p("};", 2); // p("/* End PBXVariantGroup section */"); // p(); this.p('/* Begin XCBuildConfiguration section */'); this.p(debugId + ' /* Debug */ = {', 2); this.p('isa = XCBuildConfiguration;', 3); this.p('buildSettings = {', 3); this.p('ALWAYS_SEARCH_USER_PATHS = NO;', 4); if (project.cppStd !== '' && project.cppStd !== 'gnu++14') { this.p('CLANG_CXX_LANGUAGE_STANDARD = "' + project.cppStd + '";', 4); } else { this.p('CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";', 4); } this.p('CLANG_CXX_LIBRARY = "compiler-default";', 4); this.p('CLANG_ENABLE_MODULES = YES;', 4); this.p('CLANG_ENABLE_OBJC_ARC = YES;', 4); this.p('CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;', 4); this.p('CLANG_WARN_BOOL_CONVERSION = YES;', 4); this.p('CLANG_WARN_COMMA = YES;', 4); this.p('CLANG_WARN_CONSTANT_CONVERSION = YES;', 4); this.p('CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;', 4); this.p('CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;', 4); this.p('CLANG_WARN_EMPTY_BODY = YES;', 4); this.p('CLANG_WARN_ENUM_CONVERSION = YES;', 4); this.p('CLANG_WARN_INFINITE_RECURSION = YES;', 4); this.p('CLANG_WARN_INT_CONVERSION = YES;', 4); this.p('CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;', 4); this.p('CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;', 4); this.p('CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;', 4); this.p('CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;', 4); this.p('CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;', 4); this.p('CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;', 4); this.p('CLANG_WARN_STRICT_PROTOTYPES = YES;', 4); this.p('CLANG_WARN_SUSPICIOUS_MOVE = YES;', 4); this.p('CLANG_WARN_UNREACHABLE_CODE = YES;', 4); this.p('CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;', 4); if (platform === Platform_1.Platform.iOS) { this.p('"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";', 4); } else { this.p('CODE_SIGN_IDENTITY = "-";', 4); } this.p('COPY_PHASE_STRIP = NO;', 4); this.p('ENABLE_STRICT_OBJC_MSGSEND = YES;', 4); this.p('ENABLE_TESTABILITY = YES;', 4); if (project.cStd !== '' && project.cStd !== 'c99') { this.p('GCC_C_LANGUAGE_STANDARD = "' + project.cStd + '";', 4); } else { this.p('GCC_C_LANGUAGE_STANDARD = "gnu99";', 4); } this.p('GCC_DYNAMIC_NO_PIC = NO;', 4); this.p('GCC_NO_COMMON_BLOCKS = YES;', 4); this.p('GCC_OPTIMIZATION_LEVEL = 0;', 4); this.p('GCC_PREPROCESSOR_DEFINITIONS = (', 4); this.p('"DEBUG=1",', 5); for (const define of project.getDefines()) { if (define.config && define.config.toLowerCase() === 'release') { continue; } if (define.value.indexOf('=') >= 0) this.p('"' + define.value.replace(/\"/g, '\\\\\\"') + '",', 5); else this.p(define.value + ',', 5); } this.p('"$(inherited)",', 5); this.p(');', 4); this.p('GCC_SYMBOLS_PRIVATE_EXTERN = NO;', 4); this.p('GCC_WARN_64_TO_32_BIT_CONVERSION = YES;', 4); this.p('GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;', 4); this.p('GCC_WARN_UNDECLARED_SELECTOR = YES;', 4); this.p('GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;', 4); this.p('GCC_WARN_UNUSED_FUNCTION = YES;', 4); this.p('GCC_WARN_UNUSED_VARIABLE = YES;', 4); if (platform === Platform_1.Platform.iOS) { this.p('IPHONEOS_DEPLOYMENT_TARGET = 15.6;', 4); } else { this.p('MACOSX_DEPLOYMENT_TARGET = 11.5;', 4); } this.p('MTL_ENABLE_DEBUG_INFO = YES;', 4); this.p('ONLY_ACTIVE_ARCH = YES;', 4); if (platform === Platform_1.Platform.iOS) { this.p('SDKROOT = iphoneos;', 4); this.p('TARGETED_DEVICE_FAMILY = "1,2";', 4); } else { this.p('SDKROOT = macosx;', 4); } this.p('};', 3); this.p('name = Debug;', 3); this.p('};', 2); this.p(releaseId + ' /* Release */ = {', 2); this.p('isa = XCBuildConfiguration;', 3); this.p('buildSettings = {', 3); this.p('ALWAYS_SEARCH_USER_PATHS = NO;', 4); if (project.cppStd !== '' && project.cppStd !== 'gnu++14') { this.p('CLANG_CXX_LANGUAGE_STANDARD = "' + project.cppStd + '";', 4); } else { this.p('CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";', 4); } this.p('CLANG_CXX_LIBRARY = "compiler-default";', 4); this.p('CLANG_ENABLE_MODULES = YES;', 4); this.p('CLANG_ENABLE_OBJC_ARC = YES;', 4); this.p('CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;', 4); this.p('CLANG_WARN_BOOL_CONVERSION = YES;', 4); this.p('CLANG_WARN_COMMA = YES;', 4); this.p('CLANG_WARN_CONSTANT_CONVERSION = YES;', 4); this.p('CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;', 4); this.p('CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;', 4); this.p('CLANG_WARN_EMPTY_BODY = YES;', 4); this.p('CLANG_WARN_ENUM_CONVERSION = YES;', 4); this.p('CLANG_WARN_INFINITE_RECURSION = YES;', 4); this.p('CLANG_WARN_INT_CONVERSION = YES;', 4); this.p('CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;', 4); this.p('CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;', 4); this.p('CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;', 4); this.p('CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;', 4); this.p('CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;', 4); this.p('CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;', 4); this.p('CLANG_WARN_STRICT_PROTOTYPES = YES;', 4); this.p('CLANG_WARN_SUSPICIOUS_MOVE = YES;', 4); this.p('CLANG_WARN_UNREACHABLE_CODE = YES;', 4); this.p('CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;', 4); if (platform === Platform_1.Platform.iOS) { this.p('"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";', 4); } else { this.p('CODE_SIGN_IDENTITY = "-";', 4); } this.p('COPY_PHASE_STRIP = YES;', 4); if (platform === Platform_1.Platform.OSX) { this.p('DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";', 4); } this.p('ENABLE_NS_ASSERTIONS = NO;', 4); this.p('ENABLE_STRICT_OBJC_MSGSEND = YES;', 4); if (project.cStd !== '' && project.cStd !== 'c99') { this.p('GCC_C_LANGUAGE_STANDARD = "' + project.cStd + '";', 4); } else { this.p('GCC_C_LANGUAGE_STANDARD = "gnu99";', 4); } this.p('GCC_NO_COMMON_BLOCKS = YES;', 4); this.p('GCC_PREPROCESSOR_DEFINITIONS = (', 4); this.p('NDEBUG,', 5); for (const define of project.getDefines()) { if (define.config && define.config.toLowerCase() === 'debug') { continue; } if (define.value.indexOf('=') >= 0) this.p('"' + define.value.replace(/\"/g, '\\\\\\"') + '",', 5); else this.p(define.value + ',', 5); } this.p('"$(inherited)",', 5); this.p(');', 4); this.p('GCC_WARN_64_TO_32_BIT_CONVERSION = YES;', 4); this.p('GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;', 4); this.p('GCC_WARN_UNDECLARED_SELECTOR = YES;', 4); this.p('GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;', 4); this.p('GCC_WARN_UNUSED_FUNCTION = YES;', 4); this.p('GCC_WARN_UNUSED_VARIABLE = YES;', 4); if (platform === Platform_1.Platform.iOS) { this.p('IPHONEOS_DEPLOYMENT_TARGET = 15.6;', 4); } else { this.p('MACOSX_DEPLOYMENT_TARGET = 11.5;', 4); } this.p('MTL_ENABLE_DEBUG_INFO = NO;', 4); if (platform === Platform_1.Platform.iOS) { this.p('SDKROOT = iphoneos;', 4); this.p('TARGETED_DEVICE_FAMILY = "1,2";', 4); this.p('VALIDATE_PRODUCT = YES;', 4); } else { this.p('SDKROOT = macosx;', 4); } this.p('};', 3); this.p('name = Release;', 3); this.p('};', 2); this.p(nativeDebugId + ' /* Debug */ = {', 2); this.p('isa = XCBuildConfiguration;', 3); this.p('buildSettings = {', 3); if (project.macOSnoArm) { this.p('ARCHS = x86_64;', 4); } if (!options.lib && !options.dynlib) { this.p('ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;', 4); } if (platform === Platform_1.Platform.OSX && (!options.lib && !options.dynlib)) { this.p('COMBINE_HIDPI_IMAGES = YES;', 4); } this.p('FRAMEWORK_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); // Search paths to local frameworks for (let framework of frameworks) { if (framework.localPath != null) this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } this.p(');', 4); this.p('HEADER_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); this.p('"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",', 5); for (let projectpath of project.getIncludeDirs()) this.p('"' + path.resolve(from, projectpath).replace(/ /g, '\\\\ ') + '",', 5); this.p(');', 4); this.p('LIBRARY_SEARCH_PATHS = (', 4); for (let framework of frameworks) { if ((framework.toString().endsWith('.dylib') || framework.toString().endsWith('.a')) && framework.localPath != null) { this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } } this.p(');', 4); if (!options.lib && !options.dynlib) { this.p('INFOPLIST_EXPAND_BUILD_SETTINGS = "YES";', 4); this.p('INFOPLIST_FILE = "' + path.resolve(from, plistname) + '";', 4); this.p('LD_RUNPATH_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); if (platform === Platform_1.Platform.iOS) { this.p('"@executable_path/Frameworks",', 5); } for (let framework of frameworks) { if (framework.toString().endsWith('.dylib') && framework.localPath != null) { this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } } this.p(');', 4); } if (project.cFlags.length > 0) { this.p('OTHER_CFLAGS = (', 4); for (let cFlag of project.cFlags) { this.p('"' + cFlag + '",', 5); } this.p(');', 4); } if (project.cppFlags.length > 0) { this.p('OTHER_CPLUSPLUSFLAGS = (', 4); for (let cppFlag of project.cppFlags) { this.p('"' + cppFlag + '",', 5); } this.p(');', 4); } if (options.dynlib) { this.p('DYLIB_COMPATIBILITY_VERSION = 1;', 4); this.p('DYLIB_CURRENT_VERSION = 1;', 4); this.p('EXECUTABLE_PREFIX = lib;', 4); } else if (options.lib) { this.p('EXECUTABLE_PREFIX = lib;', 4); } if (!options.lib && !options.dynlib) { this.p('PRODUCT_BUNDLE_IDENTIFIER = "' + targetOptions.bundle + '";', 4); } this.p('BUNDLE_VERSION = "' + targetOptions.version + '";', 4); this.p('BUILD_VERSION = "' + targetOptions.build + '";', 4); this.p('CODE_SIGN_IDENTITY = "-";', 4); this.p('PRODUCT_NAME = "$(TARGET_NAME)";', 4); if (options.lib) { // this.p('MACH_O_TYPE = staticlib;', 4); // this.p('STRIP_INSTALLED_PRODUCT = NO;', 4); this.p('SKIP_INSTALL = YES;', 4); } else if (options.dynlib) { // this.p('MACH_O_TYPE = mh_dylib;', 4); // this.p('STRIP_STYLE = debugging;', 4); this.p('SKIP_INSTALL = YES;', 4); } this.p('};', 3); this.p('name = Debug;', 3); this.p('};', 2); this.p(nativeReleaseId + ' /* Release */ = {', 2); this.p('isa = XCBuildConfiguration;', 3); this.p('buildSettings = {', 3); if (project.macOSnoArm) { this.p('ARCHS = x86_64;', 4); } if (!options.lib && !options.dynlib) { this.p('ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;', 4); } if (platform === Platform_1.Platform.OSX && (!options.lib && !options.dynlib)) { this.p('COMBINE_HIDPI_IMAGES = YES;', 4); } this.p('"EXCLUDED_SOURCE_FILE_NAMES[arch=*]" = (', 4); for (let fileobject of project.getFiles()) { let file = fileobject.file; if (file.endsWith('.cpp') || file.endsWith('.c') || file.endsWith('.cc') || file.endsWith('.cxx') || file.endsWith('.m') || file.endsWith('.mm')) { if (fileobject.options && fileobject.options.nocompile) { this.p('"' + file + '",', 5); } } } this.p(');', 4); this.p('FRAMEWORK_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); // Search paths to local frameworks for (let framework of frameworks) { if (framework.localPath != null) this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } this.p(');', 4); this.p('HEADER_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); this.p('"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",', 5); for (let p of project.getIncludeDirs()) this.p('"' + path.resolve(from, p).replace(/ /g, '\\\\ ') + '",', 5); this.p(');', 4); this.p('LIBRARY_SEARCH_PATHS = (', 4); for (let framework of frameworks) { if ((framework.toString().endsWith('.dylib') || framework.toString().endsWith('.a')) && framework.localPath != null) { this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } } this.p(');', 4); if (!options.lib && !options.dynlib) { this.p('INFOPLIST_EXPAND_BUILD_SETTINGS = "YES";', 4); this.p('INFOPLIST_FILE = "' + path.resolve(from, plistname) + '";', 4); this.p('LD_RUNPATH_SEARCH_PATHS = (', 4); this.p('"$(inherited)",', 5); if (platform === Platform_1.Platform.iOS) { this.p('"@executable_path/Frameworks",', 5); } for (let framework of frameworks) { if (framework.toString().endsWith('.dylib') && framework.localPath != null) { this.p(framework.localPath.substr(0, framework.localPath.lastIndexOf('/')) + ',', 5); } } this.p(');', 4); } if (project.cFlags.length > 0) { this.p('OTHER_CFLAGS = (', 4); for (let cFlag of project.cFlags) { this.p('"' + cFlag + '",', 5); } this.p(');', 4); } if (project.cppFlags.length > 0) { this.p('OTHER_CPLUSPLUSFLAGS = (', 4); for (let cppFlag of project.cppFlags) { this.p('"' + cppFlag + '",', 5); } this.p(');', 4); } if (options.dynlib) { this.p('DYLIB_COMPATIBILITY_VERSION = 1;', 4); this.p('DYLIB_CURRENT_VERSION = 1;', 4); this.p('EXECUTABLE_PREFIX = lib;', 4); } else if (options.lib) { this.p('EXECUTABLE_PREFIX = lib;', 4); } if (!options.lib && !options.dynlib) { this.p('PRODUCT_BUNDLE_IDENTIFIER = "' + targetOptions.bundle + '";', 4); } this.p('BUNDLE_VERSION = "' + targetOptions.version + '";', 4); this.p('BUILD_VERSION = "' + targetOptions.build + '";', 4); this.p('CODE_SIGN_IDENTITY = "-";', 4); this.p('PRODUCT_NAME = "$(TARGET_NAME)";', 4); if (options.lib) { // this.p('MACH_O_TYPE = staticlib;', 4); // this.p('STRIP_INSTALLED_PRODUCT = NO;', 4); this.p('SKIP_INSTALL = YES;', 4); } else if (options.dynlib) { // this.p('MACH_O_TYPE = mh_dylib;', 4); // this.p('STRIP_STYLE = debugging;', 4); this.p('SKIP_INSTALL = YES;', 4); } this.p('};', 3); this.p('name = Release;', 3); this.p('};', 2); this.p('/* End XCBuildConfiguration section */'); this.p(); this.p('/* Begin XCConfigurationList section */'); this.p(projectBuildConfigListId + ' /* Build configuration list for PBXProject "' + project.getSafeName() + '" */ = {', 2); this.p('isa = XCConfigurationList;', 3); this.p('buildConfigurations = (', 3); this.p(debugId + ' /* Debug */,', 4); this.p(releaseId + ' /* Release */,', 4); this.p(');', 3); this.p('defaultConfigurationIsVisible = 0;', 3); this.p('defaultConfigurationName = Release;', 3); this.p('};', 2); this.p(nativeBuildConfigListId + ' /* Build configuration list for PBXNativeTarget "' + project.getSafeName() + '" */ = {', 2); this.p('isa = XCConfigurationList;', 3); this.p('buildConfigurations = (', 3); this.p(nativeDebugId + ' /* Debug */,', 4); this.p(nativeReleaseId + ' /* Release */,', 4); this.p(');', 3); this.p('defaultConfigurationIsVisible = 0;', 3); this.p('defaultConfigurationName = Release;', 3); this.p('};', 2); this.p('/* End XCConfigurationList section */'); this.p('};', 1); this.p('rootObject = ' + projectId + ' /* Project object */;', 1); this.p('}'); this.closeFile(); } } exports.XCodeExporter = XCodeExporter; //# sourceMappingURL=XCodeExporter.js.map