aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2022-10-16 18:19:33 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2022-10-16 18:19:33 +0300
commit2b43f1ec1dd72e774162642c91421f4a6ae38f9c (patch)
treef2e544cf9a1dac65797a6ac06ae1cfdc24f504e1
parent5937bbf6ee99d31b2f7d47d4e5cae7892bcb88d8 (diff)
downloadmeson-biggen.zip
meson-biggen.tar.gz
meson-biggen.tar.bz2
Add support for opaque build targets. Closes #10627.biggen
-rw-r--r--mesonbuild/backend/backends.py16
-rw-r--r--mesonbuild/backend/ninjabackend.py10
-rw-r--r--mesonbuild/build.py1
-rw-r--r--mesonbuild/interpreter/interpreter.py19
-rw-r--r--mesonbuild/minstall.py15
-rw-r--r--mesonbuild/utils/universal.py21
-rw-r--r--test cases/frameworks/14 doxygen/doc/meson.build13
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)