Merge pull request #908 from centricular/vala-generated-sources

Support all kinds of generated vala and vapi sources
This commit is contained in:
Jussi Pakkanen 2016-10-19 21:15:22 +03:00 committed by GitHub
commit d367738ec7
21 changed files with 339 additions and 177 deletions

View File

@ -93,16 +93,16 @@ class Backend():
src = src.fname
raise RuntimeError('No specified compiler can handle file ' + src)
def get_target_filename(self, target):
assert(isinstance(target, (build.BuildTarget, build.CustomTarget)))
targetdir = self.get_target_dir(target)
fname = target.get_filename()
if isinstance(fname, list):
# FIXME FIXME FIXME: build.CustomTarget has multiple output files
# and get_filename() returns them all
fname = fname[0]
filename = os.path.join(targetdir, fname)
return filename
def get_target_filename(self, t):
if isinstance(t, build.CustomTarget):
if len(t.get_outputs()) != 1:
mlog.log(mlog.red('WARNING'), 'custom_target {!r} has more ' \
'than one output! Using the first one.'.format(t.name))
filename = t.get_outputs()[0]
else:
assert(isinstance(t, build.BuildTarget))
filename = t.get_filename()
return os.path.join(self.get_target_dir(t), filename)
def get_target_filename_abs(self, target):
return os.path.join(self.environment.get_build_dir(), self.get_target_filename(target))
@ -140,6 +140,19 @@ class Backend():
dirname = os.path.join(self.environment.get_build_dir(), self.get_target_private_dir(target))
return dirname
def get_target_generated_dir(self, target, gensrc, src):
"""
Takes a BuildTarget, a generator source (CustomTarget or GeneratedList),
and a generated source filename.
Returns the full path of the generated source relative to the build root
"""
# CustomTarget generators output to the build dir of the CustomTarget
if isinstance(gensrc, build.CustomTarget):
return os.path.join(self.get_target_dir(gensrc), src)
# GeneratedList generators output to the private build directory of the
# target that the GeneratedList is used in
return os.path.join(self.get_target_private_dir(target), src)
def generate_unity_files(self, target, unity_src):
langlist = {}
abs_files = []
@ -520,15 +533,17 @@ class Backend():
outdir = '.'
if absolute_paths:
outdir = os.path.join(self.environment.get_build_dir(), outdir)
for i in target.sources:
for i in target.get_sources():
if hasattr(i, 'held_object'):
i = i.held_object
if isinstance(i, str):
fname = [os.path.join(self.build_to_src, target.subdir, i)]
elif isinstance(i, (build.BuildTarget, build.CustomTarget)):
elif isinstance(i, build.BuildTarget):
fname = [self.get_target_filename(i)]
elif isinstance(i, build.CustomTarget):
fname = [os.path.join(self.get_target_dir(i), p) for p in i.get_outputs()]
elif isinstance(i, build.GeneratedList):
fname = [os.path.join(self.get_target_private_dir(target), p) for p in i.get_outfilelist()]
fname = [os.path.join(self.get_target_private_dir(target), p) for p in i.get_outputs()]
else:
fname = [i.rel_to_builddir(self.build_to_src)]
if absolute_paths:
@ -542,7 +557,7 @@ class Backend():
elif isinstance(i, build.CustomTarget):
# GIR scanner will attempt to execute this binary but
# it assumes that it is in path, so always give it a full path.
tmp = i.get_filename()[0]
tmp = i.get_outputs()[0]
i = os.path.join(self.get_target_dir(i), tmp)
elif isinstance(i, mesonlib.File):
i = i.rel_to_builddir(self.build_to_src)

View File

