def do_subproject(self, subp_name: str, method: Literal[('meson', 'cmake')], kwargs: kwargs.DoSubproject) -> SubprojectHolder:
    (disabled, required, feature) = extract_required_kwarg(kwargs, self.subproject)
    if disabled:
        mlog.log('Subproject', mlog.bold(subp_name), ':', 'skipped: feature', mlog.bold(feature), 'disabled')
        return self.disabled_subproject(subp_name, disabled_feature=feature)
    default_options = coredata.create_options_dict(kwargs['default_options'], subp_name)
    if (subp_name == ''):
        raise InterpreterException('Subproject name must not be empty.')
    if (subp_name[0] == '.'):
        raise InterpreterException('Subproject name must not start with a period.')
    if ('..' in subp_name):
        raise InterpreterException('Subproject name must not contain a ".." path segment.')
    if os.path.isabs(subp_name):
        raise InterpreterException('Subproject name must not be an absolute path.')
    if has_path_sep(subp_name):
        mlog.warning('Subproject name has a path separator. This may cause unexpected behaviour.', location=self.current_node)
    if (subp_name in self.subproject_stack):
        fullstack = (self.subproject_stack + [subp_name])
        incpath = ' => '.join(fullstack)
        raise InvalidCode(f'Recursive include of subprojects: {incpath}.')
    if (subp_name in self.subprojects):
        subproject = self.subprojects[subp_name]
        if (required and (not subproject.found())):
            raise InterpreterException(f'Subproject "{subproject.subdir}" required but not found.')
        if kwargs['version']:
            pv = self.build.subprojects[subp_name]
            wanted = kwargs['version']
            if ((pv == 'undefined') or (not mesonlib.version_compare_many(pv, wanted)[0])):
                raise InterpreterException(f'Subproject {subp_name} version is {pv} but {wanted} required.')
        return subproject
    r = self.environment.wrap_resolver
    try:
        subdir = r.resolve(subp_name, method)
    except wrap.WrapException as e:
        if (not required):
            mlog.log(e)
            mlog.log('Subproject ', mlog.bold(subp_name), 'is buildable:', mlog.red('NO'), '(disabling)')
            return self.disabled_subproject(subp_name, exception=e)
        raise e
    subdir_abs = os.path.join(self.environment.get_source_dir(), subdir)
    os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
    self.global_args_frozen = True
    stack = ':'.join((self.subproject_stack + [subp_name]))
    m = ['\nExecuting subproject', mlog.bold(stack)]
    if (method != 'meson'):
        m += ['method', mlog.bold(method)]
    mlog.log(*m, '\n', nested=False)
    try:
        if (method == 'meson'):
            return self._do_subproject_meson(subp_name, subdir, default_options, kwargs)
        elif (method == 'cmake'):
            return self._do_subproject_cmake(subp_name, subdir, subdir_abs, default_options, kwargs)
        else:
            raise mesonlib.MesonBugException(f'The method {method} is invalid for the subproject {subp_name}')
    except InvalidCode:
        raise
    except Exception as e:
        if (not required):
            with mlog.nested(subp_name):
                mlog.exception(e, prefix=mlog.yellow('Exception:'))
            mlog.log('\nSubproject', mlog.bold(subdir), 'is buildable:', mlog.red('NO'), '(disabling)')
            return self.disabled_subproject(subp_name, exception=e)
        raise e
def do_subproject(self, subp_name: str, method: Literal[('meson', 'cmake')], kwargs: kwargs.DoSubproject) -> SubprojectHolder:
    (disabled, required, feature) = extract_required_kwarg(kwargs, self.subproject)
    if disabled:
        mlog.log('Subproject', mlog.bold(subp_name), ':', 'skipped: feature', mlog.bold(feature), 'disabled')
        return self.disabled_subproject(subp_name, disabled_feature=feature)
    default_options = coredata.create_options_dict(kwargs['default_options'], subp_name)
    if (subp_name == ):
        raise InterpreterException('Subproject name must not be empty.')
    if (subp_name[0] == '.'):
        raise InterpreterException('Subproject name must not start with a period.')
    if ('..' in subp_name):
        raise InterpreterException('Subproject name must not contain a ".." path segment.')
    if os.path.isabs(subp_name):
        raise InterpreterException('Subproject name must not be an absolute path.')
    if has_path_sep(subp_name):
        mlog.warning('Subproject name has a path separator. This may cause unexpected behaviour.', location=self.current_node)
    if (subp_name in self.subproject_stack):
        fullstack = (self.subproject_stack + [subp_name])
        incpath = ' => '.join(fullstack)
        raise InvalidCode(f'Recursive include of subprojects: {incpath}.')
    if (subp_name in self.subprojects):
        subproject = self.subprojects[subp_name]
        if (required and (not subproject.found())):
            raise InterpreterException(f'Subproject "{subproject.subdir}" required but not found.')
        if kwargs['version']:
            pv = self.build.subprojects[subp_name]
            wanted = kwargs['version']
            if ((pv == 'undefined') or (not mesonlib.version_compare_many(pv, wanted)[0])):
                raise InterpreterException(f'Subproject {subp_name} version is {pv} but {wanted} required.')
        return subproject
    r = self.environment.wrap_resolver
    try:
        subdir = r.resolve(subp_name, method)
    except wrap.WrapException as e:
        if (not required):
            mlog.log(e)
            mlog.log('Subproject ', mlog.bold(subp_name), 'is buildable:', mlog.red('NO'), '(disabling)')
            return self.disabled_subproject(subp_name, exception=e)
        raise e
    subdir_abs = os.path.join(self.environment.get_source_dir(), subdir)
    os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
    self.global_args_frozen = True
    stack = ':'.join((self.subproject_stack + [subp_name]))
    m = ['\nExecuting subproject', mlog.bold(stack)]
    if (method != 'meson'):
        m += ['method', mlog.bold(method)]
    mlog.log(*m, '\n', nested=False)
    try:
        if (method == 'meson'):
            return self._do_subproject_meson(subp_name, subdir, default_options, kwargs)
        elif (method == 'cmake'):
            return self._do_subproject_cmake(subp_name, subdir, subdir_abs, default_options, kwargs)
        else:
            raise mesonlib.MesonBugException(f'The method {method} is invalid for the subproject {subp_name}')
    except InvalidCode:
        raise
    except Exception as e:
        if (not required):
            with mlog.nested(subp_name):
                mlog.exception(e, prefix=mlog.yellow('Exception:'))
            mlog.log('\nSubproject', mlog.bold(subdir), 'is buildable:', mlog.red('NO'), '(disabling)')
            return self.disabled_subproject(subp_name, exception=e)
        raise e