Make it possible to generate source files in custom targets.

pull/15/head
Jussi Pakkanen 10 years ago
parent 5736f8dc60
commit bae8507753
  1. 32
      backends.py
  2. 15
      build.py
  3. 25
      ninjabackend.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):

@ -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']

@ -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)

Loading…
Cancel
Save