aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends.py32
-rw-r--r--build.py15
-rw-r--r--ninjabackend.py25
3 files changed, 56 insertions, 16 deletions
diff --git a/backends.py b/backends.py
index 574d8f9..380af92 100644
--- a/backends.py
+++ b/backends.py
@@ -85,6 +85,16 @@ def do_conf_file(src, dst, confdata):
open(dst_tmp, 'w').writelines(result)
replace_if_different(dst, dst_tmp)
+class RawFilename():
+ def __init__(self, fname):
+ self.fname = fname
+
+ def split(self, c):
+ return self.fname.split(c)
+
+ def startswith(self, s):
+ return self.fname.startswith(s)
+
class TestSerialisation:
def __init__(self, name, fname, is_cross, exe_wrapper, is_parallel, cmd_args, env):
self.name = name
@@ -121,7 +131,10 @@ class Backend():
def get_target_filename(self, target):
targetdir = self.get_target_dir(target)
- filename = os.path.join(targetdir, target.get_filename())
+ fname = target.get_filename()
+ if isinstance(fname, list):
+ fname = fname[0] # HORROR, HORROR! Fix this.
+ filename = os.path.join(targetdir, fname)
return filename
def get_target_dir(self, target):
@@ -231,8 +244,21 @@ class Backend():
header_deps = gen_other_deps
unity_src = []
unity_deps = [] # Generated sources that must be built before compiling a Unity target.
- for genlist in target.get_generated_sources():
- for src in genlist.get_outfilelist():
+ for gensource in target.get_generated_sources():
+ if isinstance(gensource, build.CustomTarget):
+ for src in gensource.output:
+ src = os.path.join(gensource.subdir, src)
+ if self.environment.is_header(src):
+ header_deps.append(RawFilename(src))
+ elif self.environment.is_source(src):
+ if is_unity:
+ unity_deps.append(os.path.join(self.environment.get_build_dir(), RawFilename(src)))
+ else:
+ obj_list.append(self.generate_single_compile(target, outfile, RawFilename(src), True))
+ else:
+ pass # perhaps print warning about the unknown file?
+ break # just to cut down on indentation size
+ for src in gensource.get_outfilelist():
if self.environment.is_object(src):
obj_list.append(os.path.join(self.get_target_dir(target), target.get_basename() + '.dir', src))
elif not self.environment.is_header(src):
diff --git a/build.py b/build.py
index 2b5db29..8136d9e 100644
--- a/build.py
+++ b/build.py
@@ -159,9 +159,11 @@ class BuildTarget():
# Holder unpacking. Ugly.
if hasattr(s, 'glist'):
s = s.glist
+ if hasattr(s, 'held_object'):
+ s = s.held_object
if isinstance(s, str):
self.sources.append(s)
- elif isinstance(s, GeneratedList):
+ elif isinstance(s, GeneratedList) or isinstance(s, CustomTarget):
self.generated.append(s)
else:
raise InvalidArguments('Bad source in target %s.' % self.name)
@@ -609,10 +611,13 @@ class CustomTarget:
if 'output' not in kwargs:
raise InvalidArguments('Missing keyword argument "output".')
self.output = kwargs['output']
- if not(isinstance(self.output, str)):
- raise InvalidArguments('Output argument not a string.')
- if '/' in self.output:
- raise InvalidArguments('Output must not contain a path segment.')
+ if not isinstance(self.output, list):
+ self.output = [self.output]
+ for i in self.output:
+ if not(isinstance(i, str)):
+ raise InvalidArguments('Output argument not a string.')
+ if '/' in i:
+ raise InvalidArguments('Output must not contain a path segment.')
if 'command' not in kwargs:
raise InvalidArguments('Missing keyword argument "command".')
cmd = kwargs['command']
diff --git a/ninjabackend.py b/ninjabackend.py
index ef66b27..7b70565 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -137,21 +137,21 @@ class NinjaBackend(backends.Backend):
os.replace(tempfilename, outfilename)
def generate_custom_target(self, target, outfile):
- ofilename = os.path.join(target.subdir, target.output)
+ ofilenames = [os.path.join(target.subdir, i) for i in target.output]
deps = [os.path.join(i.get_subdir(), i.get_filename()) for i in target.get_dependencies()]
srcs = [os.path.join(self.build_to_src, target.subdir, i) for i in target.sources]
deps += srcs
- elem = NinjaBuildElement(ofilename, 'CUSTOM_COMMAND', deps)
+ elem = NinjaBuildElement(ofilenames, 'CUSTOM_COMMAND', deps)
cmd = []
for i in target.command:
if i == '@INPUT@':
cmd += srcs
elif i == '@OUTPUT@':
- cmd.append(ofilename)
+ cmd.append += ofilenames
else:
cmd.append(i)
elem.add_item('COMMAND', cmd)
- elem.add_item('description', 'Generating %s with a custom command.' % ofilename)
+ elem.add_item('description', 'Generating %s with a custom command.' % target.name)
elem.write(outfile)
self.processed_targets[target.name] = True
@@ -782,9 +782,10 @@ class NinjaBackend(backends.Backend):
newargs.append(arg)
return newargs
-
def generate_custom_generator_rules(self, target, outfile):
for genlist in target.get_generated_sources():
+ if isinstance(genlist, build.CustomTarget):
+ continue # Customtarget has already written its output rules
generator = genlist.get_generator()
exe = generator.get_exe()
if self.environment.is_cross_build() and \
@@ -827,7 +828,9 @@ class NinjaBackend(backends.Backend):
compiler = self.get_compiler_for_source(src)
commands = self.generate_basic_compiler_args(target, compiler)
commands.append(compiler.get_include_arg(self.get_target_private_dir(target)))
- if is_generated:
+ if isinstance(src, backends.RawFilename):
+ rel_src = src.fname
+ elif is_generated:
if '/' in src:
rel_src = src
else:
@@ -838,6 +841,8 @@ class NinjaBackend(backends.Backend):
src_filename = os.path.basename(src)
else:
src_filename = src
+ if isinstance(src, backends.RawFilename):
+ src_filename = src.fname
obj_basename = src_filename.replace('/', '_').replace('\\', '_')
rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename)
rel_obj += '.' + self.environment.get_object_suffix()
@@ -871,11 +876,15 @@ class NinjaBackend(backends.Backend):
element = NinjaBuildElement(rel_obj, compiler_name, rel_src)
for d in header_deps:
- if not '/' in d:
+ if isinstance(d, backends.RawFilename):
+ d = d.fname
+ elif not '/' in d:
d = os.path.join(self.get_target_private_dir(target), d)
element.add_dep(d)
for d in order_deps:
- if not '/' in d:
+ if isinstance(d, backends.RawFilename):
+ d = d.fname
+ elif not '/' in d :
d = os.path.join(self.get_target_private_dir(target), d)
element.add_orderdep(d)
element.add_orderdep(pch_dep)