From ed2b7e5ef1626c0d6318b6ea71897efbb4356277 Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Sun, 29 Sep 2019 15:30:18 +0200 Subject: Synced with GENie upstream revision e78d6c1 (#5631) * Synced with GENie upstream revision e78d6c1 * Add Visual Studio 2019 support * Fix hardcoded -m64 * Switch appveyor to Visual Studio 2019 * Fix genie being built as 32-bit * MSVC build is known to be broken currently. Let it fail until all the known issues are fixed. * Update the packages before building * Build with 3 threads Appveyor VMs have only 2 cores and 8 GB RAM. * Enable caching of pacman cache --- 3rdparty/genie/src/actions/xcode/xcode_common.lua | 726 ++++++++++++++-------- 1 file changed, 451 insertions(+), 275 deletions(-) (limited to '3rdparty/genie/src/actions/xcode/xcode_common.lua') diff --git a/3rdparty/genie/src/actions/xcode/xcode_common.lua b/3rdparty/genie/src/actions/xcode/xcode_common.lua index b3f925273b8..762c27aada1 100644 --- a/3rdparty/genie/src/actions/xcode/xcode_common.lua +++ b/3rdparty/genie/src/actions/xcode/xcode_common.lua @@ -18,10 +18,16 @@ function xcode.getbuildcategory(node) local categories = { [".a"] = "Frameworks", + [".h"] = "Headers", + [".hh"] = "Headers", + [".hpp"] = "Headers", + [".hxx"] = "Headers", + [".inl"] = "Headers", [".c"] = "Sources", [".cc"] = "Sources", [".cpp"] = "Sources", [".cxx"] = "Sources", + [".c++"] = "Sources", [".dylib"] = "Frameworks", [".bundle"] = "Frameworks", [".framework"] = "Frameworks", @@ -39,7 +45,8 @@ [".xcdatamodeld"] = "Sources", [".swift"] = "Sources", } - return categories[path.getextension(node.name)] + return categories[path.getextension(node.name)] or + categories[string.lower(path.getextension(node.name))] end @@ -78,12 +85,17 @@ [".cpp"] = "sourcecode.cpp.cpp", [".css"] = "text.css", [".cxx"] = "sourcecode.cpp.cpp", + [".c++"] = "sourcecode.cpp.cpp", [".entitlements"] = "text.xml", [".bundle"] = "wrapper.cfbundle", [".framework"] = "wrapper.framework", [".tbd"] = "sourcecode.text-based-dylib-definition", [".gif"] = "image.gif", [".h"] = "sourcecode.c.h", + [".hh"] = "sourcecode.cpp.h", + [".hpp"] = "sourcecode.cpp.h", + [".hxx"] = "sourcecode.cpp.h", + [".inl"] = "sourcecode.cpp.h", [".html"] = "text.html", [".lua"] = "sourcecode.lua", [".m"] = "sourcecode.c.objc", @@ -101,7 +113,8 @@ [".xcdatamodeld"] = "wrapper.xcdatamodeld", [".swift"] = "sourcecode.swift", } - return types[path.getextension(node.path)] or "text" + return types[path.getextension(node.path)] or + (types[string.lower(path.getextension(node.path))] or "text") end -- @@ -120,12 +133,17 @@ [".cpp"] = "sourcecode.cpp.cpp", [".css"] = "text.css", [".cxx"] = "sourcecode.cpp.cpp", + [".c++"] = "sourcecode.cpp.cpp", [".entitlements"] = "text.xml", [".bundle"] = "wrapper.cfbundle", [".framework"] = "wrapper.framework", [".tbd"] = "wrapper.framework", [".gif"] = "image.gif", [".h"] = "sourcecode.cpp.h", + [".hh"] = "sourcecode.cpp.h", + [".hpp"] = "sourcecode.cpp.h", + [".hxx"] = "sourcecode.cpp.h", + [".inl"] = "sourcecode.cpp.h", [".html"] = "text.html", [".lua"] = "sourcecode.lua", [".m"] = "sourcecode.cpp.objcpp", @@ -142,7 +160,8 @@ [".xcdatamodeld"] = "wrapper.xcdatamodeld", [".swift"] = "sourcecode.swift", } - return types[path.getextension(node.path)] or "text" + return types[path.getextension(node.path)] or + (types[string.lower(path.getextension(node.path))] or "text") end -- -- Return the Xcode product type, based target kind. @@ -156,10 +175,10 @@ function xcode.getproducttype(node) local types = { ConsoleApp = "com.apple.product-type.tool", - WindowedApp = "com.apple.product-type.application", + WindowedApp = node.cfg.options.SkipBundling and "com.apple.product-type.tool" or "com.apple.product-type.application", StaticLib = "com.apple.product-type.library.static", SharedLib = "com.apple.product-type.library.dynamic", - Bundle = "com.apple.product-type.bundle", + Bundle = node.cfg.options.SkipBundling and "com.apple.product-type.tool" or "com.apple.product-type.bundle", } return types[node.cfg.kind] end @@ -177,10 +196,10 @@ function xcode.gettargettype(node) local types = { ConsoleApp = "\"compiled.mach-o.executable\"", - WindowedApp = "wrapper.application", + WindowedApp = node.cfg.options.SkipBundling and "\"compiled.mach-o.executable\"" or "wrapper.application", StaticLib = "archive.ar", SharedLib = "\"compiled.mach-o.dylib\"", - Bundle = "wrapper.cfbundle", + Bundle = node.cfg.options.SkipBundling and "\"compiled.mach-o.bundle\"" or "wrapper.cfbundle", } return types[node.cfg.kind] end @@ -216,6 +235,16 @@ return (path.getextension(fname) == ".framework" or path.getextension(fname) == ".tbd") end +-- +-- Generates a unique 12 byte ID. +-- Parameter is optional +-- +-- @returns +-- A 24-character string representing the 12 byte ID. +-- + function xcode.uuid(param) + return os.uuid(param):upper():gsub('-',''):sub(0,24) + end -- -- Retrieves a unique 12 byte ID for an object. This function accepts and ignores two @@ -226,14 +255,77 @@ -- A 24-character string representing the 12 byte ID. -- - function xcode.newid() - return string.format("%04X%04X%04X%04X%04X%04X", - math.random(0, 32767), - math.random(0, 32767), - math.random(0, 32767), - math.random(0, 32767), - math.random(0, 32767), - math.random(0, 32767)) + function xcode.newid(node, usage) + local base = '' + + -- Seed the uuid with the project name and a project-specific counter. + -- This is to prevent matching strings from generating the same uuid, + -- while still generating the same uuid for the same properties across + -- runs. + local prj = node.project + + if prj == nil then + local parent = node.parent + while parent ~= nil do + if parent.project ~= nil then + prj = parent.project + break + end + parent = parent.parent + end + end + + if prj ~= nil then + prj.uuidcounter = (prj.uuidcounter or 0) + 1 + base = base .. prj.name .. "$" .. prj.uuidcounter .. "$" + end + + base = base .. "$" .. (node.path or node.name or "") + base = base .. "$" .. (usage or "") + return xcode.uuid(base) + end + +-- +-- Creates a label for a given scriptphase +-- based on command and config +-- such as the result looks like this: +-- 'Script Phase [cmd] (Config)', e.g. 'Script Phase 1 [rsync] (Debug)' +-- +-- This function is used for generating `PBXShellScriptBuildPhase` from `xcodescriptphases`. +-- (Thus required in more than 1 place). +-- +-- @param cmd +-- The command itself +-- @param count +-- counter to avoid having duplicate label names +-- @param cfg +-- The configuration the command is generated for +-- + + function xcode.getscriptphaselabel(cmd, count, cfg) + return string.format("\"Script Phase %s [%s] (%s)\"", count, cmd:match("(%w+)(.+)"), iif(cfg, xcode.getconfigname(cfg), "all")) + end + + +-- +-- Creates a label for a given copy phase +-- based on target +-- such as the result looks like this: +-- 'Copy [target]', e.g. 'Copy Files 1 [assets]' +-- +-- This function is used for generating `PBXCopyFilesPhase` from `xcodecopyresources`. +-- (Thus required in more than 1 place). +-- +-- @param type +-- The copy type ('Resources' for now) +-- @param count +-- counter to avoid having duplicate label names +-- @param target +-- The target subfolder +-- + + function xcode.getcopyphaselabel(type, count, target) + return string.format("\"Copy %s %s [%s]\"", type, count, target) end @@ -276,11 +368,14 @@ -- The Xcode specific list tag. -- - function xcode.printlist(list, tag) + function xcode.printlist(list, tag, sort) if #list > 0 then + if sort ~= nil and sort == true then + table.sort(list) + end _p(4,'%s = (', tag) for _, item in ipairs(list) do - local escaped_item = item:gsub("\"", "\\\"") + local escaped_item = item:gsub("\"", "\\\\\\\""):gsub("'", "\\\\'") _p(5, '"%s",', escaped_item) end _p(4,');') @@ -288,24 +383,66 @@ end +-- +-- Escape a string for use in an Xcode project file. +-- + + function xcode.quotestr(str) + -- simple strings don't need quotes + if str:match("[^a-zA-Z0-9$._/]") == nil then + return str + end + + return "\"" .. str:gsub("[\"\\\"]", "\\%0") .. "\"" + end + + + --------------------------------------------------------------------------- -- Section generator functions, in the same order in which they appear -- in the .pbxproj file --------------------------------------------------------------------------- - function xcode.Header() - _p('// !$*UTF8*$!') - _p('{') - _p(1,'archiveVersion = 1;') - _p(1,'classes = {') - _p(1,'};') - _p(1,'objectVersion = 45;') - _p(1,'objects = {') - _p('') - end +function xcode.Header(tr, objversion) + _p('// !$*UTF8*$!') + _p('{') + _p(1,'archiveVersion = 1;') + _p(1,'classes = {') + _p(1,'};') + _p(1,'objectVersion = %d;', objversion) + _p(1,'objects = {') + _p('') +end function xcode.PBXBuildFile(tr) + local function gatherCopyFiles(which) + local copyfiles = {} + local targets = tr.project[which] + if #targets > 0 then + for _, t in ipairs(targets) do + for __, tt in ipairs(t) do + table.insertflat(copyfiles, tt[2]) + end + end + end + return table.translate(copyfiles, path.getname) + end + + local function gatherCopyFrameworks(which) + local copyfiles = {} + local targets = tr.project[which] + if #targets > 0 then + table.insertflat(copyfiles, targets) + end + return table.translate(copyfiles, path.getname) + end + + local copyfiles = table.flatten({ + gatherCopyFiles('xcodecopyresources'), + gatherCopyFrameworks('xcodecopyframeworks') + }) + _p('/* Begin PBXBuildFile section */') tree.traverse(tr, { onnode = function(node) @@ -313,6 +450,15 @@ _p(2,'%s /* %s in %s */ = {isa = PBXBuildFile; fileRef = %s /* %s */; };', node.buildid, node.name, xcode.getbuildcategory(node), node.id, node.name) end + + -- adds duplicate PBXBuildFile file entry as 'CopyFiles' for files marked to be copied + -- for frameworks: add signOnCopy flag + if table.icontains(copyfiles, node.name) then + _p(2,'%s /* %s in %s */ = {isa = PBXBuildFile; fileRef = %s /* %s */; %s };', + xcode.uuid(node.name .. 'in CopyFiles'), node.name, 'CopyFiles', node.id, node.name, + iif(xcode.isframework(node.name), "settings = {ATTRIBUTES = (CodeSignOnCopy, ); };", "") + ) + end end }) _p('/* End PBXBuildFile section */') @@ -381,7 +527,8 @@ end if string.find(nodePath,'/') then if string.find(nodePath,'^%.')then - error('relative paths are not currently supported for frameworks') + --error('relative paths are not currently supported for frameworks') + nodePath = path.getabsolute(path.join(tr.project.location, nodePath)) end pth = nodePath elseif path.getextension(nodePath)=='.tbd' then @@ -404,9 +551,13 @@ -- something else; probably a source code file src = "" - -- if the parent node is virtual, it won't have a local path - -- of its own; need to use full relative path from project - if node.parent.isvpath then + if node.location then + pth = node.location + elseif node.parent.isvpath then + -- if the parent node is virtual, it won't have a local path + -- of its own; need to use full relative path from project + -- (in fact, often almost all paths are virtual because vpath + -- trims the leading dots from the full path) pth = node.cfg.name else pth = tree.getlocalpath(node) @@ -486,7 +637,10 @@ _p(3,'name = Products;') else _p(3,'name = "%s";', node.name) - if node.path and not node.isvpath then + + if node.location then + _p(3,'path = "%s";', node.location) + elseif node.path and not node.isvpath then local p = node.path if node.parent.path then p = path.getrelative(node.parent.path, node.path) @@ -527,22 +681,85 @@ end end + local function dobuildblock(id, label, which, action) + if hasBuildCommands(which) then + local commandcount = 0 + for _, cfg in ipairs(tr.configs) do + commandcount = commandcount + #cfg[which] + end + if commandcount > 0 then + action(id, label) + end + end + end + + local function doscriptphases(which, action) + local i = 0 + for _, cfg in ipairs(tr.configs) do + local cfgcmds = cfg[which] + if cfgcmds ~= nil then + for __, scripts in ipairs(cfgcmds) do + for ___, script in ipairs(scripts) do + local cmd = script[1] + local label = xcode.getscriptphaselabel(cmd, i, cfg) + local id = xcode.uuid(label) + action(id, label) + i = i + 1 + end + end + end + end + end + + local function docopyresources(which, action) + if hasBuildCommands(which) then + local targets = tr.project[which] + if #targets > 0 then + local i = 0 + for _, t in ipairs(targets) do + for __, tt in ipairs(t) do + local label = xcode.getcopyphaselabel('Resources', i, tt[1]) + local id = xcode.uuid(label) + action(id, label) + i = i + 1 + end + end + end + end + end + + local function docopyframeworks(which, action) + if hasBuildCommands(which) then + local targets = tr.project[which] + if #targets > 0 then + local label = "Copy Frameworks" + local id = xcode.uuid(label) + action(id, label) + end + end + end + + local function _p_label(id, label) + _p(4, '%s /* %s */,', id, label) + end + + _p(2,'%s /* %s */ = {', node.targetid, name) _p(3,'isa = PBXNativeTarget;') _p(3,'buildConfigurationList = %s /* Build configuration list for PBXNativeTarget "%s" */;', node.cfgsection, name) _p(3,'buildPhases = (') - if hasBuildCommands('prebuildcommands') then - _p(4,'9607AE1010C857E500CD1376 /* Prebuild */,') - end + dobuildblock('9607AE1010C857E500CD1376', 'Prebuild', 'prebuildcommands', _p_label) _p(4,'%s /* Resources */,', node.resstageid) _p(4,'%s /* Sources */,', node.sourcesid) - if hasBuildCommands('prelinkcommands') then - _p(4,'9607AE3510C85E7E00CD1376 /* Prelink */,') - end + dobuildblock('9607AE3510C85E7E00CD1376', 'Prelink', 'prelinkcommands', _p_label) _p(4,'%s /* Frameworks */,', node.fxstageid) - if hasBuildCommands('postbuildcommands') then - _p(4,'9607AE3710C85E8F00CD1376 /* Postbuild */,') + dobuildblock('9607AE3710C85E8F00CD1376', 'Postbuild', 'postbuildcommands', _p_label) + doscriptphases("xcodescriptphases", _p_label) + docopyresources("xcodecopyresources", _p_label) + if tr.project.kind == "WindowedApp" then + docopyframeworks("xcodecopyframeworks", _p_label) end + _p(3,');') _p(3,'buildRules = (') _p(3,');') @@ -575,12 +792,12 @@ end - function xcode.PBXProject(tr) + function xcode.PBXProject(tr, compatVersion) _p('/* Begin PBXProject section */') _p(2,'__RootObject_ /* Project object */ = {') _p(3,'isa = PBXProject;') _p(3,'buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "%s" */;', tr.name) - _p(3,'compatibilityVersion = "Xcode 3.2";') + _p(3,'compatibilityVersion = "Xcode %s";', compatVersion) _p(3,'hasScannedForEncodings = 1;') _p(3,'mainGroup = %s /* %s */;', tr.id, tr.name) _p(3,'projectDirPath = "";') @@ -653,47 +870,91 @@ function xcode.PBXShellScriptBuildPhase(tr) local wrapperWritten = false - local function doblock(id, name, which) + local function doblock(id, name, commands, files) + if commands ~= nil then + commands = table.flatten(commands) + end + if #commands > 0 then + if not wrapperWritten then + _p('/* Begin PBXShellScriptBuildPhase section */') + wrapperWritten = true + end + _p(2,'%s /* %s */ = {', id, name) + _p(3,'isa = PBXShellScriptBuildPhase;') + _p(3,'buildActionMask = 2147483647;') + _p(3,'files = (') + _p(3,');') + _p(3,'inputPaths = ('); + if files ~= nil then + files = table.flatten(files) + if #files > 0 then + for _, file in ipairs(files) do + _p(4, '"%s",', file) + end + end + end + _p(3,');'); + _p(3,'name = %s;', name); + _p(3,'outputPaths = ('); + _p(3,');'); + _p(3,'runOnlyForDeploymentPostprocessing = 0;'); + _p(3,'shellPath = /bin/sh;'); + _p(3,'shellScript = "%s";', table.concat(commands, "\\n"):gsub('"', '\\"')) + _p(2,'};') + end + end + + local function wrapcommands(cmds, cfg) + local commands = {} + if #cmds > 0 then + table.insert(commands, 'if [ "${CONFIGURATION}" = "' .. xcode.getconfigname(cfg) .. '" ]; then') + for i = 1, #cmds do + local cmd = cmds[i] + cmd = cmd:gsub('\\','\\\\') + table.insert(commands, cmd) + end + table.insert(commands, 'fi') + end + return commands + end + + local function dobuildblock(id, name, which) -- see if there are any commands to add for each config local commands = {} for _, cfg in ipairs(tr.configs) do - local cfgcmds = cfg[which] + local cfgcmds = wrapcommands(cfg[which], cfg) if #cfgcmds > 0 then - table.insert(commands, 'if [ "${CONFIGURATION}" = "' .. xcode.getconfigname(cfg) .. '" ]; then') - for i = 1, #cfgcmds do - local cmd = cfgcmds[i] - cmd = cmd:gsub('\\','\\\\') + for i, cmd in ipairs(cfgcmds) do table.insert(commands, cmd) end - table.insert(commands, 'fi') end end + doblock(id, name, commands) + end - if #commands > 0 then - if not wrapperWritten then - _p('/* Begin PBXShellScriptBuildPhase section */') - wrapperWritten = true + local function doscriptphases(which) + local i = 0 + for _, cfg in ipairs(tr.configs) do + local cfgcmds = cfg[which] + if cfgcmds ~= nil then + for __, scripts in ipairs(cfgcmds) do + for ___, script in ipairs(scripts) do + local cmd = script[1] + local files = script[2] + local label = xcode.getscriptphaselabel(cmd, i, cfg) + local id = xcode.uuid(label) + doblock(id, label, wrapcommands({cmd}, cfg), files) + i = i + 1 + end + end end - _p(2,'%s /* %s */ = {', id, name) - _p(3,'isa = PBXShellScriptBuildPhase;') - _p(3,'buildActionMask = 2147483647;') - _p(3,'files = (') - _p(3,');') - _p(3,'inputPaths = ('); - _p(3,');'); - _p(3,'name = %s;', name); - _p(3,'outputPaths = ('); - _p(3,');'); - _p(3,'runOnlyForDeploymentPostprocessing = 0;'); - _p(3,'shellPath = /bin/sh;'); - _p(3,'shellScript = "%s";', table.concat(commands, "\\n"):gsub('"', '\\"')) - _p(2,'};') end end - doblock("9607AE1010C857E500CD1376", "Prebuild", "prebuildcommands") - doblock("9607AE3510C85E7E00CD1376", "Prelink", "prelinkcommands") - doblock("9607AE3710C85E8F00CD1376", "Postbuild", "postbuildcommands") + dobuildblock("9607AE1010C857E500CD1376", "Prebuild", "prebuildcommands") + dobuildblock("9607AE3510C85E7E00CD1376", "Prelink", "prelinkcommands") + dobuildblock("9607AE3710C85E8F00CD1376", "Postbuild", "postbuildcommands") + doscriptphases("xcodescriptphases") if wrapperWritten then _p('/* End PBXShellScriptBuildPhase section */') @@ -725,6 +986,82 @@ _p('') end + -- copyresources leads to this + -- xcodeembedframeworks + function xcode.PBXCopyFilesBuildPhase(tr) + local wrapperWritten = false + + local function doblock(id, name, folderSpec, path, files) + -- note: folder spec: + -- 0: Absolute Path + -- 1: Wrapper + -- 6: Executables + -- 7: Resources + -- 10: Frameworks + -- 16: Products Directory + -- category: 'Frameworks' or 'CopyFiles' + + if #files > 0 then + if not wrapperWritten then + _p('/* Begin PBXCopyFilesBuildPhase section */') + wrapperWritten = true + end + _p(2,'%s /* %s */ = {', id, name) + _p(3,'isa = PBXCopyFilesBuildPhase;') + _p(3,'buildActionMask = 2147483647;') + _p(3,'dstPath = \"%s\";', path) + _p(3,'dstSubfolderSpec = \"%s\";', folderSpec) + _p(3,'files = (') + tree.traverse(tr, { + onleaf = function(node) + -- print(node.name) + if table.icontains(files, node.name) then + _p(4,'%s /* %s in %s */,', + xcode.uuid(node.name .. 'in CopyFiles'), node.name, 'CopyFiles') + end + end + }) + _p(3,');') + _p(3,'runOnlyForDeploymentPostprocessing = 0;'); + _p(2,'};') + end + end + + local function docopyresources(which) + local targets = tr.project[which] + if #targets > 0 then + local i = 0 + for _, t in ipairs(targets) do + for __, tt in ipairs(t) do + local label = xcode.getcopyphaselabel('Resources', i, tt[1]) + local id = xcode.uuid(label) + local files = table.translate(table.flatten(tt[2]), path.getname) + doblock(id, label, 7, tt[1], files) + i = i + 1 + end + end + end + end + + local function docopyframeworks(which) + local targets = tr.project[which] + if #targets > 0 then + local label = "Copy Frameworks" + local id = xcode.uuid(label) + local files = table.translate(table.flatten(targets), path.getname) + doblock(id, label, 10, "", files) + end + end + + docopyresources("xcodecopyresources") + if tr.project.kind == "WindowedApp" then + docopyframeworks("xcodecopyframeworks") + end + + if wrapperWritten then + _p('/* End PBXCopyFilesBuildPhase section */') + end + end function xcode.PBXVariantGroup(tr) _p('/* Begin PBXVariantGroup section */') @@ -767,83 +1104,7 @@ end - function xcode.XCBuildConfiguration_Target(tr, target, cfg) - local cfgname = xcode.getconfigname(cfg) - - _p(2,'%s /* %s */ = {', cfg.xcode.targetid, cfgname) - _p(3,'isa = XCBuildConfiguration;') - _p(3,'buildSettings = {') - _p(4,'ALWAYS_SEARCH_USER_PATHS = NO;') - - if not cfg.flags.Symbols then - _p(4,'DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";') - end - - if cfg.kind ~= "StaticLib" and cfg.buildtarget.prefix ~= "" then - _p(4,'EXECUTABLE_PREFIX = %s;', cfg.buildtarget.prefix) - end - - if cfg.targetextension then - local ext = cfg.targetextension - ext = iif(ext:startswith("."), ext:sub(2), ext) - _p(4,'EXECUTABLE_EXTENSION = %s;', ext) - end - - if cfg.flags.ObjcARC then - _p(4,'CLANG_ENABLE_OBJC_ARC = YES;') - end - - local outdir = path.getdirectory(cfg.buildtarget.bundlepath) - if outdir ~= "." then - _p(4,'CONFIGURATION_BUILD_DIR = %s;', outdir) - end - - _p(4,'GCC_DYNAMIC_NO_PIC = NO;') - _p(4,'GCC_MODEL_TUNING = G5;') - - if tr.infoplist then - _p(4,'INFOPLIST_FILE = "%s";', tr.infoplist.cfg.name) - end - - installpaths = { - ConsoleApp = '/usr/local/bin', - WindowedApp = '"$(HOME)/Applications"', - SharedLib = '/usr/local/lib', - StaticLib = '/usr/local/lib', - Bundle = '"$(LOCAL_LIBRARY_DIR)/Bundles"', - } - _p(4,'INSTALL_PATH = %s;', installpaths[cfg.kind]) - - local infoplist_file = nil - - for _, v in ipairs(cfg.files) do - -- for any file named *info.plist, use it as the INFOPLIST_FILE - if (string.find (string.lower (v), 'info.plist') ~= nil) then - infoplist_file = string.format('$(SRCROOT)/%s', v) - end - end - - if infoplist_file ~= nil then - _p(4,'INFOPLIST_FILE = "%s";', infoplist_file) - end - - if cfg.kind == "Bundle" then - _p(4, 'PRODUCT_BUNDLE_IDENTIFIER = "genie.%s";', cfg.buildtarget.basename:gsub("%s+", '.')) --replace spaces with . - end - - _p(4,'PRODUCT_NAME = "%s";', cfg.buildtarget.basename) - - if cfg.kind == "Bundle" then - _p(4, 'WRAPPER_EXTENSION = bundle;') - end - - _p(3,'};') - _p(3,'name = "%s";', cfgname) - _p(2,'};') - end - - - local function cfg_excluded_files(prj, cfg) + function xcode.cfg_excluded_files(prj, cfg) local excluded = {} -- Converts a file path to a pattern with no relative parts, prefixed with `*`. @@ -902,161 +1163,76 @@ end - function xcode.XCBuildConfiguration_Project(tr, prj, cfg) + function xcode.XCBuildConfiguration_Impl(tr, id, opts, cfg) local cfgname = xcode.getconfigname(cfg) - _p(2,'%s /* %s */ = {', cfg.xcode.projectid, cfgname) + _p(2,'%s /* %s */ = {', id, cfgname) _p(3,'isa = XCBuildConfiguration;') _p(3,'buildSettings = {') - local archs = { - Native = "$(NATIVE_ARCH_ACTUAL)", - x32 = "i386", - x64 = "x86_64", - Universal32 = "$(ARCHS_STANDARD_32_BIT)", - Universal64 = "$(ARCHS_STANDARD_64_BIT)", - Universal = "$(ARCHS_STANDARD_32_64_BIT)", - } - _p(4,'ARCHS = "%s";', archs[cfg.platform]) - - _p(4,'SDKROOT = "%s";', xcode.toolset) - - if tr.entitlements then - _p(4,'CODE_SIGN_ENTITLEMENTS = "%s";', tr.entitlements.cfg.name) - end - - local targetdir = path.getdirectory(cfg.buildtarget.bundlepath) - if targetdir ~= "." then - _p(4,'CONFIGURATION_BUILD_DIR = "$(SYMROOT)";'); - end - - _p(4,'CONFIGURATION_TEMP_DIR = "$(OBJROOT)";') + for k, v in table.sortedpairs(opts) do + if type(v) == "table" then + if #v > 0 then + _p(4,'%s = (', k) - if cfg.flags.Symbols then - _p(4,'COPY_PHASE_STRIP = NO;') - end + for i, v2 in ipairs(v) do + _p(5,'%s,', xcode.quotestr(tostring(v2))) + end - local excluded = cfg_excluded_files(prj, cfg) - if #excluded > 0 then - _p(4, 'EXCLUDED_SOURCE_FILE_NAMES = (') - for _, file in ipairs(excluded) do - _p(5, '"' .. file .. '",') + _p(4,');') + end + else + _p(4,'%s = %s;', k, xcode.quotestr(tostring(v))) end - _p(4, ');') - end - - _p(4,'GCC_C_LANGUAGE_STANDARD = gnu99;') - - if cfg.flags.NoExceptions then - _p(4,'GCC_ENABLE_CPP_EXCEPTIONS = NO;') - end - - if cfg.flags.NoRTTI then - _p(4,'GCC_ENABLE_CPP_RTTI = NO;') - end - - if _ACTION ~= "xcode4" and cfg.flags.Symbols and not cfg.flags.NoEditAndContinue then - _p(4,'GCC_ENABLE_FIX_AND_CONTINUE = YES;') - end - - if cfg.flags.NoExceptions then - _p(4,'GCC_ENABLE_OBJC_EXCEPTIONS = NO;') - end - - if cfg.flags.Optimize or cfg.flags.OptimizeSize then - _p(4,'GCC_OPTIMIZATION_LEVEL = s;') - elseif cfg.flags.OptimizeSpeed then - _p(4,'GCC_OPTIMIZATION_LEVEL = 3;') - else - _p(4,'GCC_OPTIMIZATION_LEVEL = 0;') - end - - if cfg.pchheader and not cfg.flags.NoPCH then - _p(4,'GCC_PRECOMPILE_PREFIX_HEADER = YES;') - _p(4,'GCC_PREFIX_HEADER = "%s";', cfg.pchheader) - end - - xcode.printlist(cfg.defines, 'GCC_PREPROCESSOR_DEFINITIONS') - - _p(4,'GCC_SYMBOLS_PRIVATE_EXTERN = NO;') - - if cfg.flags.FatalWarnings then - _p(4,'GCC_TREAT_WARNINGS_AS_ERRORS = YES;') end - _p(4,'GCC_WARN_ABOUT_RETURN_TYPE = YES;') - _p(4,'GCC_WARN_UNUSED_VARIABLE = YES;') - - xcode.printlist(cfg.includedirs, 'HEADER_SEARCH_PATHS') - xcode.printlist(cfg.userincludedirs, 'USER_HEADER_SEARCH_PATHS') - xcode.printlist(cfg.libdirs, 'LIBRARY_SEARCH_PATHS') - - _p(4,'OBJROOT = "%s";', cfg.objectsdir) - - _p(4,'ONLY_ACTIVE_ARCH = %s;',iif(premake.config.isdebugbuild(cfg),'YES','NO')) - - -- build list of "other" C/C++ flags - local checks = { - ["-ffast-math"] = cfg.flags.FloatFast, - ["-ffloat-store"] = cfg.flags.FloatStrict, - ["-fomit-frame-pointer"] = cfg.flags.NoFramePointer, - } + _p(3,'};') + _p(3,'name = %s;', xcode.quotestr(cfgname)) + _p(2,'};') + end - local flags = { } - for flag, check in pairs(checks) do - if check then - table.insert(flags, flag) + local function add_options(options, extras) + for _, tbl in ipairs(extras) do + for tkey, tval in pairs(tbl) do + options[tkey] = tval end end + end - for _, val in ipairs(premake.xcode.parameters) do - _p(4, val ..';') - end - - xcode.printlist(table.join(flags, cfg.buildoptions, cfg.buildoptions_c), 'OTHER_CFLAGS') - xcode.printlist(table.join(flags, cfg.buildoptions, cfg.buildoptions_cpp), 'OTHER_CPLUSPLUSFLAGS') + local function add_wholearchive_links(opts, cfg) + if #cfg.wholearchive > 0 then + local linkopts = {} - -- build list of "other" linked flags. All libraries that aren't frameworks - -- are listed here, so I don't have to try and figure out if they are ".a" - -- or ".dylib", which Xcode requires to list in the Frameworks section - flags = { } - for _, lib in ipairs(premake.getlinks(cfg, "system")) do - if not xcode.isframework(lib) then - table.insert(flags, "-l" .. lib) + for _, depcfg in ipairs(premake.getlinks(cfg, "siblings", "object")) do + if table.icontains(cfg.wholearchive, depcfg.project.name) then + local linkpath = path.rebase(depcfg.linktarget.fullpath, depcfg.location, cfg.location) + table.insert(linkopts, "-force_load") + table.insert(linkopts, linkpath) + end end - end - flags = table.join(flags, cfg.linkoptions) - xcode.printlist(flags, 'OTHER_LDFLAGS') - - if cfg.flags.StaticRuntime then - _p(4,'STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;') - end - if targetdir ~= "." then - _p(4,'SYMROOT = "%s";', targetdir) - end + if opts.OTHER_LDFLAGS then + linkopts = table.join(linkopts, opts.OTHER_LDFLAGS) + end - if cfg.flags.PedanticWarnings - or cfg.flags.ExtraWarnings - then - _p(4,'WARNING_CFLAGS = "-Wall";') + opts.OTHER_LDFLAGS = linkopts end - - _p(3,'};') - _p(3,'name = "%s";', cfgname) - _p(2,'};') end - - function xcode.XCBuildConfiguration(tr, prj) + function xcode.XCBuildConfiguration(tr, prj, opts) _p('/* Begin XCBuildConfiguration section */') for _, target in ipairs(tr.products.children) do for _, cfg in ipairs(tr.configs) do - xcode.XCBuildConfiguration_Target(tr, target, cfg) + local values = opts.ontarget(tr, target, cfg) + add_options(values, cfg.xcodetargetopts) + xcode.XCBuildConfiguration_Impl(tr, cfg.xcode.targetid, values, cfg) end end for _, cfg in ipairs(tr.configs) do - xcode.XCBuildConfiguration_Project(tr, prj, cfg) + local values = opts.onproject(tr, prj, cfg) + add_options(values, cfg.xcodeprojectopts) + add_wholearchive_links(values, cfg) + xcode.XCBuildConfiguration_Impl(tr, cfg.xcode.projectid, values, cfg) end _p('/* End XCBuildConfiguration section */') _p('') -- cgit v1.2.3-70-g09d2