diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-01-13 19:00:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-13 19:00:38 +0200 |
commit | d6bed2a77df7f7ff4512fd1be6333420d84b71b8 (patch) | |
tree | e5be5987b3903e3617973e9a29ded3f8f22c4f9f /mesonbuild | |
parent | 81100f0695c595f4c0020034284846cea7e8e6aa (diff) | |
parent | 27d4a611a54251dfab968e3cb111d8cbd6b88254 (diff) | |
download | meson-d6bed2a77df7f7ff4512fd1be6333420d84b71b8.zip meson-d6bed2a77df7f7ff4512fd1be6333420d84b71b8.tar.gz meson-d6bed2a77df7f7ff4512fd1be6333420d84b71b8.tar.bz2 |
Merge pull request #2764 from mesonbuild/generatorpath
Generator outputs can have path segments
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 11 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 5 | ||||
-rw-r--r-- | mesonbuild/build.py | 37 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 15 |
4 files changed, 54 insertions, 14 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 2945d6a..77c7d50 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1791,18 +1791,23 @@ rule FORTRAN_DEP_HACK continue self.generate_genlist_for_target(genlist, target, outfile) - def replace_paths(self, target, args): - source_target_dir = self.get_target_source_dir(target) + def replace_paths(self, target, args, override_subdir=None): + if override_subdir: + source_target_dir = os.path.join(self.build_to_src, override_subdir) + else: + source_target_dir = self.get_target_source_dir(target) relout = self.get_target_private_dir(target) args = [x.replace("@SOURCE_DIR@", self.build_to_src).replace("@BUILD_DIR@", relout) for x in args] args = [x.replace("@CURRENT_SOURCE_DIR@", source_target_dir) for x in args] args = [x.replace("@SOURCE_ROOT@", self.build_to_src).replace("@BUILD_ROOT@", '.') for x in args] + args = [x.replace('\\', '/') for x in args] return args def generate_genlist_for_target(self, genlist, target, outfile): generator = genlist.get_generator() + subdir = genlist.subdir exe = generator.get_exe() exe_arr = self.exe_object_to_cmd_array(exe) infilelist = genlist.get_inputs() @@ -1834,7 +1839,7 @@ rule FORTRAN_DEP_HACK if sole_output == '': outfilelist = outfilelist[len(generator.outputs):] relout = self.get_target_private_dir(target) - args = self.replace_paths(target, args) + args = self.replace_paths(target, args, override_subdir=subdir) cmdlist = exe_arr + self.replace_extra_args(args, genlist) if generator.capture: exe_data = self.serialize_executable( diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 367f391..1722db7 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -87,7 +87,6 @@ class Vs2010Backend(backends.Backend): custom_target_include_dirs = [] custom_target_output_files = [] target_private_dir = self.relpath(self.get_target_private_dir(target), self.get_target_dir(target)) - source_target_dir = self.get_target_source_dir(target) down = self.target_to_build_root(target) for genlist in target.get_generated_sources(): if isinstance(genlist, (build.CustomTarget, build.CustomTargetIndex)): @@ -103,6 +102,7 @@ class Vs2010Backend(backends.Backend): exe = generator.get_exe() infilelist = genlist.get_inputs() outfilelist = genlist.get_outputs() + source_dir = os.path.join(self.build_to_src, genlist.subdir) exe_arr = self.exe_object_to_cmd_array(exe) idgroup = ET.SubElement(parent_node, 'ItemGroup') for i in range(len(infilelist)): @@ -122,10 +122,11 @@ class Vs2010Backend(backends.Backend): args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir()) .replace("@BUILD_DIR@", target_private_dir) for x in args] - args = [x.replace("@CURRENT_SOURCE_DIR@", source_target_dir) for x in args] + args = [x.replace("@CURRENT_SOURCE_DIR@", source_dir) for x in args] args = [x.replace("@SOURCE_ROOT@", self.environment.get_source_dir()) .replace("@BUILD_ROOT@", self.environment.get_build_dir()) for x in args] + args = [x.replace('\\', '/') for x in args] cmd = exe_arr + self.replace_extra_args(args, genlist) if generator.capture: exe_data = self.serialize_executable( diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 16a18a9..5eab794 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -14,7 +14,7 @@ import copy, os, re from collections import OrderedDict -import itertools +import itertools, pathlib from . import environment from . import dependencies @@ -1077,7 +1077,8 @@ class Generator: def get_base_outnames(self, inname): plainname = os.path.split(inname)[1] basename = os.path.splitext(plainname)[0] - return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs] + bases = [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs] + return bases def get_dep_outname(self, inname): if self.depfile is None: @@ -1091,32 +1092,54 @@ class Generator: basename = os.path.splitext(plainname)[0] return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.arglist] - def process_files(self, name, files, state, extra_args=[]): - output = GeneratedList(self, extra_args=extra_args) + def is_parent_path(self, parent, trial): + relpath = pathlib.PurePath(trial).relative_to(parent) + return relpath.parts[0] != '..' # For subdirs we can only go "down". + + def process_files(self, name, files, state, preserve_path_from=None, extra_args=[]): + output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args) for f in files: if isinstance(f, str): f = File.from_source_file(state.environment.source_dir, state.subdir, f) elif not isinstance(f, File): raise InvalidArguments('{} arguments must be strings or files not {!r}.'.format(name, f)) - output.add_file(f) + if preserve_path_from: + abs_f = f.absolute_path(state.environment.source_dir, state.environment.build_dir) + if not self.is_parent_path(preserve_path_from, abs_f): + raise InvalidArguments('When using preserve_path_from, all input files must be in a subdirectory of the given dir.') + output.add_file(f, state) return output class GeneratedList: - def __init__(self, generator, extra_args=[]): + def __init__(self, generator, subdir, preserve_path_from=None, extra_args=[]): if hasattr(generator, 'held_object'): generator = generator.held_object self.generator = generator self.name = self.generator.exe + self.subdir = subdir self.infilelist = [] self.outfilelist = [] self.outmap = {} self.extra_depends = [] + self.preserve_path_from = preserve_path_from self.extra_args = extra_args - def add_file(self, newfile): + def add_preserved_path_segment(self, infile, outfiles, state): + result = [] + in_abs = infile.absolute_path(state.environment.source_dir, state.environment.build_dir) + assert(os.path.isabs(self.preserve_path_from)) + rel = os.path.relpath(in_abs, self.preserve_path_from) + path_segment = os.path.split(rel)[0] + for of in outfiles: + result.append(os.path.join(path_segment, of)) + return result + + def add_file(self, newfile, state): self.infilelist.append(newfile) outfiles = self.generator.get_base_outnames(newfile.fname) + if self.preserve_path_from: + outfiles = self.add_preserved_path_segment(newfile, outfiles, state) self.outfilelist += outfiles self.outmap[newfile] = outfiles diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index c30c00f..c759892 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -375,7 +375,18 @@ class GeneratorHolder(InterpreterObject, ObjectHolder): def process_method(self, args, kwargs): extras = mesonlib.stringlistify(kwargs.get('extra_args', [])) - gl = self.held_object.process_files('Generator', args, self.interpreter, extra_args=extras) + if 'preserve_path_from' in kwargs: + preserve_path_from = kwargs['preserve_path_from'] + if not isinstance(preserve_path_from, str): + raise InvalidArguments('Preserve_path_from must be a string.') + preserve_path_from = os.path.normpath(preserve_path_from) + if not os.path.isabs(preserve_path_from): + # This is a bit of a hack. Fix properly before merging. + raise InvalidArguments('Preserve_path_from must be an absolute path for now. Sorry.') + else: + preserve_path_from = None + gl = self.held_object.process_files('Generator', args, self.interpreter, + preserve_path_from, extra_args=extras) return GeneratedListHolder(gl) @@ -1372,7 +1383,7 @@ permitted_kwargs = {'add_global_arguments': {'language'}, 'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'}, 'executable': exe_kwargs, 'find_program': {'required', 'native'}, - 'generator': {'arguments', 'output', 'depfile', 'capture'}, + 'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'}, 'include_directories': {'is_system'}, 'install_data': {'install_dir', 'install_mode', 'sources'}, 'install_headers': {'install_dir', 'subdir'}, |