From ad8f24f232290b778dad1152583820512ecf9f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20=22sp1rit=22=E2=80=8B?= Date: Sat, 23 Apr 2022 00:02:13 +0200 Subject: Implement `preserve_path` for install_headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 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 Fixes #3371 --- .../snippets/install_headers_preserve_path_arg.md | 35 ++++++++++++++++++++++ docs/yaml/functions/install_headers.yaml | 16 ++++++++++ mesonbuild/interpreter/interpreter.py | 22 +++++++++++--- .../common/9 header install/child/childdir.h | 3 ++ test cases/common/9 header install/meson.build | 7 +++-- test cases/common/9 header install/test.json | 2 ++ 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 docs/markdown/snippets/install_headers_preserve_path_arg.md create mode 100644 test cases/common/9 header install/child/childdir.h 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" } ] -- cgit v1.1