Add env kwarg in generator.process()

pull/12340/head
Nomura 1 year ago committed by Dylan Baker
parent 03a0d3ddfb
commit 3cac6ea545
  1. 4
      docs/markdown/snippets/env_kwarg_generator_process.md
  2. 9
      docs/yaml/objects/generator.yaml
  3. 3
      mesonbuild/backend/ninjabackend.py
  4. 3
      mesonbuild/backend/vs2010backend.py
  5. 14
      mesonbuild/build.py
  6. 5
      mesonbuild/interpreter/interpreterobjects.py
  7. 1
      mesonbuild/interpreter/kwargs.py
  8. 11
      test cases/common/272 env in generator.process/generate_main.py
  9. 3
      test cases/common/272 env in generator.process/main.template
  10. 21
      test cases/common/272 env in generator.process/meson.build

@ -0,0 +1,4 @@
## generator.process() gains 'env' keyword argument
Like the kwarg of the same name in `custom_target()`, `env` allows
you to set the environment in which the generator will process inputs.

@ -34,3 +34,12 @@ methods:
`subdir/one.input` is processed it generates a file `{target private `subdir/one.input` is processed it generates a file `{target private
directory}/subdir/one.out` as opposed to `{target private directory}/subdir/one.out` as opposed to `{target private
directory}/one.out`. directory}/one.out`.
env:
type: env | list[str] | dict[str]
since: 1.3.0
description: |
environment variables to set, such as
`{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`,
or an [[@env]] object which allows more
sophisticated environment juggling.

@ -2649,7 +2649,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
args = self.replace_paths(target, args, override_subdir=subdir) args = self.replace_paths(target, args, override_subdir=subdir)
cmdlist, reason = self.as_meson_exe_cmdline(exe, cmdlist, reason = self.as_meson_exe_cmdline(exe,
self.replace_extra_args(args, genlist), self.replace_extra_args(args, genlist),
capture=outfiles[0] if generator.capture else None) capture=outfiles[0] if generator.capture else None,
env=genlist.env)
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True) os.makedirs(abs_pdir, exist_ok=True)

@ -211,7 +211,8 @@ class Vs2010Backend(backends.Backend):
self.replace_extra_args(args, genlist), self.replace_extra_args(args, genlist),
workdir=tdir_abs, workdir=tdir_abs,
capture=outfiles[0] if generator.capture else None, capture=outfiles[0] if generator.capture else None,
force_serialize=True force_serialize=True,
env=genlist.env
) )
deps = cmd[-1:] + deps deps = cmd[-1:] + deps
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))

@ -1822,8 +1822,14 @@ class Generator(HoldableObject):
def process_files(self, files: T.Iterable[T.Union[str, File, 'CustomTarget', 'CustomTargetIndex', 'GeneratedList']], def process_files(self, files: T.Iterable[T.Union[str, File, 'CustomTarget', 'CustomTargetIndex', 'GeneratedList']],
state: T.Union['Interpreter', 'ModuleState'], state: T.Union['Interpreter', 'ModuleState'],
preserve_path_from: T.Optional[str] = None, preserve_path_from: T.Optional[str] = None,
extra_args: T.Optional[T.List[str]] = None) -> 'GeneratedList': extra_args: T.Optional[T.List[str]] = None,
output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args if extra_args is not None else []) env: T.Optional[EnvironmentVariables] = None) -> 'GeneratedList':
output = GeneratedList(
self,
state.subdir,
preserve_path_from,
extra_args=extra_args if extra_args is not None else [],
env=env if env is not None else EnvironmentVariables())
for e in files: for e in files:
if isinstance(e, CustomTarget): if isinstance(e, CustomTarget):
@ -1862,6 +1868,7 @@ class GeneratedList(HoldableObject):
subdir: str subdir: str
preserve_path_from: T.Optional[str] preserve_path_from: T.Optional[str]
extra_args: T.List[str] extra_args: T.List[str]
env: T.Optional[EnvironmentVariables]
def __post_init__(self) -> None: def __post_init__(self) -> None:
self.name = self.generator.exe self.name = self.generator.exe
@ -1875,6 +1882,9 @@ class GeneratedList(HoldableObject):
if self.extra_args is None: if self.extra_args is None:
self.extra_args: T.List[str] = [] self.extra_args: T.List[str] = []
if self.env is None:
self.env: EnvironmentVariables = EnvironmentVariables()
if isinstance(self.generator.exe, programs.ExternalProgram): if isinstance(self.generator.exe, programs.ExternalProgram):
if not self.generator.exe.found(): if not self.generator.exe.found():
raise InvalidArguments('Tried to use not-found external program as generator') raise InvalidArguments('Tried to use not-found external program as generator')

