diff options
author | Charles Brunet <charles.brunet@optelgroup.com> | 2023-03-30 11:32:44 -0400 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2023-04-20 18:31:39 +0300 |
commit | 5eb55075baa2883170a3d0cf3c0621aae56a1632 (patch) | |
tree | 79c5818be45ec8737dd9b4e7246cb6e9ab875b94 /mesonbuild/mintro.py | |
parent | fbab1488ae31ac0e3f08aa84c811cbdcd5fa68b4 (diff) | |
download | meson-5eb55075baa2883170a3d0cf3c0621aae56a1632.zip meson-5eb55075baa2883170a3d0cf3c0621aae56a1632.tar.gz meson-5eb55075baa2883170a3d0cf3c0621aae56a1632.tar.bz2 |
intro: add more details to generated json files
This will help with the writing of tools to generate
VisualStudio project and solution files, and possibly
for other IDEs as well.
- Used compilers a about `host`, `build` and `target` machines
arere listed in `intro-compilers.json`
- Informations lister in `intro-machines.json`
- `intro-dependencies.json` now includes internal dependencies,
and relations between dependencies.
- `intro-targets.json` now includes dependencies, `vs_module_defs`,
`win_subsystem`, and linker parameters.
Diffstat (limited to 'mesonbuild/mintro.py')
-rw-r--r-- | mesonbuild/mintro.py | 94 |
1 files changed, 84 insertions, 10 deletions
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 1842313..dd1a000 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -22,6 +22,7 @@ project files and don't need this info.""" from contextlib import redirect_stdout import collections +import dataclasses import json import os from pathlib import Path, PurePath @@ -31,6 +32,9 @@ import typing as T from . import build, mesonlib, coredata as cdata from .ast import IntrospectionInterpreter, BUILD_TARGET_FUNCTIONS, AstConditionLevel, AstIDGenerator, AstIndentationGenerator, AstJSONPrinter from .backend import backends +from .dependencies import Dependency +from . import environment +from .interpreterbase import ObjectHolder from .mesonlib import OptionKey from .mparser import FunctionNode, ArrayNode, ArgumentNode, StringNode @@ -76,10 +80,12 @@ def get_meson_introspection_types(coredata: T.Optional[cdata.CoreData] = None, ('benchmarks', IntroCommand('List all benchmarks', func=lambda: list_benchmarks(benchmarkdata))), ('buildoptions', IntroCommand('List all build options', func=lambda: list_buildoptions(coredata), no_bd=list_buildoptions_from_source)), ('buildsystem_files', IntroCommand('List files that make up the build system', func=lambda: list_buildsystem_files(builddata, interpreter))), - ('dependencies', IntroCommand('List external dependencies', func=lambda: list_deps(coredata), no_bd=list_deps_from_source)), + ('compilers', IntroCommand('List used compilers', func=lambda: list_compilers(coredata))), + ('dependencies', IntroCommand('List external dependencies', func=lambda: list_deps(coredata, backend), no_bd=list_deps_from_source)), ('scan_dependencies', IntroCommand('Scan for dependencies used in the meson.build file', no_bd=list_deps_from_source)), ('installed', IntroCommand('List all installed files and directories', func=lambda: list_installed(installdata))), ('install_plan', IntroCommand('List all installed files and directories with their details', func=lambda: list_install_plan(installdata))), + ('machines', IntroCommand('Information about host, build, and target machines', func=lambda: list_machines(builddata))), ('projectinfo', IntroCommand('Information about projects', func=lambda: list_projinfo(builddata), no_bd=list_projinfo_from_source)), ('targets', IntroCommand('List top level targets', func=lambda: list_targets(builddata, installdata, backend), no_bd=list_targets_from_source)), ('tests', IntroCommand('List all unit tests', func=lambda: list_tests(testdata))), @@ -250,14 +256,22 @@ def list_targets(builddata: build.Build, installdata: backends.InstallData, back 'name': target.get_basename(), 'id': idname, 'type': target.get_typename(), - 'defined_in': os.path.normpath(os.path.join(src_dir, target.subdir, 'meson.build')), + 'defined_in': os.path.normpath(os.path.join(src_dir, target.subdir, environment.build_filename)), 'filename': [os.path.join(build_dir, outdir, x) for x in target.get_outputs()], 'build_by_default': target.build_by_default, 'target_sources': backend.get_introspection_data(idname, target), 'extra_files': [os.path.normpath(os.path.join(src_dir, x.subdir, x.fname)) for x in target.extra_files], - 'subproject': target.subproject or None + 'subproject': target.subproject or None, + 'dependencies': [d.name for d in getattr(target, 'external_deps', [])], } + vs_module_defs = getattr(target, 'vs_module_defs', None) + if vs_module_defs is not None: + t['vs_module_defs'] = vs_module_defs.relative_name() + win_subsystem = getattr(target, 'win_subsystem', None) + if win_subsystem is not None: + t['win_subsystem'] = win_subsystem + if installdata and target.should_install(): t['installed'] = True ifn = [install_lookuptable.get(x, [None]) for x in target.get_outputs()] @@ -343,6 +357,23 @@ def list_buildsystem_files(builddata: build.Build, interpreter: Interpreter) -> filelist = [PurePath(src_dir, x).as_posix() for x in filelist] return filelist +def list_compilers(coredata: cdata.CoreData) -> T.Dict[str, T.Dict[str, T.Dict[str, str]]]: + compilers: T.Dict[str, T.Dict[str, T.Dict[str, str]]] = {} + for machine in ('host', 'build'): + compilers[machine] = {} + for language, compiler in getattr(coredata.compilers, machine).items(): + compilers[machine][language] = { + 'id': compiler.get_id(), + 'exelist': compiler.get_exelist(), + 'linker_exelist': compiler.get_linker_exelist(), + 'file_suffixes': compiler.file_suffixes, + 'default_suffix': compiler.get_default_suffix(), + 'version': compiler.version, + 'full_version': compiler.full_version, + 'linker_id': compiler.get_linker_id(), + } + return compilers + def list_deps_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, T.Union[str, bool]]]: result = [] # type: T.List[T.Dict[str, T.Union[str, bool]]] for i in intr.dependencies: @@ -356,15 +387,48 @@ def list_deps_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, result += [{k: v for k, v in i.items() if k in keys}] return result -def list_deps(coredata: cdata.CoreData) -> T.List[T.Dict[str, T.Union[str, T.List[str]]]]: - result = [] # type: T.List[T.Dict[str, T.Union[str, T.List[str]]]] +def list_deps(coredata: cdata.CoreData, backend: backends.Backend) -> T.List[T.Dict[str, T.Union[str, T.List[str]]]]: + result: T.Dict[str, T.Dict[str, T.Union[str, T.List[str]]]] = {} + + def _src_to_str(src_file: T.Union[mesonlib.FileOrString, build.CustomTarget, build.StructuredSources, build.CustomTargetIndex, build.GeneratedList]) -> T.List[str]: + if isinstance(src_file, str): + return [src_file] + if isinstance(src_file, mesonlib.File): + return [src_file.absolute_path(backend.source_dir, backend.build_dir)] + if isinstance(src_file, (build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)): + return src_file.get_outputs() + if isinstance(src_file, build.StructuredSources): + return [f for s in src_file.as_list() for f in _src_to_str(s)] + raise mesonlib.MesonBugException(f'Invalid file type {type(src_file)}.') + + def _create_result(d: Dependency, varname: T.Optional[str] = None) -> T.Dict[str, T.Any]: + return { + 'name': d.name, + 'type': d.type_name, + 'version': d.get_version(), + 'compile_args': d.get_compile_args(), + 'link_args': d.get_link_args(), + 'include_directories': [i for idirs in d.get_include_dirs() for i in idirs.to_string_list(backend.source_dir)], + 'sources': [f for s in d.get_sources() for f in _src_to_str(s)], + 'extra_files': [f for s in d.get_extra_files() for f in _src_to_str(s)], + 'deps': [e.name for e in d.ext_deps], + 'meson_variables': [varname] if varname else [], + } + for d in coredata.deps.host.values(): if d.found(): - result += [{'name': d.name, - 'version': d.get_version(), - 'compile_args': d.get_compile_args(), - 'link_args': d.get_link_args()}] - return result + result[d.name] = _create_result(d) + + for varname, holder in backend.interpreter.variables.items(): + if isinstance(holder, ObjectHolder): + d = holder.held_object + if isinstance(d, Dependency) and d.found(): + if d.name in result: + T.cast(T.List[str], result[d.name]['meson_variables']).append(varname) + else: + result[d.name] = _create_result(d, varname) + + return list(result.values()) def get_test_list(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]: result = [] # type: T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]] @@ -396,6 +460,16 @@ def list_tests(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[st def list_benchmarks(benchdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]: return get_test_list(benchdata) +def list_machines(builddata: build.Build) -> T.Dict[str, T.Dict[str, T.Union[str, bool]]]: + machines: T.Dict[str, T.Dict[str, T.Union[str, bool]]] = {} + for m in ('host', 'build', 'target'): + machine = getattr(builddata.environment.machines, m) + machines[m] = dataclasses.asdict(machine) + machines[m]['is_64_bit'] = machine.is_64_bit + machines[m]['exe_suffix'] = machine.get_exe_suffix() + machines[m]['object_suffix'] = machine.get_object_suffix() + return machines + def list_projinfo(builddata: build.Build) -> T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]: result = {'version': builddata.project_version, 'descriptive_name': builddata.project_name, |