aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2021-03-01 22:05:19 -0500
committerXavier Claessens <xclaesse@gmail.com>2021-03-18 08:41:21 -0400
commit3990754bf55727ef5593769b48f0a03c6b7a3671 (patch)
treeb00148182600db24bd01b0041de5274b15437433
parent848e360450c397f1dcfc4d8d3f614df05806699a (diff)
downloadmeson-3990754bf55727ef5593769b48f0a03c6b7a3671.zip
meson-3990754bf55727ef5593769b48f0a03c6b7a3671.tar.gz
meson-3990754bf55727ef5593769b48f0a03c6b7a3671.tar.bz2
Allow add_dist_script() in subprojects
Fixes: #8440.
-rw-r--r--docs/markdown/Reference-manual.md21
-rw-r--r--docs/markdown/snippets/dist_script.md14
-rw-r--r--mesonbuild/interpreter.py3
-rw-r--r--mesonbuild/mdist.py16
-rwxr-xr-xrun_unittests.py4
-rw-r--r--test cases/unit/35 dist script/meson.build2
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/dist-script.py12
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/meson.build11
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/meson_options.txt1
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/prog.c1
10 files changed, 73 insertions, 12 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index d81be47..6e18e68 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1907,16 +1907,25 @@ the following methods.
archived. Note that this runs the script file that is in the
_staging_ directory, not the one in the source directory. If the
script file can not be found in the staging directory, it is a hard
- error. This command can only invoked from the main project, calling
- it from a subproject is a hard error. *(since 0.49.0)* Accepts multiple arguments
- for the script. *(since 0.54.0)* The `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT`
- environment variables are set when dist scripts are run.
-
+ error. The `MESON_DIST_ROOT` environment variables is set when dist scripts is
+ run.
+ *(since 0.49.0)* Accepts multiple arguments for the script.
+ *(since 0.54.0)* The `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT`
+ environment variables are set when dist scripts are run. They are path to the
+ root source and build directory of the main project, even when the script
+ comes from a subproject.
*(since 0.55.0)* The output of `configure_file`, `files`, and `find_program`
as well as strings.
-
*(since 0.57.0)* `file` objects and the output of `configure_file` may be
used as the `script_name` parameter.
+ *(since 0.58.0)* This command can be invoked from a subproject, it was a hard
+ error in earlier versions. Subproject dist scripts will only be executed
+ when running `meson dist --include-subprojects`. `MESON_PROJECT_SOURCE_ROOT`,
+ `MESON_PROJECT_BUILD_ROOT` and `MESON_PROJECT_DIST_ROOT` environment
+ variables are set when dist scripts are run. They are identical to
+ `MESON_SOURCE_ROOT`, `MESON_BUILD_ROOT` and `MESON_DIST_ROOT` for main project
+ scripts, but for subproject scripts they have the path to the root of the
+ subproject appended, usually `subprojects/<subproject-name>`.
- `add_install_script(script_name, arg1, arg2, ...)`: causes the script
given as an argument to be run during the install step, this script
diff --git a/docs/markdown/snippets/dist_script.md b/docs/markdown/snippets/dist_script.md
new file mode 100644
index 0000000..93b97aa
--- /dev/null
+++ b/docs/markdown/snippets/dist_script.md
@@ -0,0 +1,14 @@
+## `meson.add_dist_script()` allowd in subprojects
+
+`meson.add_dist_script()` can now be invoked from a subproject, it was a hard
+error in earlier versions. Subproject dist scripts will only be executed
+when running `meson dist --include-subprojects`. `MESON_PROJECT_SOURCE_ROOT`,
+`MESON_PROJECT_BUILD_ROOT` and `MESON_PROJECT_DIST_ROOT` environment variables
+are set when dist scripts are run. They are identical to `MESON_SOURCE_ROOT`,
+`MESON_BUILD_ROOT` and `MESON_DIST_ROOT` for main project scripts, but for
+subproject scripts they have the path to the root of the subproject appended,
+usually `subprojects/<subproject-name>`.
+
+Note that existing dist scripts likely need to be modified to use those new
+environment variables instead of `MESON_DIST_ROOT` to work properly when used
+from a subproject.
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index ac0d786..6a51f3d 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2028,7 +2028,8 @@ class MesonMain(InterpreterObject):
FeatureNew.single_use('Passing file object to script parameter of add_dist_script',
'0.57.0', self.interpreter.subproject)
if self.interpreter.subproject != '':
- raise InterpreterException('add_dist_script may not be used in a subproject.')
+ FeatureNew.single_use('Calling "add_dist_script" in a subproject',
+ '0.58.0', self.interpreter.subproject)
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)
diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py
index 3085f44..36bad71 100644
--- a/mesonbuild/mdist.py
+++ b/mesonbuild/mdist.py
@@ -78,13 +78,19 @@ def process_submodules(dirname):
del_gitfiles(os.path.join(dirname, v))
-def run_dist_scripts(src_root, bld_root, dist_root, dist_scripts):
+def run_dist_scripts(src_root, bld_root, dist_root, dist_scripts, subprojects):
assert(os.path.isabs(dist_root))
env = {}
env['MESON_DIST_ROOT'] = dist_root
env['MESON_SOURCE_ROOT'] = src_root
env['MESON_BUILD_ROOT'] = bld_root
for d in dist_scripts:
+ if d.subproject and d.subproject not in subprojects:
+ continue
+ subdir = subprojects.get(d.subproject, '')
+ env['MESON_PROJECT_DIST_ROOT'] = os.path.join(dist_root, subdir)
+ env['MESON_PROJECT_SOURCE_ROOT'] = os.path.join(src_root, subdir)
+ env['MESON_PROJECT_BUILD_ROOT'] = os.path.join(bld_root, subdir)
name = ' '.join(d.cmd_args)
print(f'Running custom dist script {name!r}')
try:
@@ -141,7 +147,7 @@ def git_clone(src_root, distdir):
def create_dist_git(dist_name, archives, src_root, bld_root, dist_sub, dist_scripts, subprojects):
distdir = os.path.join(dist_sub, dist_name)
git_clone(src_root, distdir)
- for path in subprojects:
+ for path in subprojects.values():
sub_src_root = os.path.join(src_root, path)
sub_distdir = os.path.join(distdir, path)
if os.path.exists(sub_distdir):
@@ -150,7 +156,7 @@ def create_dist_git(dist_name, archives, src_root, bld_root, dist_sub, dist_scri
git_clone(sub_src_root, sub_distdir)
else:
shutil.copytree(sub_src_root, sub_distdir)
- run_dist_scripts(src_root, bld_root, distdir, dist_scripts)
+ run_dist_scripts(src_root, bld_root, distdir, dist_scripts, subprojects)
output_names = []
for a in archives:
compressed_name = distdir + archive_extension[a]
@@ -278,13 +284,13 @@ def run(options):
archives = determine_archives_to_generate(options)
- subprojects = []
+ subprojects = {}
extra_meson_args = []
if options.include_subprojects:
subproject_dir = os.path.join(src_root, b.subproject_dir)
for sub in b.subprojects:
directory = wrap.get_directory(subproject_dir, sub)
- subprojects.append(os.path.join(b.subproject_dir, directory))
+ subprojects[sub] = os.path.join(b.subproject_dir, directory)
extra_meson_args.append('-Dwrap_mode=nodownload')
if is_git(src_root):
diff --git a/run_unittests.py b/run_unittests.py
index 03e931a..82689be 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -3189,6 +3189,10 @@ class AllPlatformTests(BasePlatformTests):
_git_init(project_dir)
self.init(project_dir)
self.build('dist')
+
+ self.new_builddir()
+ self.init(project_dir, extra_args=['-Dsub:broken_dist_script=false'])
+ self._run(self.meson_command + ['dist', '--include-subprojects'], workdir=self.builddir)
except PermissionError:
# When run under Windows CI, something (virus scanner?)
# holds on to the git files so cleaning up the dir
diff --git a/test cases/unit/35 dist script/meson.build b/test cases/unit/35 dist script/meson.build
index 2ae9438..8db4235 100644
--- a/test cases/unit/35 dist script/meson.build
+++ b/test cases/unit/35 dist script/meson.build
@@ -6,3 +6,5 @@ test('compare', exe)
meson.add_dist_script('replacer.py', '"incorrect"', '"correct"')
meson.add_dist_script(find_program('replacer.py'), '"incorrect"', '"correct"')
+
+subproject('sub')
diff --git a/test cases/unit/35 dist script/subprojects/sub/dist-script.py b/test cases/unit/35 dist script/subprojects/sub/dist-script.py
new file mode 100644
index 0000000..1274f29
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/dist-script.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import os
+import pathlib
+import sys
+
+assert sys.argv[1] == 'success'
+
+source_root = pathlib.Path(os.environ['MESON_PROJECT_DIST_ROOT'])
+modfile = source_root / 'prog.c'
+with modfile.open('w') as f:
+ f.write('int main(){return 0;}')
diff --git a/test cases/unit/35 dist script/subprojects/sub/meson.build b/test cases/unit/35 dist script/subprojects/sub/meson.build
new file mode 100644
index 0000000..6128613
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/meson.build
@@ -0,0 +1,11 @@
+project('sub')
+
+if get_option('broken_dist_script')
+ # Make sure we can add a dist script in a subproject, but it won't be run
+ # if not using --include-subprojects.
+ meson.add_dist_script('dist-script.py', 'broken')
+else
+ # The dist script replace prog.c with something that actually build.
+ meson.add_dist_script('dist-script.py', 'success')
+ executable('prog', 'prog.c')
+endif
diff --git a/test cases/unit/35 dist script/subprojects/sub/meson_options.txt b/test cases/unit/35 dist script/subprojects/sub/meson_options.txt
new file mode 100644
index 0000000..8f52e0f
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/meson_options.txt
@@ -0,0 +1 @@
+option('broken_dist_script', type: 'boolean', value: true)
diff --git a/test cases/unit/35 dist script/subprojects/sub/prog.c b/test cases/unit/35 dist script/subprojects/sub/prog.c
new file mode 100644
index 0000000..049b36a
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/prog.c
@@ -0,0 +1 @@
+#error This should be replaced by a program during dist