aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/install_headers_preserve_path_arg.md35
-rw-r--r--docs/yaml/functions/install_headers.yaml16
-rw-r--r--mesonbuild/interpreter/interpreter.py22
-rw-r--r--test cases/common/9 header install/child/childdir.h3
-rw-r--r--test cases/common/9 header install/meson.build7
-rw-r--r--test cases/common/9 header install/test.json2
6 files changed, 78 insertions, 7 deletions
diff --git a/docs/markdown/snippets/install_headers_preserve_path_arg.md b/docs/markdown/snippets/install_headers_preserve_path_arg.md
new file mode 100644
index 0000000..c41fceb
--- /dev/null
+++ b/docs/markdown/snippets/install_headers_preserve_path_arg.md
@@ -0,0 +1,35 @@
+## Added preserve_path arg to install_headers
+
+The [[install_headers]] function now has an optional argument `preserve_path`
+that allows installing multi-directory headerfile structures that live
+alongside sourcecode with a single command.
+
+For example, the headerfile structure
+
+```meson
+headers = [
+ 'one.h',
+ 'two.h',
+ 'alpha/one.h',
+ 'alpha/two.h',
+ 'alpha/three.h'
+ 'beta/one.h'
+]
+```
+
+can now be passed to `install_headers(headers, subdir: 'mylib', preserve_path: true)`
+and the resulting directory tree will look like
+
+```
+{prefix}
+└── include
+    └── mylib
+       ├── alpha
+       │   ├── one.h
+       │   ├── two.h
+       │   └── three.h
+       ├── beta
+       │   └── one.h
+       ├── one.h
+       └── two.h
+```
diff --git a/docs/yaml/functions/install_headers.yaml b/docs/yaml/functions/install_headers.yaml
index cf8fb9f..50e1c55 100644
--- a/docs/yaml/functions/install_headers.yaml
+++ b/docs/yaml/functions/install_headers.yaml
@@ -29,6 +29,13 @@ example: |
install_headers('common.h', 'proj/kola.h', install_dir : 'cust', subdir : 'myproj')
```
+ This will install `common.h` into `/{prefix}/include` and `kola.h`
+ into `/{prefix}/include/proj/`:
+
+ ```meson
+ install_headers('common.h, 'proj/kola.h', preserve_path : true)
+ ```
+
varargs:
name: file
type: file | str
@@ -54,3 +61,12 @@ kwargs:
and optionally the owner/uid and group/gid for the installed files.
See the `install_mode` kwarg of [[install_data]] for more information.
+
+ preserve_path:
+ type: bool
+ since: 0.63.0
+ default: false
+ description: |
+ Disable stripping child-direcories from header files when installing.
+
+ This is equivalent to GNU Automake's `nobase` option.
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 7b87843c..af83c0e54 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2091,6 +2091,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@typed_kwargs(
'install_headers',
KwargInfo('install_dir', (str, NoneType)),
+ KwargInfo('preserve_path', bool, default=False, since='0.63.0'),
KwargInfo('subdir', (str, NoneType)),
INSTALL_MODE_KW.evolve(since='0.47.0'),
)
@@ -2104,12 +2105,25 @@ class Interpreter(InterpreterBase, HoldableObject):
raise InterpreterException('install_headers: cannot specify both "install_dir" and "subdir". Use only "install_dir".')
if os.path.isabs(install_subdir):
mlog.deprecation('Subdir keyword must not be an absolute path. This will be a hard error in the next release.')
+ else:
+ install_subdir = ''
+
+ dirs = collections.defaultdict(list)
+ ret_headers = []
+ if kwargs['preserve_path']:
+ for file in source_files:
+ dirname = os.path.dirname(file.fname)
+ dirs[dirname].append(file)
+ else:
+ dirs[''].extend(source_files)
- h = build.Headers(source_files, install_subdir, kwargs['install_dir'],
- kwargs['install_mode'], self.subproject)
- self.build.headers.append(h)
+ for childdir in dirs:
+ h = build.Headers(dirs[childdir], os.path.join(install_subdir, childdir), kwargs['install_dir'],
+ kwargs['install_mode'], self.subproject)
+ ret_headers.append(h)
+ self.build.headers.append(h)
- return h
+ return ret_headers
@typed_pos_args('install_man', varargs=(str, mesonlib.File))
@typed_kwargs(
diff --git a/test cases/common/9 header install/child/childdir.h b/test cases/common/9 header install/child/childdir.h
new file mode 100644
index 0000000..5788511
--- /dev/null
+++ b/test cases/common/9 header install/child/childdir.h
@@ -0,0 +1,3 @@
+/* This file goes, depending on the state of `preserve_path` into subdirectory of include root or into the `child` dir of the subdirectory of include root. */
+
+int childdir_func();
diff --git a/test cases/common/9 header install/meson.build b/test cases/common/9 header install/meson.build
index 833b4d4..8c83be6 100644
--- a/test cases/common/9 header install/meson.build
+++ b/test cases/common/9 header install/meson.build
@@ -1,11 +1,12 @@
project('header install')
-as_array = ['subdir.h']
+as_array = ['subdir.h', 'child/childdir.h']
subdir('vanishing_subdir')
subdir('sub')
h1 = install_headers('rootdir.h')
h2 = install_headers(as_array, subdir : 'subdir')
-h3 = install_headers(subheader)
-h4 = install_headers(disabler())
+h3 = install_headers(as_array, subdir : 'subdir', preserve_path : true)
+h4 = install_headers(subheader)
+h5 = install_headers(disabler())
diff --git a/test cases/common/9 header install/test.json b/test cases/common/9 header install/test.json
index eb12cd0..8514c90 100644
--- a/test cases/common/9 header install/test.json
+++ b/test cases/common/9 header install/test.json
@@ -2,6 +2,8 @@
"installed": [
{ "type": "file", "file": "usr/include/rootdir.h" },
{ "type": "file", "file": "usr/include/subdir/subdir.h" },
+ { "type": "file", "file": "usr/include/subdir/childdir.h" },
+ { "type": "file", "file": "usr/include/subdir/child/childdir.h" },
{ "type": "file", "file": "usr/include/vanished.h" },
{ "type": "file", "file": "usr/include/fileheader.h" }
]