summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/genie/src/actions/xcode
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/genie/src/actions/xcode')
-rw-r--r--3rdparty/genie/src/actions/xcode/_xcode.lua88
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode10.lua116
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode4_workspace.lua100
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode6_config.lua10
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode6_project.lua247
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode8.lua362
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode9.lua107
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode_common.lua726
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode_project.lua71
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode_scheme.lua239
-rw-r--r--3rdparty/genie/src/actions/xcode/xcode_workspace.lua145
11 files changed, 1461 insertions, 750 deletions
diff --git a/3rdparty/genie/src/actions/xcode/_xcode.lua b/3rdparty/genie/src/actions/xcode/_xcode.lua
index f14e8d7300e..406486f796a 100644
--- a/3rdparty/genie/src/actions/xcode/_xcode.lua
+++ b/3rdparty/genie/src/actions/xcode/_xcode.lua
@@ -5,8 +5,6 @@
--
premake.xcode = { }
- premake.xcode.xcode6 = { }
-
--
-- Verify only single target kind for Xcode project
@@ -15,7 +13,7 @@
-- Project to be analyzed
--
- local function checkproject(prj)
+ function premake.xcode.checkproject(prj)
-- Xcode can't mix target kinds within a project
local last
for cfg in premake.eachconfig(prj) do
@@ -31,87 +29,3 @@
--
premake.xcode.toolset = "macosx"
-
- newaction
- {
- trigger = "xcode3",
- shortname = "Xcode 3",
- description = "Generate Apple Xcode 3 project files (experimental)",
- os = "macosx",
-
- valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Bundle" },
-
- valid_languages = { "C", "C++" },
-
- valid_tools = {
- cc = { "gcc" },
- },
-
- valid_platforms = {
- Native = "Native",
- x32 = "Native 32-bit",
- x64 = "Native 64-bit",
- Universal32 = "32-bit Universal",
- Universal64 = "64-bit Universal",
- Universal = "Universal",
- },
-
- default_platform = "Universal",
-
- onsolution = function(sln)
- -- Assign IDs needed for inter-project dependencies
- premake.xcode.preparesolution(sln)
- end,
-
- onproject = function(prj)
- premake.generate(prj, "%%.xcodeproj/project.pbxproj", premake.xcode.project)
- end,
-
- oncleanproject = function(prj)
- premake.clean.directory(prj, "%%.xcodeproj")
- end,
-
- oncheckproject = checkproject,
- }
-
- newaction
- {
- trigger = "xcode4",
- shortname = "Xcode 4",
- description = "Generate Apple Xcode 4 project files (experimental)",
- os = "macosx",
-
- valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Bundle" },
-
- valid_languages = { "C", "C++" },
-
- valid_tools = {
- cc = { "gcc" },
- },
-
- valid_platforms = {
- Native = "Native",
- x32 = "Native 32-bit",
- x64 = "Native 64-bit",
- Universal32 = "32-bit Universal",
- Universal64 = "64-bit Universal",
- Universal = "Universal",
- },
-
- default_platform = "Universal",
-
- onsolution = function(sln)
- premake.generate(sln, "%%.xcworkspace/contents.xcworkspacedata", premake.xcode4.workspace_generate)
- end,
-
- onproject = function(prj)
- premake.generate(prj, "%%.xcodeproj/project.pbxproj", premake.xcode.project)
- end,
-
- oncleanproject = function(prj)
- premake.clean.directory(prj, "%%.xcodeproj")
- premake.clean.directory(prj, "%%.xcworkspace")
- end,
-
- oncheckproject = checkproject,
- }
diff --git a/3rdparty/genie/src/actions/xcode/xcode10.lua b/3rdparty/genie/src/actions/xcode/xcode10.lua
new file mode 100644
index 00000000000..f8ae0b42cac
--- /dev/null
+++ b/3rdparty/genie/src/actions/xcode/xcode10.lua
@@ -0,0 +1,116 @@
+--
+-- xcode10.lua
+-- Define the Apple XCode 10.0 action and support functions.
+--
+
+ local premake = premake
+ premake.xcode10 = { }
+
+ local xcode = premake.xcode
+ local xcode8 = premake.xcode8
+ local xcode9 = premake.xcode9
+ local xcode10 = premake.xcode10
+
+ function xcode10.XCBuildConfiguration_Project(tr, prj, cfg)
+ local options = xcode9.XCBuildConfiguration_Project(tr, prj, cfg)
+
+ return table.merge(options, {
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = "YES",
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = "YES",
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = "YES",
+ CLANG_WARN_COMMA = "YES",
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = "YES",
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = "YES",
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = "YES",
+ CLANG_WARN_STRICT_PROTOTYPES = "YES",
+ })
+ end
+
+ function xcode10.XCBuildConfiguration_Target(tr, target, cfg)
+ local options = xcode8.XCBuildConfiguration_Target(tr, target, cfg)
+
+ if not cfg.flags.ObjcARC then
+ options.CLANG_ENABLE_OBJC_WEAK = "YES"
+ end
+
+ return options
+ end
+
+ function xcode10.project(prj)
+ local tr = xcode.buildprjtree(prj)
+ xcode.Header(tr, 48)
+ xcode.PBXBuildFile(tr)
+ xcode.PBXContainerItemProxy(tr)
+ xcode.PBXFileReference(tr,prj)
+ xcode.PBXFrameworksBuildPhase(tr)
+ xcode.PBXGroup(tr)
+ xcode.PBXNativeTarget(tr)
+ xcode.PBXProject(tr, "8.0")
+ xcode.PBXReferenceProxy(tr)
+ xcode.PBXResourcesBuildPhase(tr)
+ xcode.PBXShellScriptBuildPhase(tr)
+ xcode.PBXCopyFilesBuildPhase(tr)
+ xcode.PBXSourcesBuildPhase(tr,prj)
+ xcode.PBXVariantGroup(tr)
+ xcode.PBXTargetDependency(tr)
+ xcode.XCBuildConfiguration(tr, prj, {
+ ontarget = xcode10.XCBuildConfiguration_Target,
+ onproject = xcode10.XCBuildConfiguration_Project,
+ })
+ xcode.XCBuildConfigurationList(tr)
+ xcode.Footer(tr)
+ end
+
+
+--
+-- xcode10 action
+--
+
+ newaction
+ {
+ trigger = "xcode10",
+ shortname = "Xcode 10",
+ description = "Generate Apple Xcode 10 project files (experimental)",
+ os = "macosx",
+
+ valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Bundle" },
+
+ valid_languages = { "C", "C++" },
+
+ valid_tools = {
+ cc = { "gcc" },
+ },
+
+ valid_platforms = {
+ Native = "Native",
+ x32 = "Native 32-bit",
+ x64 = "Native 64-bit",
+ Universal = "Universal",
+ },
+
+ default_platform = "Native",
+
+ onsolution = function(sln)
+ premake.generate(sln, "%%.xcworkspace/contents.xcworkspacedata", xcode.workspace_generate)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings", xcode.workspace_settings)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/xcschemes/-ALL-.xcscheme", xcode.workspace_scheme)
+ end,
+
+ onproject = function(prj)
+ premake.generate(prj, "%%.xcodeproj/project.pbxproj", xcode10.project)
+ xcode.generate_schemes(prj, "%%.xcodeproj/xcshareddata/xcschemes")
+ end,
+
+ oncleanproject = function(prj)
+ premake.clean.directory(prj, "%%.xcodeproj")
+ premake.clean.directory(prj, "%%.xcworkspace")
+ end,
+
+ oncheckproject = xcode.checkproject,
+
+ xcode = {
+ iOSTargetPlatformVersion = nil,
+ macOSTargetPlatformVersion = nil,
+ tvOSTargetPlatformVersion = nil,
+ },
+ }
diff --git a/3rdparty/genie/src/actions/xcode/xcode4_workspace.lua b/3rdparty/genie/src/actions/xcode/xcode4_workspace.lua
deleted file mode 100644
index 726a306dc6f..00000000000
--- a/3rdparty/genie/src/actions/xcode/xcode4_workspace.lua
+++ /dev/null
@@ -1,100 +0,0 @@
-premake.xcode4 = {}
-
-local xcode4 = premake.xcode4
-
-function xcode4.workspace_head()
- _p('<?xml version="1.0" encoding="UTF-8"?>')
- _p('<Workspace')
- _p(1,'version = "1.0">')
-
-end
-
-function xcode4.workspace_tail()
- _p('</Workspace>')
-end
-
-function xcode4.workspace_file_ref(prj, indent)
-
- local projpath = path.getrelative(prj.solution.location, prj.location)
- if projpath == '.' then projpath = ''
- else projpath = projpath ..'/'
- end
- _p(indent, '<FileRef')
- _p(indent + 1, 'location = "group:%s">', projpath .. prj.name .. '.xcodeproj')
- _p(indent, '</FileRef>')
-end
-
-function xcode4.workspace_group(grp, indent)
- _p(indent, '<Group')
- _p(indent + 1, 'location = "container:"')
- _p(indent + 1, 'name = "%s">', grp.name)
-
- for _, child in ipairs(grp.groups) do
- xcode4.workspace_group(child, indent + 1)
- end
-
- for _, prj in ipairs(grp.projects) do
- xcode4.workspace_file_ref(prj, indent + 1)
- end
-
- _p(indent, '</Group>')
-end
-
-function xcode4.workspace_generate(sln)
- premake.xcode.preparesolution(sln)
-
- xcode4.workspace_head()
-
- xcode4.reorderProjects(sln)
-
- for grp in premake.solution.eachgroup(sln) do
- if grp.parent == nil then
- xcode4.workspace_group(grp, 1)
- end
- end
-
- for prj in premake.solution.eachproject(sln) do
- if prj.group == nil then
- xcode4.workspace_file_ref(prj, 1)
- end
- end
-
- xcode4.workspace_tail()
-end
-
---
--- If a startup project is specified, move it to the front of the project list.
--- This will make Visual Studio treat it like a startup project.
---
-
-function xcode4.reorderProjects(sln)
- if sln.startproject then
- for i, prj in ipairs(sln.projects) do
- if sln.startproject == prj.name then
- -- Move group tree containing the project to start of group list
- local cur = prj.group
- while cur ~= nil do
- -- Remove group from array
- for j, group in ipairs(sln.groups) do
- if group == cur then
- table.remove(sln.groups, j)
- break
- end
- end
-
- -- Add back at start
- table.insert(sln.groups, 1, cur)
- cur = cur.parent
- end
- -- Move the project itself to start
- table.remove(sln.projects, i)
- table.insert(sln.projects, 1, prj)
- break
- end
- end
- end
-end
-
-
-
-
diff --git a/3rdparty/genie/src/actions/xcode/xcode6_config.lua b/3rdparty/genie/src/actions/xcode/xcode6_config.lua
deleted file mode 100644
index 74be0e16f06..00000000000
--- a/3rdparty/genie/src/actions/xcode/xcode6_config.lua
+++ /dev/null
@@ -1,10 +0,0 @@
-local xcode6 = premake.xcode.xcode6
-
-function xcode6.generate_project_config(prj)
- _p("PRODUCT_NAME = $(TARGET_NAME)")
-
- if premake.isswiftproject(prj) then
- _p("OTHER_SWIFT_FLAGS = -DXcode")
- _p("USE_HEADERMAP = NO")
- end
-end \ No newline at end of file
diff --git a/3rdparty/genie/src/actions/xcode/xcode6_project.lua b/3rdparty/genie/src/actions/xcode/xcode6_project.lua
deleted file mode 100644
index 3ee73127e2a..00000000000
--- a/3rdparty/genie/src/actions/xcode/xcode6_project.lua
+++ /dev/null
@@ -1,247 +0,0 @@
---
--- xcode4_project.lua
--- Generate an Xcode4 C/C++ project.
--- Copyright (c) 2009 Jason Perkins and the Premake project
---
-
-local xcode = premake.xcode
-local xcode6 = xcode.xcode6
-local tree = premake.tree
-
---
--- Create a tree corresponding to what is shown in the Xcode project browser
--- pane, with nodes for files and folders, resources, frameworks, and products.
---
--- @param prj
--- The project being generated.
--- @returns
--- A tree, loaded with metadata, which mirrors Xcode's view of the project.
---
-
-function xcode6.buildprjtree(prj)
- local tr = premake.project.buildsourcetree(prj)
-
- -- create a list of build configurations and assign IDs
- tr.configs = {}
- for _, cfgname in ipairs(prj.solution.configurations) do
- for _, platform in ipairs(prj.solution.xcode.platforms) do
- local cfg = premake.getconfig(prj, cfgname, platform)
- cfg.xcode = {}
- cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode, cfgname)
- cfg.xcode.projectid = xcode.newid(tr, cfgname)
- table.insert(tr.configs, cfg)
- end
- end
-
- -- convert localized resources from their filesystem layout (English.lproj/MainMenu.xib)
- -- to Xcode's display layout (MainMenu.xib/English).
- tree.traverse(tr, {
- onbranch = function(node)
- if path.getextension(node.name) == ".lproj" then
- local lang = path.getbasename(node.name) -- "English", "French", etc.
-
- -- create a new language group for each file it contains
- for _, filenode in ipairs(node.children) do
- local grpnode = node.parent.children[filenode.name]
- if not grpnode then
- grpnode = tree.insert(node.parent, tree.new(filenode.name))
- grpnode.kind = "vgroup"
- end
-
- -- convert the file node to a language node and add to the group
- filenode.name = path.getbasename(lang)
- tree.insert(grpnode, filenode)
- end
-
- -- remove this directory from the tree
- tree.remove(node)
- end
- end
- })
-
- -- fix .xcassets files, they should be treated as a file, not a folder
- tree.traverse(tr, {
- onbranch = function(node)
- if path.getextension(node.name) == ".xcassets" then
- node.children = {}
- end
- end
- })
-
- -- the special folder "Frameworks" lists all linked frameworks
- tr.frameworks = tree.new("Frameworks")
- for cfg in premake.eachconfig(prj) do
- for _, link in ipairs(premake.getlinks(cfg, "system", "fullpath")) do
- local name = path.getname(link)
- if xcode.isframework(name) and not tr.frameworks.children[name] then
- node = tree.insert(tr.frameworks, tree.new(name))
- node.path = link
- end
- end
- end
-
- -- only add it to the tree if there are frameworks to link
- if #tr.frameworks.children > 0 then
- tree.insert(tr, tr.frameworks)
- end
-
- -- the special folder "Products" holds the target produced by the project; this
- -- is populated below
- tr.products = tree.insert(tr, tree.new("Products"))
-
- -- the special folder "Projects" lists sibling project dependencies
- tr.projects = tree.new("Projects")
- for _, dep in ipairs(premake.getdependencies(prj, "sibling", "object")) do
- -- create a child node for the dependency's xcodeproj
- local xcpath = xcode.getxcodeprojname(dep)
- local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath)))
- xcnode.path = xcpath
- xcnode.project = dep
- xcnode.productgroupid = xcode.newid(xcnode, "prodgrp")
- xcnode.productproxyid = xcode.newid(xcnode, "prodprox")
- xcnode.targetproxyid = xcode.newid(xcnode, "targprox")
- xcnode.targetdependid = xcode.newid(xcnode, "targdep")
-
- -- create a grandchild node for the dependency's link target
- local cfg = premake.getconfig(dep, prj.configurations[1])
- node = tree.insert(xcnode, tree.new(cfg.linktarget.name))
- node.path = cfg.linktarget.fullpath
- node.cfg = cfg
- end
-
- if #tr.projects.children > 0 then
- tree.insert(tr, tr.projects)
- end
-
- -- Final setup
- tree.traverse(tr, {
- onnode = function(node)
- -- assign IDs to every node in the tree
- node.id = xcode.newid(node)
-
- -- assign build IDs to buildable files
- if xcode.getbuildcategory(node) then
- node.buildid = xcode.newid(node, "build")
- end
-
- -- remember key files that are needed elsewhere
- if string.endswith(node.name, "Info.plist") then
- tr.infoplist = node
- end
- if string.endswith(node.name, ".entitlements") then
- tr.entitlements = node
- end
- end
- }, true)
-
- -- Plug in the product node into the Products folder in the tree. The node
- -- was built in xcode.preparesolution() in xcode_common.lua; it contains IDs
- -- that are necessary for inter-project dependencies
- node = tree.insert(tr.products, prj.xcode.projectnode)
- node.kind = "product"
- node.path = node.cfg.buildtarget.fullpath
- node.cfgsection = xcode.newid(node, "cfg")
- node.resstageid = xcode.newid(node, "rez")
- node.sourcesid = xcode.newid(node, "src")
- node.fxstageid = xcode.newid(node, "fxs")
-
- return tr
-end
-
-
---
--- Generate an Xcode4 .xcodeproj for a Premake project.
---
--- @param prj
--- The Premake project to generate.
---
-
-function xcode6.project(prj)
- local tr = xcode6.buildprjtree(prj)
-
- xcode6.Header(tr)
- xcode6.PBXProject(tr)
-
- xcode.PBXBuildFile(tr)
- xcode.PBXContainerItemProxy(tr)
- xcode.PBXFileReference(tr,prj)
- xcode.PBXFrameworksBuildPhase(tr)
- xcode.PBXGroup(tr)
- xcode.PBXNativeTarget(tr)
- xcode.PBXReferenceProxy(tr)
- xcode.PBXResourcesBuildPhase(tr)
- xcode.PBXShellScriptBuildPhase(tr)
- xcode.PBXSourcesBuildPhase(tr,prj)
- xcode.PBXVariantGroup(tr)
- xcode.PBXTargetDependency(tr)
- xcode.XCBuildConfiguration(tr)
- xcode.XCBuildConfigurationList(tr)
-
- xcode6.PBXConfigsGroup()
- xcode6.Footer(tr)
-end
-
----------------------------------------------------------------------------
--- Section generator functions, in the same order in which they appear
--- in the .pbxproj file
----------------------------------------------------------------------------
-
-function xcode6.Header()
- _p('// !$*UTF8*$!')
- _p('{')
- _p(1,'archiveVersion = 1;')
- _p(1,'classes = {}')
- _p(1,'objectVersion = 46;')
- _p(1,'rootObject = __RootObject_;')
- _p(1,'objects = {')
-end
-
-function xcode6.PBXProject(tr)
- _p(2,'__RootObject_ = {')
- _p(3,'isa = PBXProject;')
- _p(3,'attributes = {LastUpgradeCheck = 9999;};')
- _p(3,'buildConfigurationList = ___RootConfs_;', tr.name)
- _p(3,'compatibilityVersion = "Xcode 3.2";')
- _p(3,'developmentRegion = English;')
- _p(3,'hasScannedForEncodings = 0;')
- _p(3,'knownRegions = (en);')
- _p(3,'mainGroup = ___RootGroup_;')
- _p(3,'projectDirPath = "";')
- _p(3,'projectRoot = "";')
-
- _p(3,'targets = (')
- for _, node in ipairs(tr.products.children) do
- _p(4,'%s /* %s */,', node.targetid, node.name)
- end
- _p(3,');')
-
- if #tr.projects.children > 0 then
- _p(3,'projectReferences = (')
- for _, node in ipairs(tr.projects.children) do
- _p(4,'{')
- _p(5,'ProductGroup = %s /* Products */;', node.productgroupid)
- _p(5,'ProjectRef = %s /* %s */;', node.id, path.getname(node.path))
- _p(4,'},')
- end
- _p(3,');')
- end
-
- _p(2,'};')
- _p('')
-end
-
-function xcode6.PBXConfigsGroup()
- _p(2, "_____Configs_ = {")
- _p(3, "isa = PBXGroup;")
- _p(3, "children = (")
- -- '__PBXFileRef_SGLMath.xcodeproj/Configs/Project.xcconfig'
- _p(3, ");")
- _p(3, "name = Configs;")
- _p(3, "sourceTree = '<group>';")
- _p(2, "};")
-end
-
-function xcode6.Footer()
- _p(1,'};')
- _p('}')
-end
diff --git a/3rdparty/genie/src/actions/xcode/xcode8.lua b/3rdparty/genie/src/actions/xcode/xcode8.lua
new file mode 100644
index 00000000000..5a658c992fd
--- /dev/null
+++ b/3rdparty/genie/src/actions/xcode/xcode8.lua
@@ -0,0 +1,362 @@
+--
+-- _xcode8.lua
+-- Define the Apple XCode 8.0 action and support functions.
+--
+
+ local premake = premake
+ premake.xcode8 = { }
+
+ local xcode = premake.xcode
+ local xcode8 = premake.xcode8
+
+ function xcode8.XCBuildConfiguration_Target(tr, target, cfg)
+ local cfgname = xcode.getconfigname(cfg)
+ local installpaths = {
+ ConsoleApp = "/usr/local/bin",
+ WindowedApp = "$(HOME)/Applications",
+ SharedLib = "/usr/local/lib",
+ StaticLib = "/usr/local/lib",
+ Bundle = "$(LOCAL_LIBRARY_DIR)/Bundles",
+ }
+
+ -- options table to return
+ local options = {
+ ALWAYS_SEARCH_USER_PATHS = "NO",
+ GCC_DYNAMIC_NO_PIC = "NO",
+ GCC_MODEL_TUNING = "G5",
+ INSTALL_PATH = installpaths[cfg.kind],
+ PRODUCT_NAME = cfg.buildtarget.basename,
+ }
+
+ if not cfg.flags.Symbols then
+ options.DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"
+ end
+
+ if cfg.kind ~= "StaticLib" and cfg.buildtarget.prefix ~= "" then
+ options.EXECUTABLE_PREFIX = cfg.buildtarget.prefix
+ end
+
+ if cfg.targetextension then
+ local ext = cfg.targetextension
+ options.EXECUTABLE_EXTENSION = iif(ext:startswith("."), ext:sub(2), ext)
+ end
+
+ if cfg.flags.ObjcARC then
+ options.CLANG_ENABLE_OBJC_ARC = "YES"
+ end
+
+ local outdir = path.getdirectory(cfg.buildtarget.bundlepath)
+ if outdir ~= "." then
+ options.CONFIGURATION_BUILD_DIR = outdir
+ end
+
+ if tr.infoplist then
+ options.INFOPLIST_FILE = tr.infoplist.cfg.name
+ end
+
+ 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
+ options.INFOPLIST_FILE = infoplist_file
+ end
+
+ local action = premake.action.current()
+ local get_opt = function(opt, def)
+ return (opt and #opt > 0) and opt or def
+ end
+
+ local iosversion = get_opt(cfg.iostargetplatformversion, action.xcode.iOSTargetPlatformVersion)
+ local macosversion = get_opt(cfg.macostargetplatformversion, action.xcode.macOSTargetPlatformVersion)
+ local tvosversion = get_opt(cfg.tvostargetplatformversion, action.xcode.tvOSTargetPlatformVersion)
+
+ if iosversion then
+ options.IPHONEOS_DEPLOYMENT_TARGET = iosversion
+ elseif macosversion then
+ options.MACOSX_DEPLOYMENT_TARGET = macosversion
+ elseif tvosversion then
+ options.TVOS_DEPLOYMENT_TARGET = tvosversion
+ end
+
+ if cfg.kind == "Bundle" and not cfg.options.SkipBundling then
+ options.PRODUCT_BUNDLE_IDENTIFIER = "genie." .. cfg.buildtarget.basename:gsub("%s+", ".") --replace spaces with .
+ local ext = cfg.targetextension
+ if ext then
+ options.WRAPPER_EXTENSION = iif(ext:startswith("."), ext:sub(2), ext)
+ else
+ options.WRAPPER_EXTENSION = "bundle"
+ end
+ end
+
+ return options
+ end
+
+ function xcode8.XCBuildConfiguration_Project(tr, prj, cfg)
+ local cfgname = xcode.getconfigname(cfg)
+ local archs = {
+ Native = nil,
+ x32 = "i386",
+ x64 = "x86_64",
+ Universal32 = "$(ARCHS_STANDARD_32_BIT)",
+ Universal64 = "$(ARCHS_STANDARD_64_BIT)",
+ Universal = "$(ARCHS_STANDARD_32_64_BIT)",
+ }
+
+ -- 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,
+ }
+
+ local cflags = { }
+ for flag, check in pairs(checks) do
+ if check then
+ table.insert(cflags, flag)
+ end
+ end
+
+ -- 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
+ local ldflags = { }
+ for _, lib in ipairs(premake.getlinks(cfg, "system")) do
+ if not xcode.isframework(lib) then
+ table.insert(ldflags, "-l" .. lib)
+ end
+ end
+
+ -- options table to return
+ local options = {
+ ARCHS = archs[cfg.platform],
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = "YES",
+ CLANG_WARN_BOOL_CONVERSION = "YES",
+ CLANG_WARN_CONSTANT_CONVERSION = "YES",
+ CLANG_WARN_EMPTY_BODY = "YES",
+ CLANG_WARN_ENUM_CONVERSION = "YES",
+ CLANG_WARN_INFINITE_RECURSION = "YES",
+ CLANG_WARN_INT_CONVERSION = "YES",
+ CLANG_WARN_SUSPICIOUS_MOVE = "YES",
+ CLANG_WARN_UNREACHABLE_CODE = "YES",
+ CONFIGURATION_TEMP_DIR = "$(OBJROOT)",
+ ENABLE_STRICT_OBJC_MSGSEND = "YES",
+ ENABLE_TESTABILITY = "YES",
+ GCC_C_LANGUAGE_STANDARD = "gnu99",
+ GCC_NO_COMMON_BLOCKS = "YES",
+ GCC_PREPROCESSOR_DEFINITIONS = cfg.defines,
+ GCC_SYMBOLS_PRIVATE_EXTERN = "NO",
+ GCC_WARN_64_TO_32_BIT_CONVERSION = "YES",
+ GCC_WARN_ABOUT_RETURN_TYPE = "YES",
+ GCC_WARN_UNDECLARED_SELECTOR = "YES",
+ GCC_WARN_UNINITIALIZED_AUTOS = "YES",
+ GCC_WARN_UNUSED_FUNCTION = "YES",
+ GCC_WARN_UNUSED_VARIABLE = "YES",
+ HEADER_SEARCH_PATHS = table.join(cfg.includedirs, cfg.systemincludedirs),
+ LIBRARY_SEARCH_PATHS = cfg.libdirs,
+ OBJROOT = cfg.objectsdir,
+ ONLY_ACTIVE_ARCH = "YES",
+ OTHER_CFLAGS = table.join(cflags, cfg.buildoptions, cfg.buildoptions_c),
+ OTHER_CPLUSPLUSFLAGS = table.join(cflags, cfg.buildoptions, cfg.buildoptions_cpp),
+ OTHER_LDFLAGS = table.join(ldflags, cfg.linkoptions),
+ SDKROOT = xcode.toolset,
+ USER_HEADER_SEARCH_PATHS = cfg.userincludedirs,
+ }
+
+ if tr.entitlements then
+ options.CODE_SIGN_ENTITLEMENTS = tr.entitlements.cfg.name
+ end
+
+ local targetdir = path.getdirectory(cfg.buildtarget.bundlepath)
+ if targetdir ~= "." then
+ options.CONFIGURATION_BUILD_DIR = "$(SYMROOT)"
+ options.SYMROOT = targetdir
+ end
+
+ if cfg.flags.Symbols then
+ options.COPY_PHASE_STRIP = "NO"
+ end
+
+ local excluded = xcode.cfg_excluded_files(prj, cfg)
+ if #excluded > 0 then
+ options.EXCLUDED_SOURCE_FILE_NAMES = excluded
+ end
+
+ if cfg.flags.NoExceptions then
+ options.GCC_ENABLE_CPP_EXCEPTIONS = "NO"
+ end
+
+ if cfg.flags.NoRTTI then
+ options.GCC_ENABLE_CPP_RTTI = "NO"
+ end
+
+ if cfg.flags.Symbols and not cfg.flags.NoEditAndContinue then
+ options.GCC_ENABLE_FIX_AND_CONTINUE = "YES"
+ end
+
+ if cfg.flags.NoExceptions then
+ options.GCC_ENABLE_OBJC_EXCEPTIONS = "NO"
+ end
+
+ if cfg.flags.Optimize or cfg.flags.OptimizeSize then
+ options.GCC_OPTIMIZATION_LEVEL = "s"
+ elseif cfg.flags.OptimizeSpeed then
+ options.GCC_OPTIMIZATION_LEVEL = 3
+ else
+ options.GCC_OPTIMIZATION_LEVEL = 0
+ end
+
+ if cfg.pchheader and not cfg.flags.NoPCH then
+ options.GCC_PRECOMPILE_PREFIX_HEADER = "YES"
+
+ -- Visual Studio requires the PCH header to be specified in the same way
+ -- it appears in the #include statements used in the source code; the PCH
+ -- source actual handles the compilation of the header. GCC compiles the
+ -- header file directly, and needs the file's actual file system path in
+ -- order to locate it.
+
+ -- To maximize the compatibility between the two approaches, see if I can
+ -- locate the specified PCH header on one of the include file search paths
+ -- and, if so, adjust the path automatically so the user doesn't have
+ -- add a conditional configuration to the project script.
+
+ local pch = cfg.pchheader
+ for _, incdir in ipairs(cfg.includedirs) do
+
+ -- convert this back to an absolute path for os.isfile()
+ local abspath = path.getabsolute(path.join(cfg.project.location, incdir))
+
+ local testname = path.join(abspath, pch)
+ if os.isfile(testname) then
+ pch = path.getrelative(cfg.location, testname)
+ break
+ end
+ end
+
+ options.GCC_PREFIX_HEADER = pch
+ end
+
+ if cfg.flags.FatalWarnings then
+ options.GCC_TREAT_WARNINGS_AS_ERRORS = "YES"
+ end
+
+ if cfg.kind == "Bundle" then
+ options.MACH_O_TYPE = "mh_bundle"
+ end
+
+ if cfg.flags.StaticRuntime then
+ options.STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = "static"
+ end
+
+ if cfg.flags.PedanticWarnings or cfg.flags.ExtraWarnings then
+ options.WARNING_CFLAGS = "-Wall"
+ end
+
+ if cfg.flags.Cpp11 then
+ options.CLANG_CXX_LANGUAGE_STANDARD = "c++11"
+ elseif cfg.flags.Cpp14 or cfg.flags.CppLatest then
+ options.CLANG_CXX_LANGUAGE_STANDARD = "c++14"
+ elseif cfg.flags.Cpp17 then
+ -- XCode8 does not support C++17, but other actions use this as
+ -- base that *do* support C++17, so check if this is the current
+ -- action before erroring.
+ if premake.action.current() == premake.action.get("xcode8") then
+ error("XCode8 does not support C++17.")
+ end
+ end
+
+ for _, val in ipairs(premake.xcode.parameters) do
+ local eqpos = string.find(val, "=")
+ if eqpos ~= nil then
+ local key = string.trim(string.sub(val, 1, eqpos - 1))
+ local value = string.trim(string.sub(val, eqpos + 1))
+ options[key] = value
+ end
+ end
+
+ return options
+ end
+
+ function xcode8.project(prj)
+ local tr = xcode.buildprjtree(prj)
+ xcode.Header(tr, 48)
+ xcode.PBXBuildFile(tr)
+ xcode.PBXContainerItemProxy(tr)
+ xcode.PBXFileReference(tr,prj)
+ xcode.PBXFrameworksBuildPhase(tr)
+ xcode.PBXGroup(tr)
+ xcode.PBXNativeTarget(tr)
+ xcode.PBXProject(tr, "8.0")
+ xcode.PBXReferenceProxy(tr)
+ xcode.PBXResourcesBuildPhase(tr)
+ xcode.PBXShellScriptBuildPhase(tr)
+ xcode.PBXCopyFilesBuildPhase(tr)
+ xcode.PBXSourcesBuildPhase(tr,prj)
+ xcode.PBXVariantGroup(tr)
+ xcode.PBXTargetDependency(tr)
+ xcode.XCBuildConfiguration(tr, prj, {
+ ontarget = xcode8.XCBuildConfiguration_Target,
+ onproject = xcode8.XCBuildConfiguration_Project,
+ })
+ xcode.XCBuildConfigurationList(tr)
+ xcode.Footer(tr)
+ end
+
+
+--
+-- xcode8 action
+--
+
+ newaction
+ {
+ trigger = "xcode8",
+ shortname = "Xcode 8",
+ description = "Generate Apple Xcode 8 project files",
+ os = "macosx",
+
+ valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Bundle" },
+
+ valid_languages = { "C", "C++" },
+
+ valid_tools = {
+ cc = { "gcc" },
+ },
+
+ valid_platforms = {
+ Native = "Native",
+ x32 = "Native 32-bit",
+ x64 = "Native 64-bit",
+ Universal = "Universal",
+ },
+
+ default_platform = "Native",
+
+ onsolution = function(sln)
+ premake.generate(sln, "%%.xcworkspace/contents.xcworkspacedata", xcode.workspace_generate)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings", xcode.workspace_settings)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/xcschemes/-ALL-.xcscheme", xcode.workspace_scheme)
+ end,
+
+ onproject = function(prj)
+ premake.generate(prj, "%%.xcodeproj/project.pbxproj", xcode8.project)
+ xcode.generate_schemes(prj, "%%.xcodeproj/xcshareddata/xcschemes")
+ end,
+
+ oncleanproject = function(prj)
+ premake.clean.directory(prj, "%%.xcodeproj")
+ premake.clean.directory(prj, "%%.xcworkspace")
+ end,
+
+ oncheckproject = xcode.checkproject,
+
+ xcode = {
+ iOSTargetPlatformVersion = nil,
+ macOSTargetPlatformVersion = nil,
+ tvOSTargetPlatformVersion = nil,
+ },
+ }
diff --git a/3rdparty/genie/src/actions/xcode/xcode9.lua b/3rdparty/genie/src/actions/xcode/xcode9.lua
new file mode 100644
index 00000000000..aa70275bdda
--- /dev/null
+++ b/3rdparty/genie/src/actions/xcode/xcode9.lua
@@ -0,0 +1,107 @@
+--
+-- xcode9.lua
+-- Define the Apple XCode 9.0 action and support functions.
+--
+
+ local premake = premake
+ premake.xcode9 = { }
+
+ local xcode = premake.xcode
+ local xcode8 = premake.xcode8
+ local xcode9 = premake.xcode9
+
+ function xcode9.XCBuildConfiguration_Project(tr, prj, cfg)
+ local options = xcode8.XCBuildConfiguration_Project(tr, prj, cfg)
+
+ if cfg.flags.Cpp17 or cfg.flags.CppLatest then
+ options.CLANG_CXX_LANGUAGE_STANDARD = "c++17"
+ end
+
+ return table.merge(options, {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = "YES",
+ CLANG_WARN_COMMA = "YES",
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = "YES",
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = "YES",
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = "YES",
+ CLANG_WARN_STRICT_PROTOTYPES = "YES",
+ })
+ end
+
+ function xcode9.project(prj)
+ local tr = xcode.buildprjtree(prj)
+ xcode.Header(tr, 48)
+ xcode.PBXBuildFile(tr)
+ xcode.PBXContainerItemProxy(tr)
+ xcode.PBXFileReference(tr,prj)
+ xcode.PBXFrameworksBuildPhase(tr)
+ xcode.PBXGroup(tr)
+ xcode.PBXNativeTarget(tr)
+ xcode.PBXProject(tr, "8.0")
+ xcode.PBXReferenceProxy(tr)
+ xcode.PBXResourcesBuildPhase(tr)
+ xcode.PBXShellScriptBuildPhase(tr)
+ xcode.PBXCopyFilesBuildPhase(tr)
+ xcode.PBXSourcesBuildPhase(tr,prj)
+ xcode.PBXVariantGroup(tr)
+ xcode.PBXTargetDependency(tr)
+ xcode.XCBuildConfiguration(tr, prj, {
+ ontarget = xcode8.XCBuildConfiguration_Target,
+ onproject = xcode9.XCBuildConfiguration_Project,
+ })
+ xcode.XCBuildConfigurationList(tr)
+ xcode.Footer(tr)
+ end
+
+
+--
+-- xcode9 action
+--
+
+ newaction
+ {
+ trigger = "xcode9",
+ shortname = "Xcode 9",
+ description = "Generate Apple Xcode 9 project files",
+ os = "macosx",
+
+ valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Bundle" },
+
+ valid_languages = { "C", "C++" },
+
+ valid_tools = {
+ cc = { "gcc" },
+ },
+
+ valid_platforms = {
+ Native = "Native",
+ x32 = "Native 32-bit",
+ x64 = "Native 64-bit",
+ Universal = "Universal",
+ },
+
+ default_platform = "Native",
+
+ onsolution = function(sln)
+ premake.generate(sln, "%%.xcworkspace/contents.xcworkspacedata", xcode.workspace_generate)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings", xcode.workspace_settings)
+ premake.generate(sln, "%%.xcworkspace/xcshareddata/xcschemes/-ALL-.xcscheme", xcode.workspace_scheme)
+ end,
+
+ onproject = function(prj)
+ premake.generate(prj, "%%.xcodeproj/project.pbxproj", xcode9.project)
+ xcode.generate_schemes(prj, "%%.xcodeproj/xcshareddata/xcschemes")
+ end,
+
+ oncleanproject = function(prj)
+ premake.clean.directory(prj, "%%.xcodeproj")
+ premake.clean.directory(prj, "%%.xcworkspace")
+ end,
+
+ oncheckproject = xcode.checkproject,
+
+ xcode = {
+ iOSTargetPlatformVersion = nil,
+ macOSTargetPlatformVersion = nil,
+ tvOSTargetPlatformVersion = nil,
+ },
+ }
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 <number> [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 <type> <number> [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 = "<group>"
- -- 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('')
diff --git a/3rdparty/genie/src/actions/xcode/xcode_project.lua b/3rdparty/genie/src/actions/xcode/xcode_project.lua
index 5a54d53ff5c..3a461ebdc16 100644
--- a/3rdparty/genie/src/actions/xcode/xcode_project.lua
+++ b/3rdparty/genie/src/actions/xcode/xcode_project.lua
@@ -26,8 +26,8 @@
for _, platform in ipairs(prj.solution.xcode.platforms) do
local cfg = premake.getconfig(prj, cfgname, platform)
cfg.xcode = {}
- cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode, cfgname)
- cfg.xcode.projectid = xcode.newid(tr, cfgname)
+ cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode, "tgt:"..platform..cfgname)
+ cfg.xcode.projectid = xcode.newid(tr, "prj:"..platform..cfgname)
table.insert(tr.configs, cfg)
end
end
@@ -112,6 +112,44 @@
tree.insert(tr, tr.projects)
end
+ -- Add intermediate paths so groups have sensible locations
+
+ -- find common prefixes going up the tree
+ tree.traverse(tr, {
+ onbranchexit = function(node)
+ for _, child in ipairs(node.children) do
+ if (child.location) then
+ if (node.location) then
+ while (not string.startswith(child.location, node.location)) do
+ node.location = path.getdirectory(node.location)
+ end
+ else
+ node.location = path.getdirectory(child.location)
+ end
+ end
+ end
+ end,
+ onleaf = function(node)
+ if (node.cfg) then
+ node.location = node.cfg.name
+ end
+ end
+ }, true)
+
+ -- now convert to relative where possible
+ tree.traverse(tr, {
+ onbranchexit = function(node, depth)
+ if (node.location and node.parent and node.parent.location) then
+ node.location = path.getrelative(node.parent.location, node.location)
+ end
+ end,
+ onleaf = function(node, depth)
+ if (node.location and node.parent and node.parent.location) then
+ node.location = path.getrelative(node.parent.location, node.location)
+ end
+ end
+ }, true)
+
-- Final setup
tree.traverse(tr, {
onnode = function(node)
@@ -146,32 +184,3 @@
return tr
end
-
-
---
--- Generate an Xcode .xcodeproj for a Premake project.
---
--- @param prj
--- The Premake project to generate.
---
-
- function premake.xcode.project(prj)
- local tr = xcode.buildprjtree(prj)
- xcode.Header(tr)
- xcode.PBXBuildFile(tr)
- xcode.PBXContainerItemProxy(tr)
- xcode.PBXFileReference(tr,prj)
- xcode.PBXFrameworksBuildPhase(tr)
- xcode.PBXGroup(tr)
- xcode.PBXNativeTarget(tr)
- xcode.PBXProject(tr)
- xcode.PBXReferenceProxy(tr)
- xcode.PBXResourcesBuildPhase(tr)
- xcode.PBXShellScriptBuildPhase(tr)
- xcode.PBXSourcesBuildPhase(tr,prj)
- xcode.PBXVariantGroup(tr)
- xcode.PBXTargetDependency(tr)
- xcode.XCBuildConfiguration(tr, prj)
- xcode.XCBuildConfigurationList(tr)
- xcode.Footer(tr)
- end
diff --git a/3rdparty/genie/src/actions/xcode/xcode_scheme.lua b/3rdparty/genie/src/actions/xcode/xcode_scheme.lua
new file mode 100644
index 00000000000..662582e2afb
--- /dev/null
+++ b/3rdparty/genie/src/actions/xcode/xcode_scheme.lua
@@ -0,0 +1,239 @@
+--
+-- xcode_scheme.lua
+--
+
+local premake = premake
+local xcode = premake.xcode
+
+
+--
+-- Print a BuildableReference element.
+--
+
+ local function buildableref(indent, prj, cfg)
+ cfg = cfg or premake.eachconfig(prj)()
+
+ _p(indent + 0, '<BuildableReference')
+ _p(indent + 1, 'BuildableIdentifier = "primary"')
+ _p(indent + 1, 'BlueprintIdentifier = "%s"', prj.xcode.projectnode.targetid)
+ _p(indent + 1, 'BuildableName = "%s"', cfg.buildtarget.name)
+ _p(indent + 1, 'BlueprintName = "%s"', prj.name)
+ _p(indent + 1, 'ReferencedContainer = "container:%s.xcodeproj">', prj.name)
+ _p(indent + 0, '</BuildableReference>')
+ end
+
+
+--
+-- Print a CommandLineArgs element, if needed by the provided config.
+--
+
+ local function cmdlineargs(indent, cfg)
+ if #cfg.debugargs > 0 then
+ _p(indent, '<CommandLineArguments>')
+ for _, arg in ipairs(cfg.debugargs) do
+ _p(indent + 1, '<CommandLineArgument')
+ _p(indent + 2, 'argument = "%s"', arg)
+ _p(indent + 2, 'isEnabled = "YES">')
+ _p(indent + 1, '</CommandLineArgument>')
+ end
+ _p(indent, '</CommandLineArguments>')
+ end
+ end
+
+
+--
+-- Print an EnvironmentVariables element, if needed by the provided config.
+
+ local function envvars(indent, cfg)
+ if #cfg.debugenvs > 0 then
+ _p(indent, '<EnvironmentVariables>')
+ for _, arg in ipairs(cfg.debugenvs) do
+ local eq = arg:find("=")
+ local k = arg:sub(1, eq)
+ local v = arg:sub(eq + 1)
+ _p(indent + 1, '<EnvironmentVariable')
+ _p(indent + 2, 'key = "%s"', arg:sub(1, eq))
+ _p(indent + 2, 'value = "%s"', arg:sub(eq))
+ _p(indent + 2, 'isEnabled = "YES">')
+ _p(indent + 1, '</EnvironmentVariable>')
+ end
+ _p(indent, '</EnvironmentVariables>')
+ end
+ end
+
+
+--
+-- Generate the customWorkingDir path from the given dir.
+--
+
+ local function workingdir(dir)
+ if not path.isabsolute(dir) then
+ dir = "$PROJECT_DIR/" .. dir
+ end
+ return dir
+ end
+
+
+--
+-- Determine the best matching configuration.
+--
+-- @param fordebug
+-- True to find a debug configuration.
+--
+
+ local function bestconfig(prj, fordebug)
+ local bestcfg = nil
+ local bestscore = -1
+
+ for cfg in premake.eachconfig(prj) do
+ local score = 0
+
+ if cfg.platform == "Native" then
+ score = score + 10
+ end
+
+ if fordebug and cfg.name == "Debug" then
+ score = score + 1
+ end
+
+ if not fordebug and cfg.name == "Release" then
+ score = score + 1
+ end
+
+ if score > bestscore then
+ bestcfg = cfg
+ bestscore = score
+ end
+ end
+
+ return bestcfg
+ end
+
+
+--
+-- Print out an xcscheme file.
+--
+-- @param tobuild
+-- The list of targets to build. Assumed to be sorted.
+-- @param primary
+-- The target to set as test/profile/launch target.
+--
+
+ function xcode.scheme(tobuild, primary, schemecfg)
+ _p('<?xml version="1.0" encoding="UTF-8"?>')
+ _p('<Scheme')
+ _p(1, 'LastUpgradeVersion = "0940"')
+ _p(1, 'version = "1.3">')
+ _p(1, '<BuildAction')
+ _p(2, 'parallelizeBuildables = "YES"')
+ _p(2, 'buildImplicitDependencies = "YES">')
+ _p(2, '<BuildActionEntries>')
+
+ for _, prj in ipairs(tobuild) do
+ _p(3, '<BuildActionEntry')
+ _p(4, 'buildForTesting = "YES"')
+ _p(4, 'buildForRunning = "YES"')
+ _p(4, 'buildForProfiling = "YES"')
+ _p(4, 'buildForArchiving = "YES"')
+ _p(4, 'buildForAnalyzing = "YES">')
+ buildableref(4, prj)
+ _p(3, '</BuildActionEntry>')
+ end
+
+ local debugcfg = schemecfg or bestconfig(primary, true)
+ local releasecfg = schemecfg or bestconfig(primary, false)
+ local debugname = xcode.getconfigname(debugcfg)
+ local releasename = xcode.getconfigname(releasecfg)
+
+ _p(2, '</BuildActionEntries>')
+ _p(1, '</BuildAction>')
+ _p(1, '<TestAction')
+ _p(2, 'buildConfiguration = "%s"', debugname)
+ _p(2, 'selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"')
+ _p(2, 'selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"')
+ _p(2, 'shouldUseLaunchSchemeArgsEnv = "YES">')
+ _p(2, '<Testables>')
+ _p(2, '</Testables>')
+ _p(2, '<MacroExpansion>')
+ buildableref(3, primary, debugcfg)
+ _p(2, '</MacroExpansion>')
+ _p(2, '<AdditionalOptions>')
+ _p(2, '</AdditionalOptions>')
+ _p(1, '</TestAction>')
+ _p(1, '<LaunchAction')
+ _p(2, 'buildConfiguration = "%s"', debugname)
+ _p(2, 'selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"')
+ _p(2, 'selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"')
+ _p(2, 'launchStyle = "0"')
+ if debugcfg.debugdir then
+ _p(2, 'useCustomWorkingDirectory = "YES"')
+ _p(2, 'customWorkingDirectory = "%s"', workingdir(debugcfg.debugdir))
+ else
+ _p(2, 'useCustomWorkingDirectory = "NO"')
+ end
+ _p(2, 'ignoresPersistentStateOnLaunch = "NO"')
+ _p(2, 'debugDocumentVersioning = "YES"')
+ _p(2, 'debugServiceExtension = "internal"')
+ _p(2, 'allowLocationSimulation = "YES">')
+ if debugcfg.debugcmd then
+ _p(2, '<PathRunnable')
+ _p(3, 'runnableDebuggingMode = "0"')
+ _p(3, 'FilePath = "%s">', debugcfg.debugcmd)
+ _p(2, '</PathRunnable>')
+ else
+ _p(2, '<BuildableProductRunnable')
+ _p(3, 'runnableDebuggingMode = "0">')
+ buildableref(3, primary, debugcfg)
+ _p(2, '</BuildableProductRunnable>')
+ end
+ cmdlineargs(2, debugcfg)
+ envvars(2, debugcfg)
+ _p(2, '<AdditionalOptions>')
+ _p(2, '</AdditionalOptions>')
+ _p(1, '</LaunchAction>')
+ _p(1, '<ProfileAction')
+ _p(2, 'buildConfiguration = "%s"', releasename)
+ _p(2, 'shouldUseLaunchSchemeArgsEnv = "YES"')
+ _p(2, 'savedToolIdentifier = ""')
+ if releasecfg.debugdir then
+ _p(2, 'useCustomWorkingDirectory = "YES"')
+ _p(2, 'customWorkingDirectory = "%s"', workingdir(releasecfg.debugdir))
+ else
+ _p(2, 'useCustomWorkingDirectory = "NO"')
+ end
+ _p(2, 'debugDocumentVersioning = "YES">')
+ _p(2, '<BuildableProductRunnable')
+ _p(3, 'runnableDebuggingMode = "0">')
+ buildableref(3, primary, releasecfg)
+ _p(2, '</BuildableProductRunnable>')
+ cmdlineargs(2, releasecfg)
+ envvars(2, releasecfg)
+ _p(1, '</ProfileAction>')
+ _p(1, '<AnalyzeAction')
+ _p(2, 'buildConfiguration = "%s">', debugname)
+ _p(1, '</AnalyzeAction>')
+ _p(1, '<ArchiveAction')
+ _p(2, 'buildConfiguration = "%s"', releasename)
+ _p(2, 'revealArchiveInOrganizer = "YES">')
+ _p(1, '</ArchiveAction>')
+ _p('</Scheme>')
+ end
+
+--
+-- Generate XCode schemes for the given project.
+--
+
+ function xcode.generate_schemes(prj, base_path)
+ if (prj.kind == "ConsoleApp" or prj.kind == "WindowedApp") or (prj.options and prj.options.XcodeLibrarySchemes) then
+
+ if prj.options and prj.options.XcodeSchemeNoConfigs then
+ premake.generate(prj, path.join(base_path, "%%.xcscheme"),
+ function(prj) xcode.scheme({prj}, prj) end)
+ else
+ for cfg in premake.eachconfig(prj) do
+ premake.generate(prj, path.join(base_path, "%% " .. cfg.name .. ".xcscheme"),
+ function(prj) xcode.scheme({prj}, prj, cfg) end)
+ end
+ end
+ end
+ end
diff --git a/3rdparty/genie/src/actions/xcode/xcode_workspace.lua b/3rdparty/genie/src/actions/xcode/xcode_workspace.lua
new file mode 100644
index 00000000000..ed0542258e7
--- /dev/null
+++ b/3rdparty/genie/src/actions/xcode/xcode_workspace.lua
@@ -0,0 +1,145 @@
+local premake = premake
+local xcode = premake.xcode
+
+xcode.allscheme = false
+
+function xcode.workspace_head()
+ _p('<?xml version="1.0" encoding="UTF-8"?>')
+ _p('<Workspace')
+ _p(1,'version = "1.0">')
+end
+
+function xcode.workspace_tail()
+ _p('</Workspace>')
+end
+
+function xcode.workspace_file_ref(prj, indent)
+ local projpath = path.getrelative(prj.solution.location, prj.location)
+ if projpath == '.' then projpath = ''
+ else projpath = projpath ..'/'
+ end
+ _p(indent, '<FileRef')
+ _p(indent + 1, 'location = "group:%s">', projpath .. prj.name .. '.xcodeproj')
+ _p(indent, '</FileRef>')
+end
+
+function xcode.workspace_group(grp, indent)
+ _p(indent, '<Group')
+ _p(indent + 1, 'location = "container:"')
+ _p(indent + 1, 'name = "%s">', grp.name)
+
+ local function comparenames(a, b)
+ return a.name < b.name
+ end
+
+ local groups = table.join(grp.groups)
+ local projects = table.join(grp.projects)
+ table.sort(groups, comparenames)
+ table.sort(projects, comparenames)
+
+ for _, child in ipairs(groups) do
+ xcode.workspace_group(child, indent + 1)
+ end
+
+ for _, prj in ipairs(projects) do
+ xcode.workspace_file_ref(prj, indent + 1)
+ end
+
+ _p(indent, '</Group>')
+end
+
+function xcode.workspace_generate(sln)
+ xcode.preparesolution(sln)
+ xcode.workspace_head()
+ xcode.reorderProjects(sln)
+
+ for grp in premake.solution.eachgroup(sln) do
+ if grp.parent == nil then
+ xcode.workspace_group(grp, 1)
+ end
+ end
+
+ for prj in premake.solution.eachproject(sln) do
+ if prj.group == nil then
+ xcode.workspace_file_ref(prj, 1)
+ end
+ end
+
+ xcode.workspace_tail()
+end
+
+
+--
+-- Generate the `-ALL` scheme, building all targets.
+--
+
+function xcode.workspace_scheme(sln)
+ if not xcode.allscheme then
+ return false
+ end
+
+ local projects = {}
+ local primary = nil
+
+ for prj in premake.solution.eachproject(sln) do
+ if not primary or (sln.startproject == prj.name) then
+ primary = prj
+ end
+ table.insert(projects, prj)
+ end
+
+ xcode.scheme(projects, primary)
+end
+
+--
+-- Generate the workspace settings file, preventing xcode from auto-generating
+-- schemes we have manually provided.
+--
+
+function xcode.workspace_settings(sln)
+ _p('<?xml version="1.0" encoding="UTF-8"?>')
+ _p('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">')
+ _p('<plist version="1.0">')
+ _p('<dict>')
+ _p(1, '<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>')
+ _p(1, '<false/>')
+ _p('</dict>')
+ _p('</plist>')
+end
+
+--
+-- If a startup project is specified, move it to the front of the project list.
+-- This will make Visual Studio treat it like a startup project.
+--
+
+function xcode.reorderProjects(sln)
+ if sln.startproject then
+ for i, prj in ipairs(sln.projects) do
+ if sln.startproject == prj.name then
+ -- Move group tree containing the project to start of group list
+ local cur = prj.group
+ while cur ~= nil do
+ -- Remove group from array
+ for j, group in ipairs(sln.groups) do
+ if group == cur then
+ table.remove(sln.groups, j)
+ break
+ end
+ end
+
+ -- Add back at start
+ table.insert(sln.groups, 1, cur)
+ cur = cur.parent
+ end
+ -- Move the project itself to start
+ table.remove(sln.projects, i)
+ table.insert(sln.projects, 1, prj)
+ break
+ end
+ end
+ end
+end
+
+
+
+