aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2020-05-03 23:20:59 +0300
committerGitHub <noreply@github.com>2020-05-03 23:20:59 +0300
commit9a6e79dc6887890ffa6f7198032788caa065a959 (patch)
treed433e3ef2769d2541a88ded5c11335fbba07d229
parent88ba5ffb84d1e352489bbb094bc426174a8b4440 (diff)
parent81f35f15492a35bcb294f7a516459141b1bd73ab (diff)
downloadmeson-9a6e79dc6887890ffa6f7198032788caa065a959.zip
meson-9a6e79dc6887890ffa6f7198032788caa065a959.tar.gz
meson-9a6e79dc6887890ffa6f7198032788caa065a959.tar.bz2
Merge pull request #7060 from dcbaker/install-script-targets
Allow meson.add_*_script to take additional types
-rw-r--r--docs/markdown/Reference-manual.md7
-rw-r--r--docs/markdown/snippets/add_foo_script_type_additions.md24
-rw-r--r--mesonbuild/interpreter.py78
-rw-r--r--test cases/common/104 postconf with args/meson.build7
-rwxr-xr-xtest cases/common/56 install script/customtarget.py19
-rw-r--r--test cases/common/56 install script/meson.build26
-rw-r--r--test cases/common/56 install script/myinstall.py29
-rw-r--r--test cases/common/56 install script/src/a file.txt0
-rw-r--r--test cases/common/56 install script/src/exe.c24
-rw-r--r--test cases/common/56 install script/src/meson.build4
-rw-r--r--test cases/common/56 install script/src/myinstall.py4
-rw-r--r--test cases/common/56 install script/test.json10
-rwxr-xr-xtest cases/common/56 install script/wrap.py6
-rw-r--r--test cases/unit/35 dist script/meson.build1
14 files changed, 217 insertions, 22 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 5c5f56a..fd3408c 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1739,6 +1739,8 @@ the following methods.
0.49.0, the function only accepted a single argument. Since 0.54.0
the `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` environment variables
are set when dist scripts are run.
+ *(Since 0.55.0)* The output of `configure_file`, `files`, and `find_program`
+ as well as strings.
- `add_install_script(script_name, arg1, arg2, ...)` causes the script
given as an argument to be run during the install step, this script
@@ -1746,6 +1748,9 @@ the following methods.
`MESON_BUILD_ROOT`, `MESON_INSTALL_PREFIX`,
`MESON_INSTALL_DESTDIR_PREFIX`, and `MESONINTROSPECT` set.
All positional arguments are passed as parameters.
+ *(Since 0.55.0)* The output of `configure_file`, `files`, `find_program`,
+ `custom_target`, indexes of `custom_target`, `executable`, `library`, and
+ other built targets as well as strings.
*(added 0.54)* If `meson install` is called with the `--quiet` option, the
environment variable `MESON_INSTALL_QUIET` will be set.
@@ -1776,6 +1781,8 @@ the following methods.
executable given as an argument after all project files have been
generated. This script will have the environment variables
`MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` set.
+ *(Since 0.55.0)* The output of `configure_file`, `files`, and `find_program`
+ as well as strings.
- `backend()` *(added 0.37.0)* returns a string representing the
current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, `vs2019`,
diff --git a/docs/markdown/snippets/add_foo_script_type_additions.md b/docs/markdown/snippets/add_foo_script_type_additions.md
new file mode 100644
index 0000000..88a88b2
--- /dev/null
+++ b/docs/markdown/snippets/add_foo_script_type_additions.md
@@ -0,0 +1,24 @@
+## meson.add_*_script methods accept new types
+
+All three (`add_install_script`, `add_dist_script`, and
+`add_postconf_script`) now accept ExternalPrograms (as returned by
+`find_program`), Files, and the output of `configure_file`. The dist and
+postconf methods cannot accept other types because of when they are run.
+While dist could, in theory, take other dependencies, it would require more
+extensive changes, particularly to the backend.
+
+```meson
+meson.add_install_script(find_program('foo'), files('bar'))
+meson.add_dist_script(find_program('foo'), files('bar'))
+meson.add_postconf_script(find_program('foo'), files('bar'))
+```
+
+The install script variant is also able to accept custom_targets,
+custom_target indexes, and build targets (executables, libraries), and can
+use built executables a the script to run
+
+```meson
+installer = executable('installer', ...)
+meson.add_install_script(installer, ...)
+meson.add_install_script('foo.py', installer)
+```
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 441f3c4..6ec4c0e 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1893,48 +1893,98 @@ class MesonMain(InterpreterObject):
'backend': self.backend_method,
})
- def _find_source_script(self, name, args):
+ def _find_source_script(self, prog: T.Union[str, ExecutableHolder], args):
+ if isinstance(prog, ExecutableHolder):
+ prog_path = self.interpreter.backend.get_target_filename(prog.held_object)
+ return build.RunScript([prog_path], args)
+ elif isinstance(prog, ExternalProgramHolder):
+ return build.RunScript(prog.get_command(), args)
+
# Prefer scripts in the current source directory
search_dir = os.path.join(self.interpreter.environment.source_dir,
self.interpreter.subdir)
- key = (name, search_dir)
+ key = (prog, search_dir)
if key in self._found_source_scripts:
found = self._found_source_scripts[key]
else:
- found = dependencies.ExternalProgram(name, search_dir=search_dir)
+ found = dependencies.ExternalProgram(prog, search_dir=search_dir)
if found.found():
self._found_source_scripts[key] = found
else:
m = 'Script or command {!r} not found or not executable'
- raise InterpreterException(m.format(name))
+ raise InterpreterException(m.format(prog))
return build.RunScript(found.get_command(), args)
- @permittedKwargs({})
- def add_install_script_method(self, args, kwargs):
+ def _process_script_args(
+ self, name: str, args: T.List[T.Union[
+ str, mesonlib.File, CustomTargetHolder,
+ CustomTargetIndexHolder, ConfigureFileHolder,
+ ExternalProgramHolder, ExecutableHolder,
+ ]], allow_built: bool = False) -> T.List[str]:
+ script_args = [] # T.List[str]
+ new = False
+ for a in args:
+ a = unholder(a)
+ if isinstance(a, str):
+ script_args.append(a)
+ elif isinstance(a, mesonlib.File):
+ new = True
+ script_args.append(a.rel_to_builddir(self.interpreter.environment.source_dir))
+ elif isinstance(a, (build.BuildTarget, build.CustomTarget, build.CustomTargetIndex)):
+ if not allow_built:
+ raise InterpreterException('Arguments to {} cannot be built'.format(name))
+ new = True
+ script_args.extend([os.path.join(a.get_subdir(), o) for o in a.get_outputs()])
+
+ # This feels really hacky, but I'm not sure how else to fix
+ # this without completely rewriting install script handling.
+ # This is complicated by the fact that the install target
+ # depends on all.
+ if isinstance(a, build.CustomTargetIndex):
+ a.target.build_by_default = True
+ else:
+ a.build_by_default = True
+ elif isinstance(a, build.ConfigureFile):
+ new = True
+ script_args.append(os.path.join(a.subdir, a.targetname))
+ elif isinstance(a, dependencies.ExternalProgram):
+ script_args.extend(a.command)
+ new = True
+ else:
+ raise InterpreterException(
+ 'Arguments to {} must be strings, Files, CustomTargets, '
+ 'Indexes of CustomTargets, or ConfigureFiles'.format(name))
+ if new:
+ FeatureNew('Calling "{}" with File, CustomTaget, Index of CustomTarget, ConfigureFile, Executable, or ExternalProgram'.format(name), '0.55.0').use(
+ self.interpreter.subproject)
+ return script_args
+
+ @permittedKwargs(set())
+ def add_install_script_method(self, args: 'T.Tuple[T.Union[str, ExecutableHolder], T.Union[str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, ConfigureFileHolder], ...]', kwargs):
if len(args) < 1:
raise InterpreterException('add_install_script takes one or more arguments')
- check_stringlist(args, 'add_install_script args must be strings')
- script = self._find_source_script(args[0], args[1:])
+ script_args = self._process_script_args('add_install_script', args[1:], allow_built=True)
+ script = self._find_source_script(args[0], script_args)
self.build.install_scripts.append(script)
- @permittedKwargs({})
+ @permittedKwargs(set())
def add_postconf_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_postconf_script takes one or more arguments')
- check_stringlist(args, 'add_postconf_script arguments must be strings')
- script = self._find_source_script(args[0], args[1:])
+ script_args = self._process_script_args('add_postconf_script', args[1:], allow_built=True)
+ script = self._find_source_script(args[0], script_args)
self.build.postconf_scripts.append(script)
- @permittedKwargs({})
+ @permittedKwargs(set())
def add_dist_script_method(self, args, kwargs):
if len(args) < 1:
raise InterpreterException('add_dist_script takes one or more arguments')
if len(args) > 1:
FeatureNew('Calling "add_dist_script" with multiple arguments', '0.49.0').use(self.interpreter.subproject)
- check_stringlist(args, 'add_dist_script argument must be a string')
if self.interpreter.subproject != '':
raise InterpreterException('add_dist_script may not be used in a subproject.')
- script = self._find_source_script(args[0], args[1:])
+ script_args = self._process_script_args('add_dist_script', args[1:], allow_built=True)
+ script = self._find_source_script(args[0], script_args)
self.build.dist_scripts.append(script)
@noPosargs
diff --git a/test cases/common/104 postconf with args/meson.build b/test cases/common/104 postconf with args/meson.build
index 8510c5b..a34502c 100644
--- a/test cases/common/104 postconf with args/meson.build
+++ b/test cases/common/104 postconf with args/meson.build
@@ -1,5 +1,10 @@
project('postconf script', 'c')
-meson.add_postconf_script('postconf.py', '5', '33')
+conf = configure_file(
+ configuration : configuration_data(),
+ output : 'out'
+)
+
+meson.add_postconf_script(find_program('postconf.py'), '5', '33', conf)
test('post', executable('prog', 'prog.c'))
diff --git a/test cases/common/56 install script/customtarget.py b/test cases/common/56 install script/customtarget.py
new file mode 100755
index 0000000..e28373a
--- /dev/null
+++ b/test cases/common/56 install script/customtarget.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('dirname')
+ args = parser.parse_args()
+
+ with open(os.path.join(args.dirname, '1.txt'), 'w') as f:
+ f.write('')
+ with open(os.path.join(args.dirname, '2.txt'), 'w') as f:
+ f.write('')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/common/56 install script/meson.build b/test cases/common/56 install script/meson.build
index 6351518..e80e666 100644
--- a/test cases/common/56 install script/meson.build
+++ b/test cases/common/56 install script/meson.build
@@ -5,3 +5,29 @@ meson.add_install_script('myinstall.py', 'diiba/daaba', 'file.dat')
meson.add_install_script('myinstall.py', 'this/should', 'also-work.dat')
subdir('src')
+
+meson.add_install_script('myinstall.py', 'dir', afile, '--mode=copy')
+
+data = configuration_data()
+data.set10('foo', true)
+conf = configure_file(
+ configuration : data,
+ output : 'conf.txt'
+)
+
+meson.add_install_script('myinstall.py', 'dir', conf, '--mode=copy')
+
+t = custom_target(
+ 'ct',
+ command : [find_program('customtarget.py'), '@OUTDIR@'],
+ output : ['1.txt', '2.txt'],
+)
+
+meson.add_install_script('myinstall.py', 'customtarget', t, '--mode=copy')
+meson.add_install_script('myinstall.py', 'customtargetindex', t[0], '--mode=copy')
+
+meson.add_install_script(exe, 'generated.txt')
+wrap = find_program('wrap.py')
+# Yes, these are getting silly
+meson.add_install_script(wrap, exe, 'wrapped.txt')
+meson.add_install_script(wrap, wrap, exe, 'wrapped2.txt')
diff --git a/test cases/common/56 install script/myinstall.py b/test cases/common/56 install script/myinstall.py
index 812561e..a573342 100644
--- a/test cases/common/56 install script/myinstall.py
+++ b/test cases/common/56 install script/myinstall.py
@@ -1,12 +1,31 @@
#!/usr/bin/env python3
+import argparse
import os
-import sys
+import shutil
prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
-dirname = os.path.join(prefix, sys.argv[1])
-os.makedirs(dirname)
-with open(os.path.join(dirname, sys.argv[2]), 'w') as f:
- f.write('')
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('dirname')
+ parser.add_argument('files', nargs='+')
+ parser.add_argument('--mode', action='store', default='create', choices=['create', 'copy'])
+ args = parser.parse_args()
+
+ dirname = os.path.join(prefix, args.dirname)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ if args.mode == 'create':
+ for name in args.files:
+ with open(os.path.join(dirname, name), 'w') as f:
+ f.write('')
+ else:
+ for name in args.files:
+ shutil.copy(name, dirname)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/common/56 install script/src/a file.txt b/test cases/common/56 install script/src/a file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/56 install script/src/a file.txt
diff --git a/test cases/common/56 install script/src/exe.c b/test cases/common/56 install script/src/exe.c
new file mode 100644
index 0000000..b573b91
--- /dev/null
+++ b/test cases/common/56 install script/src/exe.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char * argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "Takes exactly 2 arguments\n");
+ return 1;
+ }
+
+ char * dirname = getenv("MESON_INSTALL_DESTDIR_PREFIX");
+ char * fullname = malloc(strlen(dirname) + 1 + strlen(argv[1]) + 1);
+ strcpy(fullname, dirname);
+ strcat(fullname, "/");
+ strcat(fullname, argv[1]);
+
+ FILE * fp = fopen(fullname, "w");
+ fputs("Some text\n", fp);
+ fclose(fp);
+
+ free(fullname);
+
+ return 0;
+}
diff --git a/test cases/common/56 install script/src/meson.build b/test cases/common/56 install script/src/meson.build
index b23574a..1db424f 100644
--- a/test cases/common/56 install script/src/meson.build
+++ b/test cases/common/56 install script/src/meson.build
@@ -1 +1,5 @@
meson.add_install_script('myinstall.py', 'this/does', 'something-different.dat')
+
+afile = files('a file.txt')
+
+exe = executable('exe', 'exe.c', install : false, native : true)
diff --git a/test cases/common/56 install script/src/myinstall.py b/test cases/common/56 install script/src/myinstall.py
index 3b7ce37..3a9d89b 100644
--- a/test cases/common/56 install script/src/myinstall.py
+++ b/test cases/common/56 install script/src/myinstall.py
@@ -7,6 +7,8 @@ prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
dirname = os.path.join(prefix, sys.argv[1])
-os.makedirs(dirname)
+if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
with open(os.path.join(dirname, sys.argv[2] + '.in'), 'w') as f:
f.write('')
diff --git a/test cases/common/56 install script/test.json b/test cases/common/56 install script/test.json
index d17625f..b2a5971 100644
--- a/test cases/common/56 install script/test.json
+++ b/test cases/common/56 install script/test.json
@@ -4,6 +4,14 @@
{"type": "pdb", "file": "usr/bin/prog"},
{"type": "file", "file": "usr/diiba/daaba/file.dat"},
{"type": "file", "file": "usr/this/should/also-work.dat"},
- {"type": "file", "file": "usr/this/does/something-different.dat.in"}
+ {"type": "file", "file": "usr/this/does/something-different.dat.in"},
+ {"type": "file", "file": "usr/dir/a file.txt"},
+ {"type": "file", "file": "usr/dir/conf.txt"},
+ {"type": "file", "file": "usr/customtarget/1.txt"},
+ {"type": "file", "file": "usr/customtarget/2.txt"},
+ {"type": "file", "file": "usr/customtargetindex/1.txt"},
+ {"type": "file", "file": "usr/generated.txt"},
+ {"type": "file", "file": "usr/wrapped.txt"},
+ {"type": "file", "file": "usr/wrapped2.txt"}
]
}
diff --git a/test cases/common/56 install script/wrap.py b/test cases/common/56 install script/wrap.py
new file mode 100755
index 0000000..87508e0
--- /dev/null
+++ b/test cases/common/56 install script/wrap.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import subprocess
+import sys
+
+subprocess.run(sys.argv[1:])
diff --git a/test cases/unit/35 dist script/meson.build b/test cases/unit/35 dist script/meson.build
index fd672a9..2ae9438 100644
--- a/test cases/unit/35 dist script/meson.build
+++ b/test cases/unit/35 dist script/meson.build
@@ -5,3 +5,4 @@ exe = executable('comparer', 'prog.c')
test('compare', exe)
meson.add_dist_script('replacer.py', '"incorrect"', '"correct"')
+meson.add_dist_script(find_program('replacer.py'), '"incorrect"', '"correct"')