Add macro_name option to configure_file

Allow macro_name to be speficied as a parameter to configure_file().
This allows C macro-style include guards to be added to
configure_file()'s output when a template file is not given. This change
simplifies the creation of configure files that define macros with
dynamic names and want the C-style include guards.
pull/11343/head
Nicholas Vinson 1 year ago committed by Xavier Claessens
parent 3c47216fe9
commit b51bce070e
  1. 6
      docs/markdown/snippets/configure_file_macro_guard.md
  2. 7
      docs/yaml/functions/configure_file.yaml
  3. 4
      mesonbuild/interpreter/interpreter.py
  4. 1
      mesonbuild/interpreter/kwargs.py
  5. 19
      mesonbuild/utils/universal.py
  6. 23
      test cases/common/269 configure file output format/expected/config.mg
  7. 9
      test cases/common/269 configure file output format/meson.build

@ -0,0 +1,6 @@
## [[configure_file]] now has a `macro_name` parameter.
This new paramater, `macro_name` allows C macro-style include guards to be added
to [[configure_file]]'s output when a template file is not given. This change
simplifies the creation of configure files that define macros with dynamic names
and want the C-style include guards.

@ -144,3 +144,10 @@ kwargs:
Set the file encoding for the input and output file.
The supported encodings are those of python3, see
[standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings).
macro_name:
type: str
since: 1.3.0
description: |
When specified, macro guards will be used instead of '#pragma once'. The
macro guard name will be the specified name.

@ -2585,6 +2585,7 @@ class Interpreter(InterpreterBase, HoldableObject):
OUTPUT_KW,
KwargInfo('output_format', str, default='c', since='0.47.0', since_values={'json': '1.3.0'},
validator=in_set_validator({'c', 'json', 'nasm'})),
KwargInfo('macro_name', (str, NoneType), default=None, since='1.3.0'),
)
def func_configure_file(self, node: mparser.BaseNode, args: T.List[TYPE_var],
kwargs: kwtypes.ConfigureFile):
@ -2676,7 +2677,8 @@ class Interpreter(InterpreterBase, HoldableObject):
'copy a file to the build dir, use the \'copy:\' keyword '
'argument added in 0.47.0', location=node)
else:
mesonlib.dump_conf_header(ofile_abs, conf, output_format)
macro_name = kwargs['macro_name']
mesonlib.dump_conf_header(ofile_abs, conf, output_format, macro_name)
conf.used = True
elif kwargs['command'] is not None:
if len(inputs) > 1:

@ -296,6 +296,7 @@ class ConfigureFile(TypedDict):
command: T.Optional[T.List[T.Union[build.Executable, ExternalProgram, Compiler, File, str]]]
input: T.List[FileOrString]
configuration: T.Optional[T.Union[T.Dict[str, T.Union[str, int, bool]], build.ConfigurationData]]
macro_name: T.Optional[str]
class Subproject(ExtractRequired):

@ -1351,7 +1351,7 @@ CONF_C_PRELUDE = '''/*
* Do not edit, your changes will be lost.
*/
#pragma once
{}
'''
@ -1360,10 +1360,16 @@ CONF_NASM_PRELUDE = '''; Autogenerated by the Meson build system.
'''
def _dump_c_header(ofile: T.TextIO, cdata: ConfigurationData, output_format: Literal['c', 'nasm']) -> None:
def _dump_c_header(ofile: T.TextIO,
cdata: ConfigurationData,
output_format: Literal['c', 'nasm'],
macro_name: T.Optional[str]) -> None:
format_desc: T.Callable[[str], str]
if output_format == 'c':
prelude = CONF_C_PRELUDE
if macro_name:
prelude = CONF_C_PRELUDE.format('#ifndef {0}\n#define {0}'.format(macro_name))
else:
prelude = CONF_C_PRELUDE.format('#pragma once')
prefix = '#'
format_desc = lambda desc: f'/* {desc} */\n'
else: # nasm
@ -1385,17 +1391,20 @@ def _dump_c_header(ofile: T.TextIO, cdata: ConfigurationData, output_format: Lit
ofile.write(f'{prefix}define {k} {v}\n\n')
else:
raise MesonException('Unknown data type in configuration file entry: ' + k)
if output_format == 'c' and macro_name:
ofile.write('#endif\n')
def dump_conf_header(ofilename: str, cdata: ConfigurationData,
output_format: Literal['c', 'nasm', 'json']) -> None:
output_format: Literal['c', 'nasm', 'json'],
macro_name: T.Optional[str]) -> None:
ofilename_tmp = ofilename + '~'
with open(ofilename_tmp, 'w', encoding='utf-8') as ofile:
if output_format == 'json':
data = {k: v[0] for k, v in cdata.values.items()}
json.dump(data, ofile, sort_keys=True)
else: # c, nasm
_dump_c_header(ofile, cdata, output_format)
_dump_c_header(ofile, cdata, output_format, macro_name)
replace_if_different(ofilename, ofilename_tmp)

@ -0,0 +1,23 @@
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#ifndef CONFIG_MAGNESIUM_H
#define CONFIG_MAGNESIUM_H
#define bool
#undef false
/* ultimate question of life, the universe, and everything */
#define int 42
/* This is
a multiline
description */
#define str "hello world!"
#define unquoted float
#endif

@ -27,12 +27,21 @@ config_json = configure_file(
output: 'config.json'
)
config_mg = configure_file(
configuration: data,
macro_name: 'CONFIG_MAGNESIUM_H',
output_format: 'c',
output: 'config_mg.h'
)
py = find_program('python3')
compare_py = files('compare.py')
expected_config_h = files('expected/config.h')
expected_config_nasm = files('expected/config.nasm')
expected_config_json = files('expected/config.json')
expected_config_mg = files('expected/config.mg')
test('c_output', py, args: [compare_py, expected_config_h, config_h])
test('nasm_output', py, args: [compare_py, expected_config_nasm, config_nasm])
test('json_output', py, args: [compare_py, expected_config_json, config_json])
test('c_mg_output', py, args: [compare_py, expected_config_mg, config_mg])

Loading…
Cancel
Save