@ -35,6 +35,10 @@ def ninja_quote(text):
return text.replace(' ', '$ ').replace(':', '$:')
class RawFilename():
"""
Used when a filename is already relative to the root build directory, so
that we know not to add the target's private build directory to it.
"""
def __init__(self, fname):
self.fname = fname
@ -216,26 +220,57 @@ int dummy;
# we need to add an order dependency to them.
def get_generated_headers(self, target):
header_deps = []
for gensource in target.get_generated_sources():
if isinstance(gensource, build.CustomTarget):
# XXX: Why don't we add deps to CustomTarget headers here?
for genlist in target.get_generated_sources():
if isinstance(genlist, build.CustomTarget):
continue
for src in gensource.get_outfilelist():
for src in genlist.get_outputs():
if self.environment.is_header(src):
header_deps.append(os.path.join(self.get_target_private_dir(target), src))
header_deps.append(self.get_target_generated_dir(target, genlist, src))
# Recurse and find generated headers
for dep in target.link_targets:
if isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
header_deps += self.get_generated_headers(dep)
return header_deps
def get_target_generated_sources(self, target):
"""
Returns a dictionary with the keys being the path to the file
(relative to the build directory) of that type and the value
being the GeneratorList or CustomTarget that generated it.
"""
srcs = {}
for gensrc in target.get_generated_sources():
for s in gensrc.get_outputs():
f = self.get_target_generated_dir(target, gensrc, s)
srcs[f] = s
return srcs
def get_target_sources(self, target):
srcs = {}
for s in target.get_sources():
# BuildTarget sources are always mesonlib.File files which are
# either in the source root, or generated with configure_file and
# in the build root
if not isinstance(s, File):
raise InvalidArguments('All sources in target {!r} must be of type mesonlib.File'.format(t))
f = s.rel_to_builddir(self.build_to_src)
srcs[f] = s
return srcs
def generate_target(self, target, outfile):
if isinstance(target, build.CustomTarget):
self.generate_custom_target(target, outfile)
if isinstance(target, build.RunTarget):
self.generate_run_target(target, outfile)
name = target.get_id()
vala_gen_sources = []
if name in self.processed_targets:
return
self.processed_targets[name] = True
# Generate rules for all dependency targets
self.process_target_dependencies(target, outfile)
# If target uses a language that cannot link to C objects,
# just generate for that language and return.
if isinstance(target, build.Jar):
self.generate_jar_target(target, outfile)
return
@ -248,11 +283,28 @@ int dummy;
if 'swift' in target.compilers:
self.generate_swift_target(target, outfile)
return
# Pre-existing target C/C++ sources to be built; dict of full path to
# source relative to build root and the original File object.
target_sources = {}
# GeneratedList and CustomTarget sources to be built; dict of the full
# path to source relative to build root and the generating target/list
generated_sources = {}
# Array of sources generated by valac that have to be compiled
vala_generated_sources = []
if 'vala' in target.compilers:
vala_gen_sources = self.generate_vala_compile(target, outfile)
# Sources consumed by valac are filtered out. These only contain
# C/C++ sources, objects, generated libs, and unknown sources now.
target_sources, generated_sources, \
vala_generated_sources = self.generate_vala_compile(target, outfile)
else:
target_sources = self.get_target_sources(target)
generated_sources = self.get_target_generated_sources(target)
self.scan_fortran_module_outputs(target)
self.process_target_dependencies(target, outfile)
self.generate_custom_generator_rules(target, outfile)
# Generate rules for GeneratedLists
self.generate_generator_list_rules(target, outfile)
# Generate rules for building the remaining source files in this target
outname = self.get_target_filename(target)
obj_list = []
use_pch = self.environment.coredata.base_options.get('b_pch', False)
@ -275,41 +327,24 @@ int dummy;
# This will be set as dependencies of all the target's sources. At the
# same time, also deal with generated sources that need to be compiled.
generated_source_files = []
for gensource in target.get_generated_sources():
if isinstance(gensource, build.CustomTarget):
for src in gensource.output:
src = os.path.join(self.get_target_dir(gensource), src)
generated_output_sources.append(src)
if self.environment.is_source(src) and not self.environment.is_header(src):
if is_unity:
unity_deps.append(os.path.join(self.environment.get_build_dir(), RawFilename(src)))
else:
generated_source_files.append(RawFilename(src))
elif self.environment.is_object(src):
obj_list.append(src)
elif self.environment.is_library(src):
pass
else:
# Assume anything not specifically a source file is a header. This is because
# people generate files with weird suffixes (.inc, .fh) that they then include
# in their source files.
header_deps.append(RawFilename(src))
for rel_src, gensrc in generated_sources.items():
generated_output_sources.append(rel_src)
if self.environment.is_source(rel_src) and not self.environment.is_header(rel_src):
if is_unity:
unity_deps.append(rel_src)
abs_src = os.path.join(self.environment.get_build_dir(), rel_src)
unity_src.append(abs_src)
else:
generated_source_files.append(RawFilename(rel_src))
elif self.environment.is_object(rel_src):
obj_list.append(rel_src)
elif self.environment.is_library(rel_src):
pass
else:
for src in gensource.get_outfilelist():
generated_output_sources.append(src)
if self.environment.is_object(src):
obj_list.append(os.path.join(self.get_target_private_dir(target), src))
elif not self.environment.is_header(src):
if is_unity:
if self.has_dir_part(src):
rel_src = src
else:
rel_src = os.path.join(self.get_target_private_dir(target), src)
unity_deps.append(rel_src)
abs_src = os.path.join(self.environment.get_build_dir(), rel_src)
unity_src.append(abs_src)
else:
generated_source_files.append(src)
# Assume anything not specifically a source file is a header. This is because
# people generate files with weird suffixes (.inc, .fh) that they then include
# in their source files.
header_deps.append(RawFilename(rel_src))
# These are the generated source files that need to be built for use by
# this target. We create the Ninja build file elements for this here
# because we need `header_deps` to be fully generated in the above loop.
@ -319,8 +354,8 @@ int dummy;
header_deps=header_deps))
# Generate compilation targets for C sources generated from Vala
# sources. This can be extended to other $LANG->C compilers later if
# necessary.
for src in vala_gen_sources:
# necessary. This needs to be separate for at least Vala
for src in vala_generated_sources:
src_list.append(src)
if is_unity:
unity_src.append(os.path.join(self.environment.get_build_dir(), src))
@ -334,11 +369,12 @@ int dummy;
if self.environment.is_header(src):
header_deps.append(src)
else:
# Passing 'vala' here signifies that we want the compile
# arguments to be specialized for C code generated by
# valac. For instance, no warnings should be emitted.
obj_list.append(self.generate_single_compile(target, outfile, src, 'vala', [], header_deps))
# Generate compile targets for all the pre-existing sources for this target
for src in target.get_sources():
if src.endswith('.vala'):
continue
for f, src in target_sources.items():
if not self.environment.is_header(src):
src_list.append(src)
if is_unity:
@ -355,7 +391,6 @@ int dummy;
elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects)
self.generate_shlib_aliases(target, self.get_target_dir(target))
elem.write(outfile)
self.processed_targets[name] = True
def process_target_dependencies(self, target, outfile):
for t in target.get_dependencies():
@ -376,10 +411,9 @@ int dummy;
# FIXME, should not grab element at zero but rather expand all.
if isinstance(i, list):
i = i[0]
fname = i.get_filename()
if isinstance(fname, list):
fname = fname[0]
deps.append(os.path.join(self.get_target_dir(i), fname))
# Add a dependency on all the outputs of this target
for output in i.get_outputs():
deps.append(os.path.join(self.get_target_dir(i), output))
return deps
def generate_custom_target(self, target, outfile):
@ -401,11 +435,9 @@ int dummy;
deps.append(os.path.join(self.build_to_src, i))
elem.add_dep(deps)
for d in target.extra_depends:
tmp = d.get_filename()
if not isinstance(tmp, list):
tmp = [tmp]
for fname in tmp:
elem.add_dep(os.path.join(self.get_target_dir(d), fname))
# Add a dependency on all the outputs of this target
for output in d.get_outputs():
elem.add_dep(os.path.join(self.get_target_dir(d), output))
# If the target requires capturing stdout, then use the serialized
# executable wrapper to capture that output and save it to a file.
#
@ -541,7 +573,8 @@ int dummy;
should_strip = self.environment.coredata.get_builtin_option('strip')
for t in self.build.get_targets().values():
if t.should_install():
# Find the installation directory
# Find the installation directory. FIXME: Currently only one
# installation directory is supported for each target
outdir = t.get_custom_install_dir()
if outdir is not None:
pass
@ -572,9 +605,14 @@ int dummy;
# stripped, and doesn't have an install_rpath
i = [self.get_target_debug_filename(t), outdir, [], False, '']
d.targets.append(i)
i = [self.get_target_filename(t), outdir, t.get_aliaslist(),\
should_strip, t.install_rpath]
d.targets.append(i)
if isinstance(t, build.BuildTarget):
i = [self.get_target_filename(t), outdir, t.get_aliaslist(),\
should_strip, t.install_rpath]
d.targets.append(i)
elif isinstance(t, build.CustomTarget):
for output in t.get_outputs():
f = os.path.join(self.get_target_dir(t), output)
d.targets.append([f, outdir, [], False, None])
def generate_custom_install_script(self, d):
d.install_scripts = self.build.install_scripts
@ -838,17 +876,13 @@ int dummy;
outfile.write(description)
outfile.write('\n')
def split_vala_sources(self, sources):
other_src = []
vapi_src = []
for s in sources:
if s.endswith('.vapi'):
vapi_src.append(s)
else:
other_src.append(s)
return (other_src, vapi_src)
def determine_dep_vapis(self, target):
"""
Peek into the sources of BuildTargets we're linking with, and if any of
them was built with Vala, assume that it also generated a .vapi file of
the same name as the BuildTarget and return the path to it relative to
the build directory.
"""
result = []
for dep in target.link_targets:
for i in dep.sources:
@ -861,57 +895,119 @@ int dummy;
break
return result
def split_vala_sources(self, t):
"""
Splits the target's sources into .vala, .vapi, and other sources.
Handles both pre-existing and generated sources.
Returns a tuple (vala, vapi, others) each of which is a dictionary with
the keys being the path to the file (relative to the build directory)
and the value being the object that generated or represents the file.
"""
vala = {}
vapi = {}
others = {}
othersgen = {}
# Split pre-existing sources
for s in t.get_sources():
# BuildTarget sources are always mesonlib.File files which are
# either in the source root, or generated with configure_file and
# in the build root
if not isinstance(s, File):
msg = 'All sources in target {!r} must be of type ' \
'mesonlib.File, not {!r}'.format(t, s)
raise InvalidArguments(msg)
f = s.rel_to_builddir(self.build_to_src)
if s.endswith('.vala'):
srctype = vala
elif s.endswith('.vapi'):
srctype = vapi
else:
srctype = others
srctype[f] = s
# Split generated sources
for gensrc in t.get_generated_sources():
for s in gensrc.get_outputs():
f = self.get_target_generated_dir(t, gensrc, s)
if s.endswith('.vala'):
srctype = vala
elif s.endswith('.vapi'):
srctype = vapi
# Generated non-Vala (C/C++) sources. Won't be used for
# generating the Vala compile rule below.
else:
srctype = othersgen
# Duplicate outputs are disastrous
if f in srctype:
msg = 'Duplicate output {0!r} from {1!r} {2!r}; ' \
'conflicts with {0!r} from {4!r} {3!r}' \
''.format(f, type(gensrc).__name__, gensrc.name,
srctype[f].name, type(srctype[f]).__name__)
raise InvalidArguments(msg)
# Store 'somefile.vala': GeneratedList (or CustomTarget)
srctype[f] = gensrc
return (vala, vapi, (others, othersgen))
def generate_vala_compile(self, target, outfile):
"""Vala is compiled into C. Set up all necessary build steps here."""
valac = target.compilers['vala']
(other_src, vapi_src) = self.split_vala_sources(target.get_sources())
vapi_src = [x.rel_to_builddir(self.build_to_src) for x in vapi_src]
(vala_src, vapi_src, other_src) = self.split_vala_sources(target)
extra_dep_files = []
if len(other_src) == 0:
if len(vala_src) == 0:
raise InvalidArguments('Vala library has no Vala source files.')
namebase = target.name
base_h = namebase + '.h'
base_vapi = namebase + '.vapi'
hname = os.path.normpath(os.path.join(self.get_target_dir(target), base_h))
vapiname = os.path.normpath(os.path.join(self.get_target_dir(target), base_vapi))
generated_c_files = []
outputs = [vapiname]
args = []
args += self.build.get_global_args(valac)
args += valac.get_buildtype_args(self.environment.coredata.get_builtin_option('buildtype'))
args += ['-d', self.get_target_private_dir(target)]
args += ['-C']#, '-o', cname]
if not isinstance(target, build.Executable):
outputs.append(hname)
args += ['-H', hname]
args += ['--library=' + target.name]
args += ['--vapi=' + os.path.join('..', base_vapi)]
vala_src = []
for s in other_src:
if not s.endswith('.vala'):
continue
vala_file = s.rel_to_builddir(self.build_to_src)
vala_src.append(vala_file)
valac = target.compilers['vala']
c_out_dir = self.get_target_private_dir(target)
# C files generated by valac
vala_c_src = []
# Files generated by valac
valac_outputs = []
# All sources that are passed to valac on the commandline
all_files = list(vapi_src.keys())
for (vala_file, gensrc) in vala_src.items():
all_files.append(vala_file)
# Figure out where the Vala compiler will write the compiled C file
dirname, basename = os.path.split(vala_file)
# If the Vala file is in a subdir of the build dir (in our case
# because it was generated/built by something else), the subdir path
# components will be preserved in the output path. But if the Vala
# file is outside the build directory, the path components will be
# stripped and just the basename will be used.
c_file = os.path.splitext(basename)[0] + '.c'
if s.is_built:
c_file = os.path.join(dirname, c_file)
full_c = os.path.join(self.get_target_private_dir(target), c_file)
generated_c_files.append(full_c)
outputs.append(full_c)
if isinstance(gensrc, (build.CustomTarget, build.GeneratedList)) or gensrc.is_built:
vala_c_file = os.path.splitext(vala_file)[0] + '.c'
else:
vala_c_file = os.path.splitext(os.path.basename(vala_file))[0] + '.c'
# All this will be placed inside the c_out_dir
vala_c_file = os.path.join(c_out_dir, vala_c_file)
vala_c_src.append(vala_c_file)
valac_outputs.append(vala_c_file)
args = []
args += self.build.get_global_args(valac)
args += valac.get_buildtype_args(self.environment.coredata.get_builtin_option('buildtype'))
# Tell Valac to output everything in our private directory. Sadly this
# means it will also preserve the directory components of Vala sources
# found inside the build tree (generated sources).
args += ['-d', c_out_dir]
args += ['-C']
if not isinstance(target, build.Executable):
# Library name
args += ['--library=' + target.name]
# Outputted header
hname = os.path.join(self.get_target_dir(target), target.name + '.h')
args += ['-H', hname]
valac_outputs.append(hname)
# Outputted vapi file
base_vapi = target.name + '.vapi'
vapiname = os.path.join(self.get_target_dir(target), base_vapi)
# Force valac to write the vapi file in the target build dir.
# Without this, it will write it inside c_out_dir
args += ['--vapi=../' + base_vapi]
valac_outputs.append(vapiname)
if self.environment.coredata.get_builtin_option('werror'):
args += valac.get_werror_args()
for d in target.external_deps:
for d in target.get_external_deps():
if isinstance(d, dependencies.PkgConfigDependency):
if d.name == 'glib-2.0' and d.version_requirement is not None \
and d.version_requirement.startswith(('>=', '==')):
and d.version_requirement.startswith(('>=', '==')):
args += ['--target-glib', d.version_requirement[2:]]
args += ['--pkg', d.name]
extra_args = []
@ -926,14 +1022,13 @@ int dummy;
dependency_vapis = self.determine_dep_vapis(target)
extra_dep_files += dependency_vapis
args += extra_args
args += dependency_vapis
element = NinjaBuildElement(self.all_outputs, outputs,
element = NinjaBuildElement(self.all_outputs, valac_outputs,
valac.get_language() + '_COMPILER',
vala_src + vapi_src)
all_files + dependency_vapis)
element.add_item('ARGS', args)
element.add_dep(extra_dep_files)
element.write(outfile)
return generated_c_files
return other_src[0], other_src[1], vala_c_src
def generate_rust_target(self, target, outfile):
rustc = target.compilers['rust']
@ -1006,16 +1101,7 @@ int dummy;
return result
def split_swift_generated_sources(self, target):
all_srcs = []
for genlist in target.get_generated_sources():
if isinstance(genlist, build.CustomTarget):
for ifile in genlist.get_filename():
rel = os.path.join(self.get_target_dir(genlist), ifile)
all_srcs.append(rel)
else:
for ifile in genlist.get_outfilelist():
rel = os.path.join(self.get_target_private_dir(target), ifile)
all_srcs.append(rel)
all_srcs = self.get_target_generated_sources(target)
srcs = []
others = []
for i in all_srcs:
@ -1392,18 +1478,20 @@ rule FORTRAN_DEP_HACK
self.generate_pch_rule_for(langname, compiler, qstr, True, outfile)
outfile.write('\n')
def generate_custom_generator_rules(self, target, outfile):
def generate_generator_list_rules(self, target, outfile):
# CustomTargets have already written their rules,
# so write rules for GeneratedLists here
for genlist in target.get_generated_sources():
if isinstance(genlist, build.CustomTarget):
continue # Customtarget has already written its output rules
continue
self.generate_genlist_for_target(genlist, target, outfile)
def generate_genlist_for_target(self, genlist, target, outfile):
generator = genlist.get_generator()
exe = generator.get_exe()
exe_arr = self.exe_object_to_cmd_array(exe)
infilelist = genlist.get_infilelist()
outfilelist = genlist.get_outfilelist()
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
base_args = generator.get_arglist()
extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends]
for i in range(len(infilelist)):
@ -1579,6 +1667,9 @@ rule FORTRAN_DEP_HACK
return linker.get_link_debugfile_args(outname)
def generate_single_compile(self, target, outfile, src, is_generated=False, header_deps=[], order_deps=[]):
"""
Compiles only C/C++ and ObjC/ObjC++ sources
"""
if(isinstance(src, str) and src.endswith('.h')):
raise RuntimeError('Fug')
if isinstance(src, RawFilename) and src.fname.endswith('.h'):
@ -1635,7 +1726,7 @@ rule FORTRAN_DEP_HACK
if isinstance(src, File):
rel_src = src.rel_to_builddir(self.build_to_src)
else:
raise build.InvalidArguments('Invalid source type.')
raise InvalidArguments('Invalid source type: {!r}'.format(src))
abs_src = os.path.join(self.environment.get_build_dir(), rel_src)
if isinstance(src, (RawFilename, File)):
src_filename = src.fname
@ -1659,11 +1750,12 @@ rule FORTRAN_DEP_HACK
arr.append(i)
pch_dep = arr
custom_target_include_dirs = []
for i in target.generated:
if isinstance(i, build.CustomTarget):
idir = self.get_target_dir(i)
if idir not in custom_target_include_dirs:
custom_target_include_dirs.append(idir)
for i in target.get_generated_sources():
if not isinstance(i, build.CustomTarget):
continue
idir = self.get_target_dir(i)
if idir not in custom_target_include_dirs:
custom_target_include_dirs.append(idir)
for i in custom_target_include_dirs:
commands+= compiler.get_include_args(i, False)
if self.environment.coredata.base_options.get('b_pch', False):
@ -1761,7 +1853,10 @@ rule FORTRAN_DEP_HACK
if len(pch) == 0:
continue
if '/' not in pch[0] or '/' not in pch[-1]:
raise build.InvalidArguments('Precompiled header of "%s" must not be in the same directory as source, please put it in a subdirectory.' % target.get_basename())
msg = 'Precompiled header of {!r} must not be in the same ' \
'directory as source, please put it in a subdirectory.' \
''.format(target.get_basename())
raise InvalidArguments(msg)
compiler = self.get_compiler_for_lang(lang)
if compiler.id == 'msvc':
src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[-1])
@ -1941,7 +2036,9 @@ rule FORTRAN_DEP_HACK
# are used by something else or are meant to be always built
if isinstance(t, build.CustomTarget) and not (t.install or t.build_always):
continue
targetlist.append(self.get_target_filename(t))
# Add the first output of each target to the 'all' target so that
# they are all built
targetlist.append(os.path.join(self.get_target_dir(t), t.get_outputs()[0]))
elem = NinjaBuildElement(self.all_outputs, 'all', 'phony', targetlist)
elem.write(outfile)

