@FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding'])
@FeatureNewKwargs('configure_file', '0.46.0', ['format'])
@FeatureNewKwargs('configure_file', '0.41.0', ['capture'])
@FeatureNewKwargs('configure_file', '0.50.0', ['install'])
@FeatureNewKwargs('configure_file', '0.52.0', ['depfile'])
@permittedKwargs(permitted_kwargs['configure_file'])
def func_configure_file(self, node, args, kwargs):
    if (len(args) > 0):
        raise InterpreterException('configure_file takes only keyword arguments.')
    if ('output' not in kwargs):
        raise InterpreterException('Required keyword argument "output" not defined.')
    actions = set(['configuration', 'command', 'copy']).intersection(kwargs.keys())
    if (len(actions) == 0):
        raise InterpreterException("Must specify an action with one of these keyword arguments: 'configuration', 'command', or 'copy'.")
    elif (len(actions) == 2):
        raise InterpreterException('Must not specify both {!r} and {!r} keyword arguments since they are mutually exclusive.'.format(*actions))
    elif (len(actions) == 3):
        raise InterpreterException('Must specify one of {!r}, {!r}, and {!r} keyword arguments since they are mutually exclusive.'.format(*actions))
    if ('capture' in kwargs):
        if (not isinstance(kwargs['capture'], bool)):
            raise InterpreterException('"capture" keyword must be a boolean.')
        if ('command' not in kwargs):
            raise InterpreterException('"capture" keyword requires "command" keyword.')
    if ('format' in kwargs):
        fmt = kwargs['format']
        if (not isinstance(fmt, str)):
            raise InterpreterException('"format" keyword must be a string.')
    else:
        fmt = 'meson'
    if (fmt not in ('meson', 'cmake', 'cmake@')):
        raise InterpreterException('"format" possible values are "meson", "cmake" or "cmake@".')
    if ('output_format' in kwargs):
        output_format = kwargs['output_format']
        if (not isinstance(output_format, str)):
            raise InterpreterException('"output_format" keyword must be a string.')
    else:
        output_format = 'c'
    if (output_format not in ('c', 'nasm')):
        raise InterpreterException('"format" possible values are "c" or "nasm".')
    if ('depfile' in kwargs):
        depfile = kwargs['depfile']
        if (not isinstance(depfile, str)):
            raise InterpreterException('depfile file name must be a string')
    else:
        depfile = None
    inputs = self.source_strings_to_files(extract_as_list(kwargs, 'input'))
    inputs_abs = []
    for f in inputs:
        if isinstance(f, mesonlib.File):
            inputs_abs.append(f.absolute_path(self.environment.source_dir, self.environment.build_dir))
            self.add_build_def_file(f)
        else:
            raise InterpreterException('Inputs can only be strings or file objects')
    output = kwargs['output']
    if (not isinstance(output, str)):
        raise InterpreterException('Output file name must be a string')
    if inputs_abs:
        values = mesonlib.get_filenames_templates_dict(inputs_abs, None)
        outputs = mesonlib.substitute_values([output], values)
        output = outputs[0]
        if depfile:
            depfile = mesonlib.substitute_values([depfile], values)[0]
    ofile_rpath = os.path.join(self.subdir, output)
    if (ofile_rpath in self.configure_file_outputs):
        mesonbuildfile = os.path.join(self.subdir, 'meson.build')
        current_call = '{}:{}'.format(mesonbuildfile, self.current_lineno)
        first_call = '{}:{}'.format(mesonbuildfile, self.configure_file_outputs[ofile_rpath])
        mlog.warning('Output file', mlog.bold(ofile_rpath, True), 'for configure_file() at', current_call, 'overwrites configure_file() output at', first_call)
    else:
        self.configure_file_outputs[ofile_rpath] = self.current_lineno
    if (os.path.dirname(output) != ''):
        raise InterpreterException('Output file name must not contain a subdirectory.')
    (ofile_path, ofile_fname) = os.path.split(os.path.join(self.subdir, output))
    ofile_abs = os.path.join(self.environment.build_dir, ofile_path, ofile_fname)
    if ('configuration' in kwargs):
        conf = kwargs['configuration']
        if isinstance(conf, dict):
            FeatureNew('configure_file.configuration dictionary', '0.49.0').use(self.subproject)
            conf = ConfigurationDataHolder(self.subproject, conf)
        elif (not isinstance(conf, ConfigurationDataHolder)):
            raise InterpreterException('Argument "configuration" is not of type configuration_data')
        mlog.log('Configuring', mlog.bold(output), 'using configuration')
        if (len(inputs) > 1):
            raise InterpreterException('At most one input file can given in configuration mode')
        if inputs:
            os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
            file_encoding = kwargs.setdefault('encoding', 'utf-8')
            (missing_variables, confdata_useless) = mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf.held_object, fmt, file_encoding)
            if missing_variables:
                var_list = ', '.join(map(repr, sorted(missing_variables)))
                mlog.warning(("The variable(s) %s in the input file '%s' are not present in the given configuration data." % (var_list, inputs[0])), location=node)
            if confdata_useless:
                ifbase = os.path.basename(inputs_abs[0])
                mlog.warning("Got an empty configuration_data() object and found no substitutions in the input file {!r}. If you want to copy a file to the build dir, use the 'copy:' keyword argument added in 0.47.0".format(ifbase), location=node)
        else:
            mesonlib.dump_conf_header(ofile_abs, conf.held_object, output_format)
        conf.mark_used()
    elif ('command' in kwargs):
        if (len(inputs) > 1):
            FeatureNew('multiple inputs in configure_file()', '0.52.0').use(self.subproject)
        values = mesonlib.get_filenames_templates_dict(inputs_abs, [ofile_abs])
        if depfile:
            depfile = os.path.join(self.environment.get_scratch_dir(), depfile)
            values['@DEPFILE@'] = depfile
        cmd = mesonlib.substitute_values(kwargs['command'], values)
        mlog.log('Configuring', mlog.bold(output), 'with command')
        res = self.run_command_impl(node, cmd, {}, True)
        if (res.returncode != 0):
            raise InterpreterException(('Running configure command failed.\n%s\n%s' % (res.stdout, res.stderr)))
        if (('capture' in kwargs) and kwargs['capture']):
            dst_tmp = (ofile_abs + '~')
            file_encoding = kwargs.setdefault('encoding', 'utf-8')
            with open(dst_tmp, 'w', encoding=file_encoding) as f:
                f.writelines(res.stdout)
            if inputs_abs:
                shutil.copymode(inputs_abs[0], dst_tmp)
            mesonlib.replace_if_different(ofile_abs, dst_tmp)
        if depfile:
            mlog.log('Reading depfile:', mlog.bold(depfile))
            with open(depfile, 'r') as f:
                df = DepFile(f.readlines())
                deps = df.get_all_dependencies(ofile_fname)
                for dep in deps:
                    self.add_build_def_file(dep)
    elif ('copy' in kwargs):
        if (len(inputs_abs) != 1):
            raise InterpreterException('Exactly one input file must be given in copy mode')
        os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
        shutil.copyfile(inputs_abs[0], ofile_abs)
        shutil.copystat(inputs_abs[0], ofile_abs)
    else:
        raise AssertionError
    idir = kwargs.get('install_dir', '')
    if (idir is False):
        idir = ''
        mlog.deprecation('Please use the new `install:` kwarg instead of passing `false` to `install_dir:`', location=node)
    if (not isinstance(idir, str)):
        if (isinstance(idir, list) and (len(idir) == 0)):
            mlog.deprecation('install_dir: kwarg must be a string and not an empty array. Please use the install: kwarg to enable or disable installation. This will be a hard error in the next release.')
        else:
            raise InterpreterException('"install_dir" must be a string')
    install = kwargs.get('install', (idir != ''))
    if (not isinstance(install, bool)):
        raise InterpreterException('"install" must be a boolean')
    if install:
        if (not idir):
            raise InterpreterException('"install_dir" must be specified when "install" in a configure_file is true')
        cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname)
        install_mode = self._get_kwarg_install_mode(kwargs)
        self.build.data.append(build.Data([cfile], idir, install_mode))
    return mesonlib.File.from_built_file(self.subdir, output)