@ -21,7 +21,7 @@ from ..interpreterbase import (
typed_pos_args, typed_kwargs, typed_operator, typed_pos_args, typed_kwargs, typed_operator,
noArgsFlattening, noPosargs, noKwargs, unholder_return, noArgsFlattening, noPosargs, noKwargs, unholder_return,
flatten, resolve_second_level_holders, InterpreterException, InvalidArguments, InvalidCode) flatten, resolve_second_level_holders, InterpreterException, InvalidArguments, InvalidCode)
from ..interpreter.type_checking import NoneType, ENV_SEPARATOR_KW, PKGCONFIG_DEFINE_KW from ..interpreter.type_checking import NoneType, ENV_KW, ENV_SEPARATOR_KW, PKGCONFIG_DEFINE_KW
from ..dependencies import Dependency, ExternalLibrary, InternalDependency from ..dependencies import Dependency, ExternalLibrary, InternalDependency
from ..programs import ExternalProgram from ..programs import ExternalProgram
from ..mesonlib import HoldableObject, OptionKey, listify, Popen_safe from ..mesonlib import HoldableObject, OptionKey, listify, Popen_safe
@ -1043,6 +1043,7 @@ class GeneratorHolder(ObjectHolder[build.Generator]):
'generator.process', 'generator.process',
KwargInfo('preserve_path_from', (str, NoneType), since='0.45.0'), KwargInfo('preserve_path_from', (str, NoneType), since='0.45.0'),
KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]), KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]),
ENV_KW.evolve(since='1.3.0')
) )
def process_method(self, def process_method(self,
args: T.Tuple[T.List[T.Union[str, mesonlib.File, 'build.GeneratedTypes']]], args: T.Tuple[T.List[T.Union[str, mesonlib.File, 'build.GeneratedTypes']]],
@ -1060,7 +1061,7 @@ class GeneratorHolder(ObjectHolder[build.Generator]):
'0.57.0', self.interpreter.subproject) '0.57.0', self.interpreter.subproject)
gl = self.held_object.process_files(args[0], self.interpreter, gl = self.held_object.process_files(args[0], self.interpreter,
preserve_path_from, extra_args=kwargs['extra_args']) preserve_path_from, extra_args=kwargs['extra_args'], env=kwargs['env'])
return gl return gl

@ -103,6 +103,7 @@ class GeneratorProcess(TypedDict):
preserve_path_from: T.Optional[str] preserve_path_from: T.Optional[str]
extra_args: T.List[str] extra_args: T.List[str]
env: EnvironmentVariables
class DependencyMethodPartialDependency(TypedDict): class DependencyMethodPartialDependency(TypedDict):

@ -0,0 +1,11 @@
#!/usr/bin/env python3
import os
import sys
ENV_VAR_VALUE = os.environ.get('ENV_VAR_VALUE')
assert ENV_VAR_VALUE is not None
with open(sys.argv[1], 'r') as infile, \
open(sys.argv[2], 'w') as outfile:
outfile.write(infile.read().replace('ENV_VAR_VALUE', ENV_VAR_VALUE))

@ -0,0 +1,3 @@
int main(void) {
return ENV_VAR_VALUE;
}

@ -0,0 +1,21 @@
project('test_env_in_generator_process', 'c')
generate_main_py = find_program('generate_main.py')
main_generator = generator(generate_main_py,
arguments: ['@INPUT@', '@OUTPUT@'],
output: '@BASENAME@' + '.c'
)
main_template = files('main.template')
# With explicit values
my_executable = executable('myexecutable', main_generator.process(main_template, env: {'ENV_VAR_VALUE': '0'}))
test('explicit_value', my_executable)
# With env object
env = environment()
env.set('ENV_VAR_VALUE', '0')
my_executable2 = executable('myexecutable2', main_generator.process(main_template, env: env))
test('env_object', my_executable2)
Loading…
Cancel
Save