View File

@ -102,7 +102,7 @@ class Vs2010Backend(backends.Backend):
down = self.target_to_build_root(target)
for genlist in target.get_generated_sources():
if isinstance(genlist, build.CustomTarget):
for i in genlist.output:
for i in genlist.get_outputs():
# Path to the generated source from the current vcxproj dir via the build root
ipath = os.path.join(down, self.get_target_dir(genlist), i)
custom_target_output_files.append(ipath)
@ -112,8 +112,8 @@ class Vs2010Backend(backends.Backend):
else:
generator = genlist.get_generator()
exe = generator.get_exe()
infilelist = genlist.get_infilelist()
outfilelist = genlist.get_outfilelist()
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
exe_arr = self.exe_object_to_cmd_array(exe)
base_args = generator.get_arglist()
for i in range(len(infilelist)):

View File

@ -547,6 +547,9 @@ class BuildTarget():
def get_filename(self):
return self.filename
def get_outputs(self):
return [self.filename]
def get_debug_filename(self):
"""
The name of the file that contains debugging symbols for this target
@ -650,12 +653,6 @@ by calling get_variable() on the subproject object.''')
raise InvalidArguments('Tried to mix cross built and native libraries in target {!r}'.format(self.name))
self.link_targets.append(t)
def set_generated(self, genlist):
for g in genlist:
if not(isinstance(g, GeneratedList)):
raise InvalidArguments('Generated source argument is not the output of a generator.')
self.generated.append(g)
def add_pch(self, language, pchlist):
if len(pchlist) == 0:
return
@ -705,7 +702,7 @@ class Generator():
def __init__(self, args, kwargs):
if len(args) != 1:
raise InvalidArguments('Generator requires one and only one positional argument')
exe = args[0]
if hasattr(exe, 'held_object'):
exe = exe.held_object
@ -779,6 +776,7 @@ class GeneratedList():
if hasattr(generator, 'held_object'):
generator = generator.held_object
self.generator = generator
self.name = self.generator.exe
self.infilelist = []
self.outfilelist = []
self.outmap = {}
@ -791,10 +789,10 @@ class GeneratedList():
self.outfilelist += outfiles
self.outmap[newfile] = outfiles
def get_infilelist(self):
def get_inputs(self):
return self.infilelist
def get_outfilelist(self):
def get_outputs(self):
return self.outfilelist
def get_outputs_for(self, filename):
@ -1085,7 +1083,6 @@ class CustomTarget:
self.depfile = None
self.process_kwargs(kwargs)
self.extra_files = []
self.install_rpath = ''
unknowns = []
for k in kwargs:
if k not in CustomTarget.known_kwargs:
@ -1217,12 +1214,9 @@ class CustomTarget:
def get_subdir(self):
return self.subdir
def get_filename(self):
def get_outputs(self):
return self.output
def get_aliaslist(self):
return []
def get_sources(self):
return self.sources

View File

@ -0,0 +1,5 @@
int retval (void);
int test (void) {
return retval ();
}

View File

@ -0,0 +1,5 @@
writec = find_program('writec.py')
retval = custom_target('writec',
output : 'retval.c',
command : [writec, '@OUTPUT@'])

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python3
import sys
c = '''int
retval(void) {
return 0;
}
'''
with open(sys.argv[1], 'w') as f:
f.write(c)

View File

@ -1,3 +0,0 @@
int test () {
return 0;
}

View File

@ -2,4 +2,6 @@ project('foo', 'c', 'vala')
glib = dependency('glib-2.0')
executable('foo', 'foo.c', 'bar.vala', dependencies: [glib])
subdir('c')
e = executable('foo', 'c/foo.c', retval, 'vala/bar.vala', dependencies: [glib])
test('test foo', e)

View File

@ -1,5 +0,0 @@
config = configure_file(input: 'config.vala.in',
output: 'config.vala',
configuration: cd)
src = files('test.vala')

View File

@ -1,3 +0,0 @@
void main() {
print (Config.x);
}

View File

@ -0,0 +1,7 @@
#!/usr/bin/env python3
import os
import sys
import shutil
shutil.copyfile(sys.argv[1], sys.argv[2])

View File

@ -0,0 +1,17 @@
config = configure_file(input: 'config.vala.in',
output: 'config.vala',
configuration: cd)
print = find_program('write_wrapper.py')
wrapper = custom_target('wrapper',
output : 'print_wrapper.vala',
command : [print, '@OUTPUT@'])
copy = find_program('copy_file.py')
gen = generator(copy,
output : '@BASENAME@.vala',
arguments : ['@INPUT@', '@OUTPUT@'])
returncode = gen.process('returncode.in')
src = files('test.vala')

View File

@ -0,0 +1,3 @@
int return_code() {
return 0;
}

View File

@ -0,0 +1,4 @@
int main() {
print_wrapper (Config.x);
return return_code ();
}

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python3
import sys
contents = '''
void print_wrapper(string arg) {
print (arg);
}
'''
with open(sys.argv[1], 'w') as f:
f.write(contents)

View File

@ -1,3 +1,3 @@
executable('generatedtest', [src, config],
executable('generatedtest', [src, config, returncode, wrapper],
install : true,
dependencies: [dependency('glib-2.0'), dependency('gobject-2.0')])