mirror of https://gitlab.com/ita1024/waf.git
Xcode 6 generator fixes #1939
This commit is contained in:
parent
942f9a14d9
commit
059939ef60
|
@ -8,14 +8,23 @@ APPNAME = 'TestProject'
|
||||||
VERSION = '1.0'
|
VERSION = '1.0'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
To create the xcode project files:
|
||||||
|
waf configure xcode6
|
||||||
|
|
||||||
|
To configure and build using Waf:
|
||||||
|
waf configure build
|
||||||
|
|
||||||
This demo will create an XCode project containing
|
This demo will create an XCode project containing
|
||||||
an App bundle target, a dynamic library target,
|
an App bundle target, a dynamic library target,
|
||||||
a static library target and an executable target.
|
a static library target and an executable target.
|
||||||
The generated XCode project can then be opened
|
The generated XCode project can then be opened
|
||||||
and XCode can then build those targets.
|
and XCode can then build those targets.
|
||||||
Tested in XCode 6 & 7.
|
Tested with XCode 8.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def options(opt):
|
||||||
|
opt.load('compiler_cxx xcode6')
|
||||||
|
|
||||||
def configure(conf):
|
def configure(conf):
|
||||||
|
|
||||||
# Use environment variables to set default project configuration
|
# Use environment variables to set default project configuration
|
||||||
|
@ -31,14 +40,15 @@ def configure(conf):
|
||||||
conf.write_config_header('config.h')
|
conf.write_config_header('config.h')
|
||||||
|
|
||||||
# This must be called at the end of configure()
|
# This must be called at the end of configure()
|
||||||
conf.load('xcode6')
|
conf.load('compiler_cxx xcode6')
|
||||||
|
|
||||||
|
conf.check(cxxflags='-std=c++11', uselib_store='STD11', mandatory=False)
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
bld.load('xcode6')
|
|
||||||
tg = bld.framework(
|
tg = bld.framework(
|
||||||
includes='include',
|
includes='include',
|
||||||
|
|
||||||
# Specify source files.
|
# Specify source files for xcode
|
||||||
# This will become the groups (folders) inside XCode.
|
# This will become the groups (folders) inside XCode.
|
||||||
# Give a dictionary to group by name. Use a list to add everything in one
|
# Give a dictionary to group by name. Use a list to add everything in one
|
||||||
source_files={
|
source_files={
|
||||||
|
@ -46,6 +56,9 @@ def build(bld):
|
||||||
'Include': bld.path.ant_glob(incl=['include/MyLib/*.h', 'include'], dir=True)
|
'Include': bld.path.ant_glob(incl=['include/MyLib/*.h', 'include'], dir=True)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# source files for waf builds
|
||||||
|
source=bld.path.ant_glob('src/MyLib/*.cpp'),
|
||||||
|
|
||||||
# export_headers will put the files in the
|
# export_headers will put the files in the
|
||||||
# 'Header Build Phase' in Xcode - i.e tell XCode to ship them with your .framework
|
# 'Header Build Phase' in Xcode - i.e tell XCode to ship them with your .framework
|
||||||
export_headers=bld.path.ant_glob(incl=['include/MyLib/*.h', 'include/MyLib/SupportLib'], dir=True),
|
export_headers=bld.path.ant_glob(incl=['include/MyLib/*.h', 'include/MyLib/SupportLib'], dir=True),
|
||||||
|
@ -53,10 +66,28 @@ def build(bld):
|
||||||
install='~/Library/Frameworks'
|
install='~/Library/Frameworks'
|
||||||
)
|
)
|
||||||
|
|
||||||
bld.env.LIB_SDL2 = '/Library/Frameworks/SDL2.framework/SDL2'
|
bld.stlib(
|
||||||
|
source=bld.path.ant_glob('src/MyLib/*.cpp'),
|
||||||
|
includes = 'include',
|
||||||
|
target='MyStaticLib',
|
||||||
|
)
|
||||||
|
|
||||||
|
bld.program(
|
||||||
|
source=['src/test.cpp'],
|
||||||
|
includes='include',
|
||||||
|
target='MyExe',
|
||||||
|
use='MyDynLib'
|
||||||
|
)
|
||||||
|
bld.shlib(
|
||||||
|
source=bld.path.ant_glob('src/MyLib/*.cpp'),
|
||||||
|
includes='include',
|
||||||
|
target='MyDynLib',
|
||||||
|
)
|
||||||
|
|
||||||
|
#bld.env.LIB_SDL2 = '/Library/Frameworks/SDL2.framework/SDL2'
|
||||||
tg2 = bld.app(
|
tg2 = bld.app(
|
||||||
source_files=bld.path.ant_glob('src/*.cpp'),
|
source=bld.path.ant_glob('src/*.cpp'),
|
||||||
includes=tg.includes,
|
includes='include',
|
||||||
target='MyApp',
|
target='MyApp',
|
||||||
use='MyLib',
|
use='MyLib',
|
||||||
uselib='SDL2',
|
uselib='SDL2',
|
||||||
|
@ -66,22 +97,4 @@ def build(bld):
|
||||||
settings={"Debug": {"CONFIG_NAME": 'Debug'}}
|
settings={"Debug": {"CONFIG_NAME": 'Debug'}}
|
||||||
)
|
)
|
||||||
|
|
||||||
bld.dylib(
|
|
||||||
source_files=bld.path.ant_glob('src/MyLib/*.cpp'),
|
|
||||||
includes=tg.includes,
|
|
||||||
target='MyDynLib',
|
|
||||||
)
|
|
||||||
|
|
||||||
bld.program(
|
|
||||||
source_files=['src/test.cpp'],
|
|
||||||
includes=tg.includes,
|
|
||||||
target='MyExe',
|
|
||||||
use='MyDynLib'
|
|
||||||
)
|
|
||||||
|
|
||||||
bld.stlib(
|
|
||||||
source_files=bld.path.ant_glob('src/MyLib/*.cpp'),
|
|
||||||
includes=tg.includes,
|
|
||||||
target='MyStaticLib',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
@ -1,312 +0,0 @@
|
||||||
#! /usr/bin/env python
|
|
||||||
# encoding: utf-8
|
|
||||||
# XCode 3/XCode 4 generator for Waf
|
|
||||||
# Nicolas Mercier 2011
|
|
||||||
|
|
||||||
"""
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
def options(opt):
|
|
||||||
opt.load('xcode')
|
|
||||||
|
|
||||||
$ waf configure xcode
|
|
||||||
"""
|
|
||||||
|
|
||||||
# TODO: support iOS projects
|
|
||||||
|
|
||||||
from waflib import Context, TaskGen, Build, Utils
|
|
||||||
import os, sys
|
|
||||||
|
|
||||||
HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
|
|
||||||
|
|
||||||
MAP_EXT = {
|
|
||||||
'.h' : "sourcecode.c.h",
|
|
||||||
|
|
||||||
'.hh': "sourcecode.cpp.h",
|
|
||||||
'.inl': "sourcecode.cpp.h",
|
|
||||||
'.hpp': "sourcecode.cpp.h",
|
|
||||||
|
|
||||||
'.c': "sourcecode.c.c",
|
|
||||||
|
|
||||||
'.m': "sourcecode.c.objc",
|
|
||||||
|
|
||||||
'.mm': "sourcecode.cpp.objcpp",
|
|
||||||
|
|
||||||
'.cc': "sourcecode.cpp.cpp",
|
|
||||||
|
|
||||||
'.cpp': "sourcecode.cpp.cpp",
|
|
||||||
'.C': "sourcecode.cpp.cpp",
|
|
||||||
'.cxx': "sourcecode.cpp.cpp",
|
|
||||||
'.c++': "sourcecode.cpp.cpp",
|
|
||||||
|
|
||||||
'.l': "sourcecode.lex", # luthor
|
|
||||||
'.ll': "sourcecode.lex",
|
|
||||||
|
|
||||||
'.y': "sourcecode.yacc",
|
|
||||||
'.yy': "sourcecode.yacc",
|
|
||||||
|
|
||||||
'.plist': "text.plist.xml",
|
|
||||||
".nib": "wrapper.nib",
|
|
||||||
".xib": "text.xib",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
part1 = 0
|
|
||||||
part2 = 10000
|
|
||||||
part3 = 0
|
|
||||||
id = 562000999
|
|
||||||
def newid():
|
|
||||||
global id
|
|
||||||
id += 1
|
|
||||||
return "%04X%04X%04X%012d" % (0, 10000, 0, id)
|
|
||||||
|
|
||||||
class XCodeNode:
|
|
||||||
def __init__(self):
|
|
||||||
self._id = newid()
|
|
||||||
|
|
||||||
def tostring(self, value):
|
|
||||||
if isinstance(value, dict):
|
|
||||||
result = "{\n"
|
|
||||||
for k,v in value.items():
|
|
||||||
result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v))
|
|
||||||
result = result + "\t\t}"
|
|
||||||
return result
|
|
||||||
elif isinstance(value, str):
|
|
||||||
return "\"%s\"" % value
|
|
||||||
elif isinstance(value, list):
|
|
||||||
result = "(\n"
|
|
||||||
for i in value:
|
|
||||||
result = result + "\t\t\t%s,\n" % self.tostring(i)
|
|
||||||
result = result + "\t\t)"
|
|
||||||
return result
|
|
||||||
elif isinstance(value, XCodeNode):
|
|
||||||
return value._id
|
|
||||||
else:
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
def write_recursive(self, value, file):
|
|
||||||
if isinstance(value, dict):
|
|
||||||
for k,v in value.items():
|
|
||||||
self.write_recursive(v, file)
|
|
||||||
elif isinstance(value, list):
|
|
||||||
for i in value:
|
|
||||||
self.write_recursive(i, file)
|
|
||||||
elif isinstance(value, XCodeNode):
|
|
||||||
value.write(file)
|
|
||||||
|
|
||||||
def write(self, file):
|
|
||||||
for attribute,value in self.__dict__.items():
|
|
||||||
if attribute[0] != '_':
|
|
||||||
self.write_recursive(value, file)
|
|
||||||
|
|
||||||
w = file.write
|
|
||||||
w("\t%s = {\n" % self._id)
|
|
||||||
w("\t\tisa = %s;\n" % self.__class__.__name__)
|
|
||||||
for attribute,value in self.__dict__.items():
|
|
||||||
if attribute[0] != '_':
|
|
||||||
w("\t\t%s = %s;\n" % (attribute, self.tostring(value)))
|
|
||||||
w("\t};\n\n")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Configurations
|
|
||||||
class XCBuildConfiguration(XCodeNode):
|
|
||||||
def __init__(self, name, settings = {}, env=None):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.baseConfigurationReference = ""
|
|
||||||
self.buildSettings = settings
|
|
||||||
self.name = name
|
|
||||||
if env and env.ARCH:
|
|
||||||
settings['ARCHS'] = " ".join(env.ARCH)
|
|
||||||
|
|
||||||
|
|
||||||
class XCConfigurationList(XCodeNode):
|
|
||||||
def __init__(self, settings):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.buildConfigurations = settings
|
|
||||||
self.defaultConfigurationIsVisible = 0
|
|
||||||
self.defaultConfigurationName = settings and settings[0].name or ""
|
|
||||||
|
|
||||||
# Group/Files
|
|
||||||
class PBXFileReference(XCodeNode):
|
|
||||||
def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.fileEncoding = 4
|
|
||||||
if not filetype:
|
|
||||||
_, ext = os.path.splitext(name)
|
|
||||||
filetype = MAP_EXT.get(ext, 'text')
|
|
||||||
self.lastKnownFileType = filetype
|
|
||||||
self.name = name
|
|
||||||
self.path = path
|
|
||||||
self.sourceTree = sourcetree
|
|
||||||
|
|
||||||
class PBXGroup(XCodeNode):
|
|
||||||
def __init__(self, name, sourcetree = "<group>"):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.children = []
|
|
||||||
self.name = name
|
|
||||||
self.sourceTree = sourcetree
|
|
||||||
|
|
||||||
def add(self, root, sources):
|
|
||||||
folders = {}
|
|
||||||
def folder(n):
|
|
||||||
if not n.is_child_of(root):
|
|
||||||
return self
|
|
||||||
try:
|
|
||||||
return folders[n]
|
|
||||||
except KeyError:
|
|
||||||
f = PBXGroup(n.name)
|
|
||||||
p = folder(n.parent)
|
|
||||||
folders[n] = f
|
|
||||||
p.children.append(f)
|
|
||||||
return f
|
|
||||||
for s in sources:
|
|
||||||
f = folder(s.parent)
|
|
||||||
source = PBXFileReference(s.name, s.abspath())
|
|
||||||
f.children.append(source)
|
|
||||||
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
class PBXLegacyTarget(XCodeNode):
|
|
||||||
def __init__(self, action, target=''):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})])
|
|
||||||
if not target:
|
|
||||||
self.buildArgumentsString = "%s %s" % (sys.argv[0], action)
|
|
||||||
else:
|
|
||||||
self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target)
|
|
||||||
self.buildPhases = []
|
|
||||||
self.buildToolPath = sys.executable
|
|
||||||
self.buildWorkingDirectory = ""
|
|
||||||
self.dependencies = []
|
|
||||||
self.name = target or action
|
|
||||||
self.productName = target or action
|
|
||||||
self.passBuildSettingsInEnvironment = 0
|
|
||||||
|
|
||||||
class PBXShellScriptBuildPhase(XCodeNode):
|
|
||||||
def __init__(self, action, target):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.buildActionMask = 2147483647
|
|
||||||
self.files = []
|
|
||||||
self.inputPaths = []
|
|
||||||
self.outputPaths = []
|
|
||||||
self.runOnlyForDeploymentPostProcessing = 0
|
|
||||||
self.shellPath = "/bin/sh"
|
|
||||||
self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target)
|
|
||||||
|
|
||||||
class PBXNativeTarget(XCodeNode):
|
|
||||||
def __init__(self, action, target, node, env):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
conf = XCBuildConfiguration('waf', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env)
|
|
||||||
self.buildConfigurationList = XCConfigurationList([conf])
|
|
||||||
self.buildPhases = [PBXShellScriptBuildPhase(action, target)]
|
|
||||||
self.buildRules = []
|
|
||||||
self.dependencies = []
|
|
||||||
self.name = target
|
|
||||||
self.productName = target
|
|
||||||
self.productType = "com.apple.product-type.application"
|
|
||||||
self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'BUILT_PRODUCTS_DIR')
|
|
||||||
|
|
||||||
# Root project object
|
|
||||||
class PBXProject(XCodeNode):
|
|
||||||
def __init__(self, name, version):
|
|
||||||
XCodeNode.__init__(self)
|
|
||||||
self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})])
|
|
||||||
self.compatibilityVersion = version[0]
|
|
||||||
self.hasScannedForEncodings = 1
|
|
||||||
self.mainGroup = PBXGroup(name)
|
|
||||||
self.projectRoot = ""
|
|
||||||
self.projectDirPath = ""
|
|
||||||
self.targets = []
|
|
||||||
self._objectVersion = version[1]
|
|
||||||
self._output = PBXGroup('out')
|
|
||||||
self.mainGroup.children.append(self._output)
|
|
||||||
|
|
||||||
def write(self, file):
|
|
||||||
w = file.write
|
|
||||||
w("// !$*UTF8*$!\n")
|
|
||||||
w("{\n")
|
|
||||||
w("\tarchiveVersion = 1;\n")
|
|
||||||
w("\tclasses = {\n")
|
|
||||||
w("\t};\n")
|
|
||||||
w("\tobjectVersion = %d;\n" % self._objectVersion)
|
|
||||||
w("\tobjects = {\n\n")
|
|
||||||
|
|
||||||
XCodeNode.write(self, file)
|
|
||||||
|
|
||||||
w("\t};\n")
|
|
||||||
w("\trootObject = %s;\n" % self._id)
|
|
||||||
w("}\n")
|
|
||||||
|
|
||||||
def add_task_gen(self, tg):
|
|
||||||
if not getattr(tg, 'mac_app', False):
|
|
||||||
self.targets.append(PBXLegacyTarget('build', tg.name))
|
|
||||||
else:
|
|
||||||
target = PBXNativeTarget('build', tg.name, tg.link_task.outputs[0].change_ext('.app'), tg.env)
|
|
||||||
self.targets.append(target)
|
|
||||||
self._output.children.append(target.productReference)
|
|
||||||
|
|
||||||
class xcode(Build.BuildContext):
|
|
||||||
cmd = 'xcode'
|
|
||||||
fun = 'build'
|
|
||||||
|
|
||||||
def collect_source(self, tg):
|
|
||||||
source_files = tg.to_nodes(getattr(tg, 'source', []))
|
|
||||||
plist_files = tg.to_nodes(getattr(tg, 'mac_plist', []))
|
|
||||||
resource_files = [tg.path.find_node(i) for i in Utils.to_list(getattr(tg, 'mac_resources', []))]
|
|
||||||
include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + Utils.to_list(getattr(tg, 'export_dirs', []))
|
|
||||||
include_files = []
|
|
||||||
for x in include_dirs:
|
|
||||||
if not isinstance(x, str):
|
|
||||||
include_files.append(x)
|
|
||||||
continue
|
|
||||||
d = tg.path.find_node(x)
|
|
||||||
if d:
|
|
||||||
lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)]
|
|
||||||
include_files.extend(lst)
|
|
||||||
|
|
||||||
# remove duplicates
|
|
||||||
source = list(set(source_files + plist_files + resource_files + include_files))
|
|
||||||
source.sort(key=lambda x: x.abspath())
|
|
||||||
return source
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
"""
|
|
||||||
Entry point
|
|
||||||
"""
|
|
||||||
self.restore()
|
|
||||||
if not self.all_envs:
|
|
||||||
self.load_envs()
|
|
||||||
self.recurse([self.run_dir])
|
|
||||||
|
|
||||||
appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath()))
|
|
||||||
p = PBXProject(appname, ('Xcode 3.2', 46))
|
|
||||||
|
|
||||||
for g in self.groups:
|
|
||||||
for tg in g:
|
|
||||||
if not isinstance(tg, TaskGen.task_gen):
|
|
||||||
continue
|
|
||||||
|
|
||||||
tg.post()
|
|
||||||
|
|
||||||
features = Utils.to_list(getattr(tg, 'features', ''))
|
|
||||||
|
|
||||||
group = PBXGroup(tg.name)
|
|
||||||
group.add(tg.path, self.collect_source(tg))
|
|
||||||
p.mainGroup.children.append(group)
|
|
||||||
|
|
||||||
if ('cprogram' in features) or ('cxxprogram' in features):
|
|
||||||
p.add_task_gen(tg)
|
|
||||||
|
|
||||||
|
|
||||||
# targets that don't produce the executable but that you might want to run
|
|
||||||
p.targets.append(PBXLegacyTarget('configure'))
|
|
||||||
p.targets.append(PBXLegacyTarget('dist'))
|
|
||||||
p.targets.append(PBXLegacyTarget('install'))
|
|
||||||
p.targets.append(PBXLegacyTarget('check'))
|
|
||||||
node = self.srcnode.make_node('%s.xcodeproj' % appname)
|
|
||||||
node.mkdir()
|
|
||||||
node = node.make_node('project.pbxproj')
|
|
||||||
p.write(open(node.abspath(), 'w'))
|
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,9 @@ Usage:
|
||||||
See also demos/xcode6/ folder
|
See also demos/xcode6/ folder
|
||||||
|
|
||||||
def options(opt):
|
def options(opt):
|
||||||
opt.load('xcode6')
|
opt.load('compiler_cxx xcode6')
|
||||||
|
|
||||||
def configure(cnf):
|
def configure(cnf):
|
||||||
# <do your stuff>
|
|
||||||
|
|
||||||
# For example
|
# For example
|
||||||
cnf.env.SDKROOT = 'macosx10.9'
|
cnf.env.SDKROOT = 'macosx10.9'
|
||||||
|
|
||||||
|
@ -31,13 +29,13 @@ def configure(cnf):
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# In the end of configure() do
|
# In the end of configure() do
|
||||||
cnf.load('xcode6')
|
cnf.load('compiler_cxx xcode6')
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
|
|
||||||
# Make a Framework target
|
# Make a Framework target
|
||||||
bld.framework(
|
bld.framework(
|
||||||
source_files={
|
source={
|
||||||
'Include': bld.path.ant_glob('include/MyLib/*.h'),
|
'Include': bld.path.ant_glob('include/MyLib/*.h'),
|
||||||
'Source': bld.path.ant_glob('src/MyLib/*.cpp')
|
'Source': bld.path.ant_glob('src/MyLib/*.cpp')
|
||||||
},
|
},
|
||||||
|
@ -45,7 +43,6 @@ def build(bld):
|
||||||
export_headers=bld.path.ant_glob('include/MyLib/*.h'),
|
export_headers=bld.path.ant_glob('include/MyLib/*.h'),
|
||||||
target='MyLib',
|
target='MyLib',
|
||||||
)
|
)
|
||||||
|
|
||||||
# You can also make bld.dylib, bld.app, bld.stlib ...
|
# You can also make bld.dylib, bld.app, bld.stlib ...
|
||||||
|
|
||||||
# To generate your XCode project, open the folder with the wscript
|
# To generate your XCode project, open the folder with the wscript
|
||||||
|
@ -53,11 +50,14 @@ def build(bld):
|
||||||
# $ waf configure xcode6
|
# $ waf configure xcode6
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: support iOS projects
|
# TODO: support iOS projects(?)
|
||||||
|
|
||||||
from waflib import Context, TaskGen, Build, Utils, Errors, Logs
|
from waflib import Context, TaskGen, Build, Utils, Errors, Logs
|
||||||
import os, sys
|
import os, sys
|
||||||
|
|
||||||
|
# FIXME too few extensions
|
||||||
|
XCODE_EXTS = ['.c', '.cpp', '.m', '.mm']
|
||||||
|
|
||||||
HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
|
HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
|
||||||
|
|
||||||
MAP_EXT = {
|
MAP_EXT = {
|
||||||
|
@ -262,6 +262,7 @@ class PBXFileReference(XCodeNode):
|
||||||
_, ext = os.path.splitext(name)
|
_, ext = os.path.splitext(name)
|
||||||
filetype = MAP_EXT.get(ext, 'text')
|
filetype = MAP_EXT.get(ext, 'text')
|
||||||
self.lastKnownFileType = filetype
|
self.lastKnownFileType = filetype
|
||||||
|
self.explicitFileType = filetype
|
||||||
self.name = name
|
self.name = name
|
||||||
self.path = path
|
self.path = path
|
||||||
self.sourceTree = sourcetree
|
self.sourceTree = sourcetree
|
||||||
|
@ -309,7 +310,6 @@ class PBXContainerItemProxy(XCodeNode):
|
||||||
self.remoteInfo = remoteInfo # Target name
|
self.remoteInfo = remoteInfo # Target name
|
||||||
self.proxyType = proxyType
|
self.proxyType = proxyType
|
||||||
|
|
||||||
|
|
||||||
class PBXTargetDependency(XCodeNode):
|
class PBXTargetDependency(XCodeNode):
|
||||||
""" This is the element for referencing other target through content proxies. """
|
""" This is the element for referencing other target through content proxies. """
|
||||||
def __init__(self, native_target, proxy):
|
def __init__(self, native_target, proxy):
|
||||||
|
@ -490,8 +490,8 @@ class xcode(Build.BuildContext):
|
||||||
|
|
||||||
def create_group(self, name, files):
|
def create_group(self, name, files):
|
||||||
"""
|
"""
|
||||||
Returns a new PBXGroup containing the files (paths) passed in the files arg
|
Returns a new PBXGroup containing the files (paths) passed in the files arg
|
||||||
:type files: string
|
:type files: string
|
||||||
"""
|
"""
|
||||||
group = PBXGroup(name)
|
group = PBXGroup(name)
|
||||||
"""
|
"""
|
||||||
|
@ -562,28 +562,26 @@ class xcode(Build.BuildContext):
|
||||||
|
|
||||||
# Create the output node
|
# Create the output node
|
||||||
target_node = tg.path.find_or_declare(tg.name+file_ext)
|
target_node = tg.path.find_or_declare(tg.name+file_ext)
|
||||||
|
|
||||||
target = PBXNativeTarget(tg.name, target_node, target_type, [], [])
|
target = PBXNativeTarget(tg.name, target_node, target_type, [], [])
|
||||||
|
|
||||||
products_group.children.append(target.productReference)
|
products_group.children.append(target.productReference)
|
||||||
|
|
||||||
if hasattr(tg, 'source_files'):
|
if hasattr(tg, 'source_files') or hasattr(tg, 'source'):
|
||||||
# Create list of PBXFileReferences
|
# Create list of PBXFileReferences
|
||||||
sources = []
|
sources = []
|
||||||
if isinstance(tg.source_files, dict):
|
if hasattr(tg, 'source_files') and isinstance(tg.source_files, dict):
|
||||||
for grpname,files in tg.source_files.items():
|
for grpname,files in tg.source_files.items():
|
||||||
group = self.create_group(grpname, files)
|
group = self.create_group(grpname, files)
|
||||||
target_group.children.append(group)
|
target_group.children.append(group)
|
||||||
sources.extend(group.children)
|
sources.extend(group.children)
|
||||||
elif isinstance(tg.source_files, list):
|
else:
|
||||||
group = self.create_group("Source", tg.source_files)
|
src = getattr(tg, 'source_files', []) or tg.source
|
||||||
|
group = self.create_group("Source", src)
|
||||||
target_group.children.append(group)
|
target_group.children.append(group)
|
||||||
sources.extend(group.children)
|
sources.extend(group.children)
|
||||||
else:
|
|
||||||
self.to_log("Argument 'source_files' passed to target '%s' was not a dictionary. Hence, some source files may not be included. Please provide a dictionary of source files, with group name as key and list of source files as value.\n" % tg.name)
|
|
||||||
|
|
||||||
supported_extensions = ['.c', '.cpp', '.m', '.mm']
|
# FIXME too complex
|
||||||
sources = filter(lambda fileref: os.path.splitext(fileref.path)[1] in supported_extensions, sources)
|
sources = list(filter(lambda fileref: os.path.splitext(fileref.path)[1] in XCODE_EXTS, sources))
|
||||||
buildfiles = [self.unique_buildfile(PBXBuildFile(fileref)) for fileref in sources]
|
buildfiles = [self.unique_buildfile(PBXBuildFile(fileref)) for fileref in sources]
|
||||||
target.add_build_phase(PBXSourcesBuildPhase(buildfiles))
|
target.add_build_phase(PBXSourcesBuildPhase(buildfiles))
|
||||||
|
|
||||||
|
@ -630,7 +628,7 @@ class xcode(Build.BuildContext):
|
||||||
bldsettings['INSTALL_PATH'].append(instpath)
|
bldsettings['INSTALL_PATH'].append(instpath)
|
||||||
target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath))
|
target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath))
|
||||||
|
|
||||||
if len(bldsettings['INSTALL_PATH']) == 0:
|
if not bldsettings['INSTALL_PATH']:
|
||||||
del bldsettings['INSTALL_PATH']
|
del bldsettings['INSTALL_PATH']
|
||||||
|
|
||||||
# The keys represents different build configuration, e.g. Debug, Release and so on..
|
# The keys represents different build configuration, e.g. Debug, Release and so on..
|
||||||
|
@ -650,27 +648,36 @@ class xcode(Build.BuildContext):
|
||||||
node = self.bldnode.make_node('%s.xcodeproj' % appname)
|
node = self.bldnode.make_node('%s.xcodeproj' % appname)
|
||||||
node.mkdir()
|
node.mkdir()
|
||||||
node = node.make_node('project.pbxproj')
|
node = node.make_node('project.pbxproj')
|
||||||
p.write(open(node.abspath(), 'w'))
|
with open(node.abspath(), 'w') as f:
|
||||||
|
p.write(f)
|
||||||
|
Logs.pprint('GREEN', 'Wrote %r' % node.abspath())
|
||||||
|
|
||||||
def build_target(self, tgtype, *k, **kw):
|
def bind_fun(tgtype):
|
||||||
"""
|
def fun(self, *k, **kw):
|
||||||
Provide aliases
|
tgtype = fun.__name__
|
||||||
E.g. bld.framework(source='..', ...) to build a Framework target.
|
if tgtype == 'shlib' or tgtype == 'dylib':
|
||||||
E.g. bld.dylib(source='..', ...) to build a Dynamic library target. etc...
|
features = 'cxx cxxshlib'
|
||||||
"""
|
tgtype = 'dylib'
|
||||||
|
elif tgtype == 'framework':
|
||||||
|
features = 'cxx cxxshlib'
|
||||||
|
tgtype = 'framework'
|
||||||
|
elif tgtype == 'program':
|
||||||
|
features = 'cxx cxxprogram'
|
||||||
|
tgtype = 'exe'
|
||||||
|
elif tgtype == 'app':
|
||||||
|
features = 'cxx cxxprogram'
|
||||||
|
tgtype = 'app'
|
||||||
|
elif tgtype == 'stlib':
|
||||||
|
features = 'cxx cxxstlib'
|
||||||
|
tgtype = 'stlib'
|
||||||
|
kw['features'] = features
|
||||||
|
|
||||||
# The following features are needed for this tool's use of
|
|
||||||
# env['INCPATHS'], env['LIB_xxx'] etc.
|
|
||||||
self.load('ccroot')
|
|
||||||
kw['features'] = 'cxx cxxprogram'
|
|
||||||
kw['target_type'] = tgtype
|
kw['target_type'] = tgtype
|
||||||
return self(*k, **kw)
|
return self(*k, **kw)
|
||||||
|
fun.__name__ = tgtype
|
||||||
|
setattr(Build.BuildContext, tgtype, fun)
|
||||||
|
return fun
|
||||||
|
|
||||||
|
for xx in 'app framework dylib shlib stlib program'.split():
|
||||||
|
bind_fun(xx)
|
||||||
|
|
||||||
def app(self, *k, **kw): return self.build_target('app', *k, **kw)
|
|
||||||
def framework(self, *k, **kw): return self.build_target('framework', *k, **kw)
|
|
||||||
def dylib(self, *k, **kw): return self.build_target('dylib', *k, **kw)
|
|
||||||
def stlib(self, *k, **kw): return self.build_target('stlib', *k, **kw)
|
|
||||||
def program(self, *k, **kw): return self.build_target('exe', *k, **kw)
|
|
||||||
def exe(self, *k, **kw):
|
|
||||||
Logs.warn("xcode6: alias 'bld.exe()' has changed name. Use 'bld.program()' instead.")
|
|
||||||
return self.build_target('exe', *k, **kw)
|
|
||||||
|
|
Loading…
Reference in New Issue