@FeatureNewKwargs('configure_file', '0.47.0', ['copy', 'output_format', 'install_mode', 'encoding'])
@FeatureNewKwargs('configure_file', '0.46.0', ['format'])
@FeatureNewKwargs('configure_file', '0.41.0', ['capture'])
@FeatureNewKwargs('configure_file', '0.50.0', ['install'])
@FeatureNewKwargs('configure_file', '0.52.0', ['depfile'])
@permittedKwargs(permitted_kwargs['configure_file'])
def func_configure_file(self, node, args, kwargs):
    if (len(args) > 0):
        raise InterpreterException('configure_file takes only keyword arguments.')
    if ('output' not in kwargs):
        raise InterpreterException('Required keyword argument "output" not defined.')
    actions = set(['configuration', 'command', 'copy']).intersection(kwargs.keys())
    if (len(actions) == 0):
        raise InterpreterException("Must specify an action with one of these keyword arguments: 'configuration', 'command', or 'copy'.")
    elif (len(actions) == 2):
        raise InterpreterException('Must not specify both {!r} and {!r} keyword arguments since they are mutually exclusive.'.format(*actions))
    elif (len(actions) == 3):
        raise InterpreterException('Must specify one of {!r}, {!r}, and {!r} keyword arguments since they are mutually exclusive.'.format(*actions))
    if ('capture' in kwargs):
        if (not isinstance(kwargs['capture'], bool)):
            raise InterpreterException('"capture" keyword must be a boolean.')
        if ('command' not in kwargs):
            raise InterpreterException('"capture" keyword requires "command" keyword.')
    if ('format' in kwargs):
        fmt = kwargs['format']
        if (not isinstance(fmt, str)):
            raise InterpreterException('"format" keyword must be a string.')
    else:
        fmt = 'meson'
    if (fmt not in ('meson', 'cmake', 'cmake@')):
        raise InterpreterException('"format" possible values are "meson", "cmake" or "cmake@".')
    if ('output_format' in kwargs):
        output_format = kwargs['output_format']
        if (not isinstance(output_format, str)):
            raise InterpreterException('"output_format" keyword must be a string.')
    else:
        output_format = 'c'
    if (output_format not in ('c', 'nasm')):
        raise InterpreterException('"format" possible values are "c" or "nasm".')
    if ('depfile' in kwargs):
        depfile = kwargs['depfile']
        if (not isinstance(depfile, str)):
            raise InterpreterException('depfile file name must be a string')
    else:
        depfile = None
    inputs = self.source_strings_to_files(extract_as_list(kwargs, 'input'))
    inputs_abs = []
    for f in inputs:
        if isinstance(f, mesonlib.File):
            inputs_abs.append(f.absolute_path(self.environment.source_dir, self.environment.build_dir))
            self.add_build_def_file(f)
        else:
            raise InterpreterException('Inputs can only be strings or file objects')
    output = kwargs['output']
    if (not isinstance(output, str)):
        raise InterpreterException('Output file name must be a string')
    if inputs_abs:
        values = mesonlib.get_filenames_templates_dict(inputs_abs, None)
        outputs = mesonlib.substitute_values([output], values)
        output = outputs[0]
        if depfile:
            depfile = mesonlib.substitute_values([depfile], values)[0]
    ofile_rpath = os.path.join(self.subdir, output)
    if (ofile_rpath in self.configure_file_outputs):
        mesonbuildfile = os.path.join(self.subdir, 'meson.build')
        current_call = '{}:{}'.format(mesonbuildfile, self.current_lineno)
        first_call = '{}:{}'.format(mesonbuildfile, self.configure_file_outputs[ofile_rpath])
        mlog.warning('Output file', mlog.bold(ofile_rpath, True), 'for configure_file() at', current_call, 'overwrites configure_file() output at', first_call)
    else:
        self.configure_file_outputs[ofile_rpath] = self.current_lineno
    if (os.path.dirname(output) != ):
        raise InterpreterException('Output file name must not contain a subdirectory.')
    (ofile_path, ofile_fname) = os.path.split(os.path.join(self.subdir, output))
    ofile_abs = os.path.join(self.environment.build_dir, ofile_path, ofile_fname)
    if ('configuration' in kwargs):
        conf = kwargs['configuration']
        if isinstance(conf, dict):
            FeatureNew('configure_file.configuration dictionary', '0.49.0').use(self.subproject)
            conf = ConfigurationDataHolder(self.subproject, conf)
        elif (not isinstance(conf, ConfigurationDataHolder)):
            raise InterpreterException('Argument "configuration" is not of type configuration_data')
        mlog.log('Configuring', mlog.bold(output), 'using configuration')
        if (len(inputs) > 1):
            raise InterpreterException('At most one input file can given in configuration mode')
        if inputs:
            os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
            file_encoding = kwargs.setdefault('encoding', 'utf-8')
            (missing_variables, confdata_useless) = mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf.held_object, fmt, file_encoding)
            if missing_variables:
                var_list = ', '.join(map(repr, sorted(missing_variables)))
                mlog.warning(("The variable(s) %s in the input file '%s' are not present in the given configuration data." % (var_list, inputs[0])), location=node)
            if confdata_useless:
                ifbase = os.path.basename(inputs_abs[0])
                mlog.warning("Got an empty configuration_data() object and found no substitutions in the input file {!r}. If you want to copy a file to the build dir, use the 'copy:' keyword argument added in 0.47.0".format(ifbase), location=node)
        else:
            mesonlib.dump_conf_header(ofile_abs, conf.held_object, output_format)
        conf.mark_used()
    elif ('command' in kwargs):
        if (len(inputs) > 1):
            FeatureNew('multiple inputs in configure_file()', '0.52.0').use(self.subproject)
        values = mesonlib.get_filenames_templates_dict(inputs_abs, [ofile_abs])
        if depfile:
            depfile = os.path.join(self.environment.get_scratch_dir(), depfile)
            values['@DEPFILE@'] = depfile
        cmd = mesonlib.substitute_values(kwargs['command'], values)
        mlog.log('Configuring', mlog.bold(output), 'with command')
        res = self.run_command_impl(node, cmd, {}, True)
        if (res.returncode != 0):
            raise InterpreterException(('Running configure command failed.\n%s\n%s' % (res.stdout, res.stderr)))
        if (('capture' in kwargs) and kwargs['capture']):
            dst_tmp = (ofile_abs + '~')
            file_encoding = kwargs.setdefault('encoding', 'utf-8')
            with open(dst_tmp, 'w', encoding=file_encoding) as f:
                f.writelines(res.stdout)
            if inputs_abs:
                shutil.copymode(inputs_abs[0], dst_tmp)
            mesonlib.replace_if_different(ofile_abs, dst_tmp)
        if depfile:
            mlog.log('Reading depfile:', mlog.bold(depfile))
            with open(depfile, 'r') as f:
                df = DepFile(f.readlines())
                deps = df.get_all_dependencies(ofile_fname)
                for dep in deps:
                    self.add_build_def_file(dep)
    elif ('copy' in kwargs):
        if (len(inputs_abs) != 1):
            raise InterpreterException('Exactly one input file must be given in copy mode')
        os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
        shutil.copyfile(inputs_abs[0], ofile_abs)
        shutil.copystat(inputs_abs[0], ofile_abs)
    else:
        raise AssertionError
    idir = kwargs.get('install_dir', )
    if (idir is False):
        idir = 
        mlog.deprecation('Please use the new `install:` kwarg instead of passing `false` to `install_dir:`', location=node)
    if (not isinstance(idir, str)):
        if (isinstance(idir, list) and (len(idir) == 0)):
            mlog.deprecation('install_dir: kwarg must be a string and not an empty array. Please use the install: kwarg to enable or disable installation. This will be a hard error in the next release.')
        else:
            raise InterpreterException('"install_dir" must be a string')
    install = kwargs.get('install', (idir != ))
    if (not isinstance(install, bool)):
        raise InterpreterException('"install" must be a boolean')
    if install:
        if (not idir):
            raise InterpreterException('"install_dir" must be specified when "install" in a configure_file is true')
        cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname)
        install_mode = self._get_kwarg_install_mode(kwargs)
        self.build.data.append(build.Data([cfile], idir, install_mode))
    return mesonlib.File.from_built_file(self.subdir, output)