aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/install_sources_preserve_path_arg.md8
-rw-r--r--docs/yaml/functions/install_data.yaml9
-rw-r--r--mesonbuild/interpreter/interpreter.py32
-rw-r--r--mesonbuild/interpreter/type_checking.py2
-rw-r--r--mesonbuild/modules/python.py14
-rw-r--r--test cases/common/252 install data structured/dir1/bad0
-rw-r--r--test cases/common/252 install data structured/dir1/file10
-rw-r--r--test cases/common/252 install data structured/dir1/file20
-rw-r--r--test cases/common/252 install data structured/dir1/file30
-rw-r--r--test cases/common/252 install data structured/dir2/bad0
-rw-r--r--test cases/common/252 install data structured/dir2/file10
-rw-r--r--test cases/common/252 install data structured/dir2/file20
-rw-r--r--test cases/common/252 install data structured/dir2/file30
-rw-r--r--test cases/common/252 install data structured/dir3/bad0
-rw-r--r--test cases/common/252 install data structured/dir3/file10
-rw-r--r--test cases/common/252 install data structured/dir3/file20
-rw-r--r--test cases/common/252 install data structured/dir3/file30
-rw-r--r--test cases/common/252 install data structured/meson.build16
-rw-r--r--test cases/common/252 install data structured/pysrc/__init__.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/bad.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/bar.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/foo.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/meson.build11
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/__init__.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/bad.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/baz.py1
-rw-r--r--test cases/common/252 install data structured/test.json18
-rw-r--r--test cases/python/7 install path/meson.build2
-rw-r--r--test cases/python/7 install path/structured/alpha/one.py0
-rw-r--r--test cases/python/7 install path/structured/alpha/three.py0
-rw-r--r--test cases/python/7 install path/structured/alpha/two.py0
-rw-r--r--test cases/python/7 install path/structured/beta/one.py0
-rw-r--r--test cases/python/7 install path/structured/meson.build9
-rw-r--r--test cases/python/7 install path/structured/one.py0
-rw-r--r--test cases/python/7 install path/structured/two.py0
-rw-r--r--test cases/python/7 install path/test.json6
36 files changed, 123 insertions, 11 deletions
diff --git a/docs/markdown/snippets/install_sources_preserve_path_arg.md b/docs/markdown/snippets/install_sources_preserve_path_arg.md
new file mode 100644
index 0000000..0bc37f2
--- /dev/null
+++ b/docs/markdown/snippets/install_sources_preserve_path_arg.md
@@ -0,0 +1,8 @@
+## Added preserve_path arg to install_data
+
+The [[install_data]] function now has an optional argument `preserve_path`
+that allows installing multi-directory data file structures that live
+alongside source code with a single command.
+
+This is also available in the specialized `py_installation.install_sources`
+method.
diff --git a/docs/yaml/functions/install_data.yaml b/docs/yaml/functions/install_data.yaml
index 3bb9802..191c612 100644
--- a/docs/yaml/functions/install_data.yaml
+++ b/docs/yaml/functions/install_data.yaml
@@ -43,6 +43,15 @@ kwargs:
to install only a subset of the files. By default these files have no install
tag which means they are not being installed when `--tags` argument is specified.
+ preserve_path:
+ type: bool
+ since: 0.64.0
+ default: false
+ description: |
+ Disable stripping child-directories from data files when installing.
+
+ This is equivalent to GNU Automake's `nobase` option.
+
rename:
type: list[str]
since: 0.46.0
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index c2f0813..2f31815 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -79,6 +79,7 @@ from .type_checking import (
INSTALL_TAG_KW,
LANGUAGE_KW,
NATIVE_KW,
+ PRESERVE_PATH_KW,
REQUIRED_KW,
SOURCES_KW,
VARIABLES_KW,
@@ -2094,7 +2095,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@typed_pos_args('install_headers', varargs=(str, mesonlib.File))
@typed_kwargs(
'install_headers',
- KwargInfo('preserve_path', bool, default=False, since='0.63.0'),
+ PRESERVE_PATH_KW,
KwargInfo('subdir', (str, NoneType)),
INSTALL_MODE_KW.evolve(since='0.47.0'),
INSTALL_DIR_KW,
@@ -2302,6 +2303,7 @@ class Interpreter(InterpreterBase, HoldableObject):
INSTALL_MODE_KW.evolve(since='0.38.0'),
INSTALL_TAG_KW.evolve(since='0.60.0'),
INSTALL_DIR_KW,
+ PRESERVE_PATH_KW.evolve(since='0.64.0'),
)
def func_install_data(self, node: mparser.BaseNode,
args: T.Tuple[T.List['mesonlib.FileOrString']],
@@ -2321,19 +2323,35 @@ class Interpreter(InterpreterBase, HoldableObject):
else:
install_dir_name = '{datadir}'
return self.install_data_impl(sources, kwargs['install_dir'], kwargs['install_mode'],
- rename, kwargs['install_tag'], install_dir_name)
+ rename, kwargs['install_tag'], install_dir_name,
+ preserve_path=kwargs['preserve_path'])
def install_data_impl(self, sources: T.List[mesonlib.File], install_dir: T.Optional[str],
install_mode: FileMode, rename: T.Optional[str],
tag: T.Optional[str],
install_dir_name: T.Optional[str] = None,
- install_data_type: T.Optional[str] = None) -> build.Data:
+ install_data_type: T.Optional[str] = None,
+ preserve_path: bool = False) -> build.Data:
"""Just the implementation with no validation."""
- data = build.Data(sources, install_dir, install_dir_name or install_dir, install_mode,
- self.subproject, rename, tag, install_data_type)
- self.build.data.append(data)
- return data
+ idir = install_dir or ''
+ idir_name = install_dir_name or idir
+ dirs = collections.defaultdict(list)
+ ret_data = []
+ if preserve_path:
+ for file in sources:
+ dirname = os.path.dirname(file.fname)
+ dirs[dirname].append(file)
+ else:
+ dirs[''].extend(sources)
+
+ for childdir, files in dirs.items():
+ d = build.Data(files, os.path.join(idir, childdir), os.path.join(idir_name, childdir),
+ install_mode, self.subproject, rename, tag, install_data_type)
+ ret_data.append(d)
+
+ self.build.data.extend(ret_data)
+ return ret_data
@typed_pos_args('install_subdir', str)
@typed_kwargs(
diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py
index e0ddb1b..09f734b 100644
--- a/mesonbuild/interpreter/type_checking.py
+++ b/mesonbuild/interpreter/type_checking.py
@@ -438,3 +438,5 @@ VARIABLES_KW: KwargInfo[T.Dict[str, str]] = KwargInfo(
convertor=variables_convertor,
default={},
)
+
+PRESERVE_PATH_KW: KwargInfo[bool] = KwargInfo('preserve_path', bool, default=False, since='0.63.0')
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 47dc674..5a6daa0 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -30,7 +30,7 @@ from ..dependencies.base import process_method_kw
from ..dependencies.detect import get_dep_identifier
from ..environment import detect_cpu_family
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
-from ..interpreter.type_checking import NoneType
+from ..interpreter.type_checking import NoneType, PRESERVE_PATH_KW
from ..interpreterbase import (
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
InvalidArguments, typed_pos_args, typed_kwargs, KwargInfo,
@@ -588,8 +588,13 @@ class PythonInstallation(ExternalProgramHolder):
return dep
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
- @typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,
- KwargInfo('install_tag', (str, NoneType), since='0.60.0'))
+ @typed_kwargs(
+ 'python_installation.install_sources',
+ _PURE_KW,
+ _SUBDIR_KW,
+ PRESERVE_PATH_KW,
+ KwargInfo('install_tag', (str, NoneType), since='0.60.0')
+ )
def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]],
kwargs: 'PyInstallKw') -> 'Data':
tag = kwargs['install_tag'] or 'runtime'
@@ -597,7 +602,8 @@ class PythonInstallation(ExternalProgramHolder):
self.interpreter.source_strings_to_files(args[0]),
self._get_install_dir_impl(kwargs['pure'], kwargs['subdir']),
mesonlib.FileMode(), rename=None, tag=tag, install_data_type='python',
- install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']))
+ install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']),
+ preserve_path=kwargs['preserve_path'])
@noPosargs
@typed_kwargs('python_installation.install_dir', _PURE_KW, _SUBDIR_KW)
diff --git a/test cases/common/252 install data structured/dir1/bad b/test cases/common/252 install data structured/dir1/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/bad
diff --git a/test cases/common/252 install data structured/dir1/file1 b/test cases/common/252 install data structured/dir1/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file1
diff --git a/test cases/common/252 install data structured/dir1/file2 b/test cases/common/252 install data structured/dir1/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file2
diff --git a/test cases/common/252 install data structured/dir1/file3 b/test cases/common/252 install data structured/dir1/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file3
diff --git a/test cases/common/252 install data structured/dir2/bad b/test cases/common/252 install data structured/dir2/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/bad
diff --git a/test cases/common/252 install data structured/dir2/file1 b/test cases/common/252 install data structured/dir2/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file1
diff --git a/test cases/common/252 install data structured/dir2/file2 b/test cases/common/252 install data structured/dir2/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file2
diff --git a/test cases/common/252 install data structured/dir2/file3 b/test cases/common/252 install data structured/dir2/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file3
diff --git a/test cases/common/252 install data structured/dir3/bad b/test cases/common/252 install data structured/dir3/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/bad
diff --git a/test cases/common/252 install data structured/dir3/file1 b/test cases/common/252 install data structured/dir3/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file1
diff --git a/test cases/common/252 install data structured/dir3/file2 b/test cases/common/252 install data structured/dir3/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file2
diff --git a/test cases/common/252 install data structured/dir3/file3 b/test cases/common/252 install data structured/dir3/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file3
diff --git a/test cases/common/252 install data structured/meson.build b/test cases/common/252 install data structured/meson.build
new file mode 100644
index 0000000..9d29794
--- /dev/null
+++ b/test cases/common/252 install data structured/meson.build
@@ -0,0 +1,16 @@
+project('install structured data')
+
+install_data(
+ 'dir1/file1',
+ 'dir1/file2',
+ 'dir1/file3',
+ 'dir2/file1',
+ 'dir2/file2',
+ 'dir2/file3',
+ 'dir3/file1',
+ 'dir3/file2',
+ 'dir3/file3',
+ install_dir: get_option('datadir'),
+ preserve_path: true,
+)
+subdir('pysrc')
diff --git a/test cases/common/252 install data structured/pysrc/__init__.py b/test cases/common/252 install data structured/pysrc/__init__.py
new file mode 100644
index 0000000..cb831ca
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/__init__.py
@@ -0,0 +1 @@
+'''init for mod'''
diff --git a/test cases/common/252 install data structured/pysrc/bad.py b/test cases/common/252 install data structured/pysrc/bad.py
new file mode 100644
index 0000000..d2f862e
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/bad.py
@@ -0,0 +1 @@
+'''mod.bad should not be installed'''
diff --git a/test cases/common/252 install data structured/pysrc/bar.py b/test cases/common/252 install data structured/pysrc/bar.py
new file mode 100644
index 0000000..1ac5d08
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/bar.py
@@ -0,0 +1 @@
+'''mod.bar module'''
diff --git a/test cases/common/252 install data structured/pysrc/foo.py b/test cases/common/252 install data structured/pysrc/foo.py
new file mode 100644
index 0000000..eff906b
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/foo.py
@@ -0,0 +1 @@
+'''mod.foo module'''
diff --git a/test cases/common/252 install data structured/pysrc/meson.build b/test cases/common/252 install data structured/pysrc/meson.build
new file mode 100644
index 0000000..64c0f4d
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/meson.build
@@ -0,0 +1,11 @@
+py_inst = import('python').find_installation()
+
+py_inst.install_sources(
+ '__init__.py',
+ 'foo.py',
+ 'bar.py',
+ 'submod/__init__.py',
+ 'submod/baz.py',
+ subdir: 'mod',
+ preserve_path: true,
+)
diff --git a/test cases/common/252 install data structured/pysrc/submod/__init__.py b/test cases/common/252 install data structured/pysrc/submod/__init__.py
new file mode 100644
index 0000000..65a3500
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/__init__.py
@@ -0,0 +1 @@
+'''init for submod'''
diff --git a/test cases/common/252 install data structured/pysrc/submod/bad.py b/test cases/common/252 install data structured/pysrc/submod/bad.py
new file mode 100644
index 0000000..6661a6d
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/bad.py
@@ -0,0 +1 @@
+'''mod.submod.bad should not be installed'''
diff --git a/test cases/common/252 install data structured/pysrc/submod/baz.py b/test cases/common/252 install data structured/pysrc/submod/baz.py
new file mode 100644
index 0000000..d0b2904
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/baz.py
@@ -0,0 +1 @@
+'''mod.submod.baz module'''
diff --git a/test cases/common/252 install data structured/test.json b/test cases/common/252 install data structured/test.json
new file mode 100644
index 0000000..f4dc2df
--- /dev/null
+++ b/test cases/common/252 install data structured/test.json
@@ -0,0 +1,18 @@
+{
+ "installed": [
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/__init__.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/foo.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/bar.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/__init__.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/baz.py"},
+ {"type": "file", "file": "usr/share/dir1/file1"},
+ {"type": "file", "file": "usr/share/dir1/file2"},
+ {"type": "file", "file": "usr/share/dir1/file3"},
+ {"type": "file", "file": "usr/share/dir2/file1"},
+ {"type": "file", "file": "usr/share/dir2/file2"},
+ {"type": "file", "file": "usr/share/dir2/file3"},
+ {"type": "file", "file": "usr/share/dir3/file1"},
+ {"type": "file", "file": "usr/share/dir3/file2"},
+ {"type": "file", "file": "usr/share/dir3/file3"}
+ ]
+}
diff --git a/test cases/python/7 install path/meson.build b/test cases/python/7 install path/meson.build
index 4a7df7e..5f0f7df 100644
--- a/test cases/python/7 install path/meson.build
+++ b/test cases/python/7 install path/meson.build
@@ -8,3 +8,5 @@ project('install path',
py = import('python').find_installation()
py.install_sources('test.py')
py.install_sources('test.py', pure: false)
+
+subdir('structured')
diff --git a/test cases/python/7 install path/structured/alpha/one.py b/test cases/python/7 install path/structured/alpha/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/one.py
diff --git a/test cases/python/7 install path/structured/alpha/three.py b/test cases/python/7 install path/structured/alpha/three.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/three.py
diff --git a/test cases/python/7 install path/structured/alpha/two.py b/test cases/python/7 install path/structured/alpha/two.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/two.py
diff --git a/test cases/python/7 install path/structured/beta/one.py b/test cases/python/7 install path/structured/beta/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/beta/one.py
diff --git a/test cases/python/7 install path/structured/meson.build b/test cases/python/7 install path/structured/meson.build
new file mode 100644
index 0000000..6c85587
--- /dev/null
+++ b/test cases/python/7 install path/structured/meson.build
@@ -0,0 +1,9 @@
+py.install_sources(
+ 'one.py',
+ 'two.py',
+ 'alpha/one.py',
+ 'alpha/two.py',
+ 'alpha/three.py',
+ 'beta/one.py',
+ preserve_path: true,
+)
diff --git a/test cases/python/7 install path/structured/one.py b/test cases/python/7 install path/structured/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/one.py
diff --git a/test cases/python/7 install path/structured/two.py b/test cases/python/7 install path/structured/two.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/two.py
diff --git a/test cases/python/7 install path/test.json b/test cases/python/7 install path/test.json
index f03ada8..9b05b66 100644
--- a/test cases/python/7 install path/test.json
+++ b/test cases/python/7 install path/test.json
@@ -1,5 +1,11 @@
{
"installed": [
+ {"type": "file", "file": "pure/one.py"},
+ {"type": "file", "file": "pure/two.py"},
+ {"type": "file", "file": "pure/alpha/one.py"},
+ {"type": "file", "file": "pure/alpha/two.py"},
+ {"type": "file", "file": "pure/alpha/three.py"},
+ {"type": "file", "file": "pure/beta/one.py"},
{"type": "file", "file": "plat/test.py"},
{"type": "file", "file": "pure/test.py"}
]