aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-11-02 13:36:43 -0700
committerDylan Baker <dylan@pnwbakers.com>2021-11-08 12:29:01 -0800
commit566c2c9a9c98d13f85ccef624e9ac584f64c6a4a (patch)
tree1c135b02dc3beea8a9a0364c90faddd1abbed725
parentbe1d013453e3df3b83da0c91f5211c822d4da4d7 (diff)
downloadmeson-566c2c9a9c98d13f85ccef624e9ac584f64c6a4a.zip
meson-566c2c9a9c98d13f85ccef624e9ac584f64c6a4a.tar.gz
meson-566c2c9a9c98d13f85ccef624e9ac584f64c6a4a.tar.bz2
modules/gnome: use typed_kwargs for gtkdoc method
-rw-r--r--mesonbuild/modules/gnome.py234
1 files changed, 121 insertions, 113 deletions
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 353b954..73f4e1a 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -29,20 +29,19 @@ from .. import build
from .. import interpreter
from .. import mesonlib
from .. import mlog
-from ..build import CustomTarget, CustomTargetIndex, GeneratedList
+from ..build import CustomTarget, CustomTargetIndex, GeneratedList, InvalidArguments
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency
-from ..interpreter.type_checking import DEPEND_FILES_KW, INSTALL_KW, NoneType
+from ..interpreter.type_checking import DEPEND_FILES_KW, INSTALL_KW, NoneType, in_set_validator
from ..interpreterbase import noPosargs, noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs
from ..interpreterbase import typed_kwargs, KwargInfo, ContainerTypeInfo
from ..interpreterbase.decorators import typed_pos_args
from ..mesonlib import (
- MachineChoice, MesonException, OrderedSet, Popen_safe, extract_as_list,
- join_args, HoldableObject
+ MachineChoice, MesonException, OrderedSet, Popen_safe, join_args,
)
from ..programs import ExternalProgram, OverrideProgram
if T.TYPE_CHECKING:
- from typing_extensions import TypedDict
+ from typing_extensions import Literal, TypedDict
from . import ModuleState
from ..compilers import Compiler
@@ -101,6 +100,31 @@ if T.TYPE_CHECKING:
sources: T.List[T.Union[FileOrString, build.GeneratedTypes]]
symbol_prefix: T.List[str]
+ class GtkDoc(TypedDict):
+
+ src_dir: T.List[T.Union[str, build.IncludeDirs]]
+ main_sgml: str
+ main_xml: str
+ module_version: str
+ namespace: str
+ mode: Literal['xml', 'smgl', 'auto', 'none']
+ html_args: T.List[str]
+ scan_args: T.List[str]
+ scanobjs_args: T.List[str]
+ fixxref_args: T.List[str]
+ mkdb_args: T.List[str]
+ content_files: T.List[T.Union[build.GeneratedTypes, FileOrString]]
+ ignore_headers: T.List[str]
+ install_dir: T.List[str]
+ check: bool
+ install: bool
+ gobject_typesfile: T.List[str]
+ html_assets: T.List[str]
+ expand_content_files: T.List[str]
+ c_args: T.List[str]
+ include_directories: T.List[T.Union[str, build.IncludeDirs]]
+ dependencies: T.List[T.Union[Dependency, build.SharedLibrary, build.StaticLibrary]]
+
# Differs from the CustomTarget version in that it straight defaults to True
_BUILD_BY_DEFAULT: KwargInfo[bool] = KwargInfo(
'build_by_default', bool, default=True,
@@ -1056,84 +1080,97 @@ class GnomeModule(ExtensionModule):
rv: T.List[T.Union[build.ExecutableSerialisation, build.RunTarget]] = [inscript, pottarget, potarget]
return ModuleReturnValue(None, rv)
- @FeatureNewKwargs('gnome.gtkdoc', '0.52.0', ['check'])
- @FeatureNewKwargs('gnome.gtkdoc', '0.48.0', ['c_args'])
- @FeatureNewKwargs('gnome.gtkdoc', '0.48.0', ['module_version'])
- @FeatureNewKwargs('gnome.gtkdoc', '0.37.0', ['namespace', 'mode'])
- @permittedKwargs({'main_xml', 'main_sgml', 'src_dir', 'dependencies', 'install',
- 'install_dir', 'scan_args', 'scanobjs_args', 'gobject_typesfile',
- 'fixxref_args', 'html_args', 'html_assets', 'content_files',
- 'mkdb_args', 'ignore_headers', 'include_directories',
- 'namespace', 'mode', 'expand_content_files', 'module_version',
- 'c_args', 'check'})
@typed_pos_args('gnome.gtkdoc', str)
- def gtkdoc(self, state: 'ModuleState', args: T.Tuple[str], kwargs):
+ @typed_kwargs(
+ 'gnome.gtkdoc',
+ KwargInfo('c_args', ContainerTypeInfo(list, str), since='0.48.0', default=[], listify=True),
+ KwargInfo('check', bool, default=False, since='0.52.0'),
+ KwargInfo('content_files', ContainerTypeInfo(list, (str, mesonlib.File, build.GeneratedList, build.CustomTarget, build.CustomTargetIndex)), default=[], listify=True),
+ KwargInfo(
+ 'dependencies',
+ ContainerTypeInfo(list, (Dependency, build.SharedLibrary, build.StaticLibrary)),
+ listify=True, default=[]),
+ KwargInfo('expand_content_files', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('fixxref_args', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('gobject_typesfile', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('html_args', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('html_assets', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('ignore_headers', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo(
+ 'include_directories',
+ ContainerTypeInfo(list, (str, build.IncludeDirs)),
+ listify=True, default=[]),
+ KwargInfo('install', bool, default=True),
+ KwargInfo('install_dir', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('main_sgml', (str, NoneType)),
+ KwargInfo('main_xml', (str, NoneType)),
+ KwargInfo('mkdb_args', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo(
+ 'mode', str, default='auto', since='0.37.0',
+ validator=in_set_validator({'xml', 'sgml', 'none', 'auto'})),
+ KwargInfo('module_version', str, default='', since='0.48.0'),
+ KwargInfo('namespace', str, default='', since='0.37.0'),
+ KwargInfo('scan_args', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('scanobjs_args', ContainerTypeInfo(list, str), default=[], listify=True),
+ KwargInfo('src_dir', ContainerTypeInfo(list, (str, build.IncludeDirs)), listify=True, required=True),
+ )
+ def gtkdoc(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GtkDoc') -> ModuleReturnValue:
modulename = args[0]
- if 'src_dir' not in kwargs:
- raise MesonException('Keyword argument src_dir missing.')
- main_file = kwargs.get('main_sgml', '')
- if not isinstance(main_file, str):
- raise MesonException('Main sgml keyword argument must be a string.')
- main_xml = kwargs.get('main_xml', '')
- if not isinstance(main_xml, str):
- raise MesonException('Main xml keyword argument must be a string.')
- moduleversion = kwargs.get('module_version', '')
- if not isinstance(moduleversion, str):
- raise MesonException('Module version keyword argument must be a string.')
- if main_xml != '':
- if main_file != '':
- raise MesonException('You can only specify main_xml or main_sgml, not both.')
+ main_file = kwargs['main_sgml']
+ main_xml = kwargs['main_xml']
+ if main_xml is not None:
+ if main_file is not None:
+ raise InvalidArguments('gnome.gtkdoc: main_xml and main_xgml are exclusive arguments')
main_file = main_xml
+ moduleversion = kwargs['module_version']
targetname = modulename + ('-' + moduleversion if moduleversion else '') + '-doc'
command = state.environment.get_build_command()
- namespace = kwargs.get('namespace', '')
- mode = kwargs.get('mode', 'auto')
- VALID_MODES = ('xml', 'sgml', 'none', 'auto')
- if mode not in VALID_MODES:
- raise MesonException(f'gtkdoc: Mode {mode} is not a valid mode: {VALID_MODES}')
+ namespace = kwargs['namespace']
+
+ def abs_filenames(files: T.Iterable['FileOrString']) -> T.Iterator[str]:
+ for f in files:
+ if isinstance(f, mesonlib.File):
+ yield f.absolute_path(state.environment.get_source_dir(), state.environment.get_build_dir())
+ else:
+ yield os.path.join(state.environment.get_source_dir(), state.subdir, f)
- src_dirs = mesonlib.extract_as_list(kwargs, 'src_dir')
- header_dirs = []
+ src_dirs = kwargs['src_dir']
+ header_dirs: T.List[str] = []
for src_dir in src_dirs:
- if isinstance(src_dir, HoldableObject):
- if not isinstance(src_dir, build.IncludeDirs):
- raise MesonException('Invalid keyword argument for src_dir.')
- for inc_dir in src_dir.get_incdirs():
- header_dirs.append(os.path.join(state.environment.get_source_dir(),
- src_dir.get_curdir(), inc_dir))
- header_dirs.append(os.path.join(state.environment.get_build_dir(),
- src_dir.get_curdir(), inc_dir))
+ if isinstance(src_dir, build.IncludeDirs):
+ header_dirs.extend(src_dir.to_string_list(state.environment.get_source_dir(),
+ state.environment.get_build_dir()))
else:
header_dirs.append(src_dir)
- args = ['--internal', 'gtkdoc',
- '--sourcedir=' + state.environment.get_source_dir(),
- '--builddir=' + state.environment.get_build_dir(),
- '--subdir=' + state.subdir,
- '--headerdirs=' + '@@'.join(header_dirs),
- '--mainfile=' + main_file,
- '--modulename=' + modulename,
- '--moduleversion=' + moduleversion,
- '--mode=' + mode]
+ t_args = ['--internal', 'gtkdoc',
+ '--sourcedir=' + state.environment.get_source_dir(),
+ '--builddir=' + state.environment.get_build_dir(),
+ '--subdir=' + state.subdir,
+ '--headerdirs=' + '@@'.join(header_dirs),
+ '--mainfile=' + main_file,
+ '--modulename=' + modulename,
+ '--moduleversion=' + moduleversion,
+ '--mode=' + kwargs['mode']]
for tool in ['scan', 'scangobj', 'mkdb', 'mkhtml', 'fixxref']:
program_name = 'gtkdoc-' + tool
program = state.find_program(program_name)
path = program.get_path()
- args.append(f'--{program_name}={path}')
+ t_args.append(f'--{program_name}={path}')
if namespace:
- args.append('--namespace=' + namespace)
- args += self._unpack_args('--htmlargs=', 'html_args', kwargs)
- args += self._unpack_args('--scanargs=', 'scan_args', kwargs)
- args += self._unpack_args('--scanobjsargs=', 'scanobjs_args', kwargs)
- args += self._unpack_args('--gobjects-types-file=', 'gobject_typesfile', kwargs, state)
- args += self._unpack_args('--fixxrefargs=', 'fixxref_args', kwargs)
- args += self._unpack_args('--mkdbargs=', 'mkdb_args', kwargs)
- args += self._unpack_args('--html-assets=', 'html_assets', kwargs, state)
-
- depends = []
+ t_args.append('--namespace=' + namespace)
+ t_args.append(f'--htmlargs={"@@".join(kwargs["html_args"])}')
+ t_args.append(f'--scanargs={"@@".join(kwargs["scan_args"])}')
+ t_args.append(f'--scanobjsargs={"@@".join(kwargs["scanobjs_args"])}')
+ t_args.append(f'--gobjects-types-file={"@@".join(abs_filenames(kwargs["gobject_typesfile"]))}')
+ t_args.append(f'--fixxrefargs={"@@".join(kwargs["fixxref_args"])}')
+ t_args.append(f'--mkdbargs={"@@".join(kwargs["mkdb_args"])}')
+ t_args.append(f'--html-assets={"@@".join(abs_filenames(kwargs["html_assets"]))}')
+
+ depends: T.List['build.GeneratedTypes'] = []
content_files = []
- for s in mesonlib.extract_as_list(kwargs, 'content_files'):
+ for s in kwargs['content_files']:
if isinstance(s, (build.CustomTarget, build.CustomTargetIndex)):
depends.append(s)
for o in s.get_outputs():
@@ -1149,50 +1186,43 @@ class GnomeModule(ExtensionModule):
content_files.append(os.path.join(state.environment.get_source_dir(),
state.subdir,
gen_src))
- elif isinstance(s, str):
+ else:
content_files.append(os.path.join(state.environment.get_source_dir(),
state.subdir,
s))
- else:
- raise MesonException(
- f'Invalid object type: {s.__class__.__name__!r}')
- args += ['--content-files=' + '@@'.join(content_files)]
+ t_args += ['--content-files=' + '@@'.join(content_files)]
- args += self._unpack_args('--expand-content-files=', 'expand_content_files', kwargs, state)
- args += self._unpack_args('--ignore-headers=', 'ignore_headers', kwargs)
- args += self._unpack_args('--installdir=', 'install_dir', kwargs)
- args += self._get_build_args(kwargs, state, depends)
+ t_args.append(f'--expand-content-files={"@@".join(abs_filenames(kwargs["expand_content_files"]))}')
+ t_args.append(f'--ignore-headers={"@@".join(kwargs["ignore_headers"])}')
+ t_args.append(f'--installdir={"@@".join(kwargs["install_dir"])}')
+ t_args += self._get_build_args(kwargs['c_args'], kwargs['include_directories'],
+ kwargs['dependencies'], state, depends)
custom_kwargs = {'output': modulename + '-decl.txt',
- 'command': command + args,
+ 'command': command + t_args,
'depends': depends,
'build_always_stale': True,
}
custom_target = build.CustomTarget(targetname, state.subdir, state.subproject, custom_kwargs)
alias_target = build.AliasTarget(targetname, [custom_target], state.subdir, state.subproject)
- if kwargs.get('check', False):
+ if kwargs['check']:
check_cmd = state.find_program('gtkdoc-check')
check_env = ['DOC_MODULE=' + modulename,
'DOC_MAIN_SGML_FILE=' + main_file]
- check_args = [targetname + '-check', check_cmd]
+ check_args = (targetname + '-check', check_cmd)
check_workdir = os.path.join(state.environment.get_build_dir(), state.subdir)
- state.test(check_args, env=check_env, workdir=check_workdir, depends=custom_target)
- res = [custom_target, alias_target]
- if kwargs.get('install', True):
- res.append(state.backend.get_executable_serialisation(command + args, tag='doc'))
+ state.test(check_args, env=check_env, workdir=check_workdir, depends=[custom_target])
+ res: T.List[T.Union[build.Target, build.ExecutableSerialisation]] = [custom_target, alias_target]
+ if kwargs['install']:
+ res.append(state.backend.get_executable_serialisation(command + t_args, tag='doc'))
return ModuleReturnValue(custom_target, res)
- def _get_build_args(self, kwargs: T.Dict[str, T.Any], state: 'ModuleState', depends: T.List[build.BuildTarget]) -> T.List[str]:
+ def _get_build_args(self, c_args: T.List[str], inc_dirs: T.List[T.Union[str, build.IncludeDirs]],
+ deps: T.List[T.Union[Dependency, build.SharedLibrary, build.StaticLibrary]],
+ state: 'ModuleState', depends: T.List[build.BuildTarget]) -> T.List[str]:
args: T.List[str] = []
- deps = extract_as_list(kwargs, 'dependencies')
- cflags: T.List[str] = []
- cflags.extend(mesonlib.stringlistify(kwargs.pop('c_args', [])))
+ cflags = c_args.copy()
deps_cflags, internal_ldflags, external_ldflags, *_ = \
self._get_dependencies_flags(deps, state, depends, include_rpath=True)
- inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories')
- for incd in inc_dirs:
- if not isinstance(incd, (str, build.IncludeDirs)):
- raise MesonException(
- 'Gir include dirs should be include_directories().')
cflags.extend(deps_cflags)
cflags.extend(state.get_include_args(inc_dirs))
@@ -1223,28 +1253,6 @@ class GnomeModule(ExtensionModule):
def gtkdoc_html_dir(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> str:
return os.path.join('share/gtk-doc/html', args[0])
- @staticmethod
- def _unpack_args(arg, kwarg_name: str, kwargs: T.Dict[str, T.Any], expend_file_state: T.Optional['ModuleState'] = None) -> T.List[str]:
- if kwarg_name not in kwargs:
- return []
-
- new_args = mesonlib.extract_as_list(kwargs, kwarg_name)
- args = []
- for i in new_args:
- if expend_file_state is not None:
- if isinstance(i, mesonlib.File):
- i = i.absolute_path(expend_file_state.environment.get_source_dir(), expend_file_state.environment.get_build_dir())
- elif isinstance(i, str):
- i = os.path.join(expend_file_state.environment.get_source_dir(), expend_file_state.subdir, i)
- elif not isinstance(i, str):
- raise MesonException(kwarg_name + ' values must be strings.')
- args.append(i)
-
- if args:
- return [arg + '@@'.join(args)]
-
- return []
-
def _get_autocleanup_args(self, kwargs: T.Dict[str, T.Any], glib_version: str) -> T.List[str]:
if not mesonlib.version_compare(glib_version, '>= 2.49.1'):
# Warn if requested, silently disable if not