diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 16 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 10 | ||||
-rw-r--r-- | mesonbuild/build.py | 1 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 19 | ||||
-rw-r--r-- | mesonbuild/minstall.py | 15 | ||||
-rw-r--r-- | mesonbuild/utils/universal.py | 21 | ||||
-rw-r--r-- | test cases/frameworks/14 doxygen/doc/meson.build | 13 |
7 files changed, 84 insertions, 11 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8943464..68efb3d 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -131,6 +131,7 @@ class InstallData: self.symlinks: T.List[InstallSymlinkData] = [] self.install_scripts: T.List[ExecutableSerialisation] = [] self.install_subdirs: T.List[SubdirInstallData] = [] + self.install_opaque: T.List[(str, str)] = [] @dataclass(eq=False) class TargetInstallData: @@ -1510,6 +1511,7 @@ class Backend: self.generate_symlink_install(d) self.generate_custom_install_script(d) self.generate_subdir_install(d) + self.generate_opaque_install(d) return d def create_install_data_files(self) -> None: @@ -1637,6 +1639,11 @@ class Backend: tag=tag) d.targets.append(i) elif isinstance(t, build.CustomTarget): + if t.is_opaque: + # The contents of opaque dirs are installed in a separate function. + # The "output" of this target is the stampfile and we do not want + # to install that. + continue # If only one install_dir is specified, assume that all # outputs will be installed into it. This is for # backwards-compatibility and because it makes sense to @@ -1771,6 +1778,15 @@ class Backend: i = SubdirInstallData(src_dir, dst_dir, dst_name, sd.install_mode, sd.exclude, sd.subproject, sd.install_tag) d.install_subdirs.append(i) + def generate_opaque_install(self, d: InstallData) -> None: + for ct in self.build.get_targets().values(): + if isinstance(ct, build.CustomTarget) and ct.is_opaque: + opdata = mesonlib.get_opaque_data(ct.subproject, ct.name) + if len(ct.install_dir) !=1: + raise RuntimeError('Internal error, install_dir must have only one string.') + installdir = ct.install_dir[0] + d.install_opaque.append((opdata.out, installdir)) + def get_introspection_data(self, target_id: str, target: build.Target) -> T.List['TargetIntrospectionData']: ''' Returns a list of source dicts with the following format for a given target: diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 593c201..8377dcf 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -3445,15 +3445,17 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) # empty. https://github.com/mesonbuild/meson/issues/1220 ctlist = [] for t in self.build.get_targets().values(): - if isinstance(t, build.CustomTarget): + if isinstance(t, build.CustomTarget) and not t.is_opaque: # Create a list of all custom target outputs for o in t.get_outputs(): ctlist.append(os.path.join(self.get_target_dir(t), o)) # As above, but restore the top level directory after deletion. + gendir_list = [] for t in self.build.get_targets().values(): - if isinstance(t, build.CustomTarget): - if False: - gendir_list.append('fake') + if isinstance(t, build.CustomTarget) and t.is_opaque: + opdata = mesonlib.get_opaque_data(t.subproject, t.name) + gendir_list.append(opdata.scratch) + gendir_list.append(opdata.out) if ctlist or gendir_list: elem.add_dep(self.generate_custom_target_clean(ctlist, gendir_list)) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index bf87071..4e5150e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2443,6 +2443,7 @@ class CustomTarget(Target, CommandBase): self.install_mode = install_mode self.install_tag = _process_install_tag(install_tag, len(self.outputs)) self.name = name if name else self.outputs[0] + self.is_opaque = False # Whether to use absolute paths for all files on the commandline self.absolute_paths = absolute_paths diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 1f9a99a..523b3e7 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -408,6 +408,7 @@ class Interpreter(InterpreterBase, HoldableObject): 'join_paths': self.func_join_paths, 'library': self.func_library, 'message': self.func_message, + 'opaque_target': self.func_opaque_target, 'option': self.func_option, 'project': self.func_project, 'range': self.func_range, @@ -1984,6 +1985,24 @@ class Interpreter(InterpreterBase, HoldableObject): self.add_target(tg.name, tg) return tg + def func_opaque_target(self, node: mparser.FunctionNode, args: T.Tuple[str], + kwargs: 'kwtypes.OpaqueTarget') -> build.CustomTarget: + if len(args) != 1: + raise InterpreterException('Opaque_target takes exactly one positional argument.') + opaque_data = mesonlib.get_opaque_data(self.subproject, args[0]) + kwargs['output'] = opaque_data.stamp + kwargs['depfile'] = opaque_data.dep + integration_args = ['--stamp=@OUTPUT@', + '--dep=@DEPFILE@', + '--scratch=' + opaque_data.scratch, + '--out=' + opaque_data.out, + '--'] + kwargs['command'] = listify(kwargs['command']) + integration_args + kwargs['args'] + del kwargs['args'] + ct = self.func_custom_target(node, args, kwargs) + ct.is_opaque = True + return ct + @typed_pos_args('run_target', str) @typed_kwargs( 'run_target', diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 69763fa..8a97c8a 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -548,6 +548,7 @@ class Installer: self.install_emptydir(d, dm, destdir, fullprefix) self.install_data(d, dm, destdir, fullprefix) self.install_symlinks(d, dm, destdir, fullprefix) + self.install_opaque(d, dm, destdir, fullprefix) self.restore_selinux_contexts(destdir) self.run_install_script(d, destdir, fullprefix) if not self.did_install_something: @@ -604,6 +605,20 @@ class Installer: if self.do_symlink(s.target, full_link_name, destdir, full_dst_dir, s.allow_missing): self.did_install_something = True + def install_opaque(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None: + for s in d.install_opaque: + from_dir, dst_dir = s + from_dir_abs = os.path.join(d.build_dir, from_dir) + full_dst_dir = get_destdir_path(destdir, fullprefix, dst_dir) + from_path = Path(from_dir_abs ) + for f in from_path.glob('*'): + if f.is_file(): + self.do_copyfile(f, os.path.join(full_dst_dir), f.parts[-1]) + else: + + self.do_copydir(d, str(f), os.path.join(full_dst_dir, f.parts[-1]), None, None, dm) + self.did_install_something = True + def install_man(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None: for m in d.man: if not self.should_install(m): diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index aaefbc5..a8f2d97 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -1,4 +1,4 @@ -# Copyright 2012-2020 The Meson development team +# Copyright 2012-2022 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -94,6 +94,7 @@ __all__ = [ 'get_compiler_for_source', 'get_filenames_templates_dict', 'get_library_dirs', + 'get_opaque_data', 'get_variable_regex', 'get_wine_shortpath', 'git', @@ -2277,3 +2278,21 @@ def first(iter: T.Iterable[_T], predicate: T.Callable[[_T], bool]) -> T.Optional if predicate(i): return i return None + +class OpaqueData: + def __init__(self, scratch, out, stamp, dep): + self.scratch = scratch + self.out = out + self.stamp = stamp + self.dep = dep + +def get_opaque_data(subproject, target_name): + if subproject: + sub_str = subproject + '_' + else: + sub_str = '' + gendir = 'meson-gen' + return OpaqueData(os.path.join(gendir, sub_str, target_name + '_s'), + os.path.join(gendir, sub_str, target_name), + target_name + '.stamp', + target_name + '.d') diff --git a/test cases/frameworks/14 doxygen/doc/meson.build b/test cases/frameworks/14 doxygen/doc/meson.build index bde2d7c..084151d 100644 --- a/test cases/frameworks/14 doxygen/doc/meson.build +++ b/test cases/frameworks/14 doxygen/doc/meson.build @@ -1,6 +1,8 @@ cdata.set('TOP_SRCDIR', meson.source_root()) cdata.set('TOP_BUILDDIR', meson.build_root()) +wrapper_script = find_program('doxyrunner.py') + doxyfile = configure_file(input: 'Doxyfile.in', output: 'Doxyfile', configuration: cdata, @@ -8,9 +10,8 @@ doxyfile = configure_file(input: 'Doxyfile.in', datadir = join_paths(get_option('datadir'), 'doc', 'spede') -html_target = custom_target('spede-docs', - input: doxyfile, - output: 'html', - command: [doxygen, doxyfile], - install: true, - install_dir: datadir) +opaque_target('spede-docs', + command: wrapper_script, + args: [doxyfile], + install: true, + install_dir: datadir) |