Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/os_comp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,32 @@ jobs:
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix

./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS

run-convert:
name: 'Test build system conversion'
runs-on: ubuntu-latest
container:
image: mesonbuild/ubuntu-rolling

steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run convert unit tests
shell: bash
run: |
source /ci/env_vars.sh
python3 run_unittests.py ConvertTests

run-check-platforms:
name: 'Test check-plaforms'
runs-on: ubuntu-latest
container:
image: mesonbuild/ubuntu-rolling
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run check-platform unit tests
shell: bash
run: |
source /ci/env_vars.sh
python3 run_unittests.py CheckPlatformsTests
64 changes: 64 additions & 0 deletions docs/markdown/Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,70 @@ Optional arguments. The most common workflow is to run
For the full list of all available options for a specific command use
the following syntax: `meson COMMAND --help`

### check-platforms

{{ check-platforms_usage.inc }}

Check the properties of the specified platform. The inputs
are a set of TOML files that define the project, the project's
platforms and the project's dependencies.

The platforms TOML file is modified when running the project
specific checks.

**This is an unstable API.**

{{ check-platforms_arguments.inc }}

#### Examples:

Check the properties of the default system platform.

```
meson check-platforms
```

Check the properties with a cross-file specified platform.

```
meson check-platforms --config=/path/to/myproject.toml \
--project-dir=/path/to/my/target_repo
--platforms=/path/to/myplatform.toml \
--dependencies=/path/to/mydeps.toml
```

### convert

{{ convert_usage.inc }}

Converts the meson project to an another build system. The input
are a series of TOML files, and the output are files in the target
build system. Soong and Bazel are supported to varying degrees.

**This is an unstable API.**

{{ convert_arguments.inc }}

#### Examples:

Each project maintains own TOML to define the hermetic transformation.

```
meson convert --config=/path/to/myproject.toml \
--project-dir=/path/to/my/target_repo
--platforms/path/to/myplatform.toml \
--dependencies=/path/to/mydeps.toml
--output_dir=/path/to/output-dir
```

Projects registered in Meson's small hermetic database (such as Mesa3D)
can use an abbreviated command to perform the conversion. Users are
encouraged to add the database.

```
meson convert android aosp_mesa3d
```

### configure

{{ configure_usage.inc }}
Expand Down
2 changes: 2 additions & 0 deletions mesonbuild/checkplatforms/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 The Meson Authors
109 changes: 109 additions & 0 deletions mesonbuild/checkplatforms/checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 The Meson Authors

from __future__ import annotations
from dataclasses import dataclass
import os
import tempfile
import typing as T

from mesonbuild import environment, build, mlog
from mesonbuild.options import OptionKey
from mesonbuild.hermetic.hermetic_interpreter import HermeticInterpreter
from mesonbuild.hermetic.hermetic_dependencies import DependenciesToml, HermeticDependencies
from mesonbuild.hermetic.common_compiler import PlatformsToml
from mesonbuild.hermetic.hermetic_platform import HermeticPlatform
from mesonbuild.convert.convert_project_config import ProjectConfigToml
from mesonbuild.checkplatforms.emitter import PlatformEmitter

if T.TYPE_CHECKING:
from typing_extensions import Protocol
from mesonbuild.cmdline import SharedCMDOptions

class CheckPlatformOptions(SharedCMDOptions, Protocol):
project_dir: T.Optional[str]
config: T.Optional[str]
dependencies: T.Optional[str]
platforms: T.Optional[str]
output: T.Optional[str]
hermetic_project: T.Optional[str]
git_project: T.Optional[str]


def _sanitize_options(args: CheckPlatformOptions) -> CheckPlatformOptions:
# default SharedCMDOptions: workaround Protocol
args.cmd_line_options = {}
args.builtin_keys = set()
args.d_keys = set()
args.cross_file = []
args.native_file = []
return args


@dataclass
class CheckPlatformsInstance:
host_platform: str
build_platform: str
meson_options: T.Dict[str, T.Union[str, bool]]


def _determine_platforms_to_run(project_toml: ProjectConfigToml, platforms_toml: PlatformsToml,
options: CheckPlatformOptions) -> T.List[CheckPlatformsInstance]: # fmt: skip
instances: T.List[CheckPlatformsInstance] = []
configs = project_toml.get('config', [])

for config in configs:
platforms_data = config.get('platforms', {})
host_platforms = platforms_data.get('host_platforms', [])
build_platforms = platforms_data.get('build_platforms', [])
static_options = config.get('static_options', {}).copy()

for host_platform in host_platforms:
for build_platform in build_platforms:
instances.append(
CheckPlatformsInstance(host_platform, build_platform, static_options)
)

return instances


def do_checkplatforms(project_toml: ProjectConfigToml, platforms_toml: PlatformsToml,
dependencies_toml: DependenciesToml, options: CheckPlatformOptions) -> int: # fmt: skip

instances = _determine_platforms_to_run(project_toml, platforms_toml, options)
hermetic_platform = HermeticPlatform(platforms_toml)
dependencies = HermeticDependencies(dependencies_toml)

for instance in instances:
sanitized_options = _sanitize_options(options)
sanitized_options.cmd_line_options = {
OptionKey.from_string(k): str(v) for k, v in instance.meson_options.items()
}

mlog.set_quiet()
with tempfile.TemporaryDirectory() as builddir:
env = environment.Environment(options.project_dir, builddir, sanitized_options)
platform_instance = hermetic_platform.create_platform_info(
instance.host_platform, instance.build_platform, env, download=True
)
b = build.Build(env)
intr = HermeticInterpreter(
b,
dependencies=dependencies,
hermetic_platform=platform_instance,
user_defined_options=sanitized_options,
)

try:
intr.run()
except Exception as e:
mlog.warning(
f'Interpreter failed during checks for platform {instance.host_platform}: {e}'
)

emitter = PlatformEmitter(hermetic_platform.platforms_toml, options)
emitter.emit(options.output)
mlog.set_verbose()
mlog.log('Platform information written to', mlog.bold(os.path.abspath(options.output)))
return 0
Loading
Loading