Skip to content

meson2hermetic: check-platforms#16006

Draft
gurchetansingh wants to merge 7 commits into
mesonbuild:masterfrom
gurchetansingh:meson2hermetic-checkplatforms
Draft

meson2hermetic: check-platforms#16006
gurchetansingh wants to merge 7 commits into
mesonbuild:masterfrom
gurchetansingh:meson2hermetic-checkplatforms

Conversation

@gurchetansingh

Copy link
Copy Markdown
Contributor

This adds check-platforms support to meson. There are two motivations for this:

  1. To help the convert tool. The convert tool needs to deal with multiple compilers. If a user had to set up SDKs and download compilers each time, it would be extremely inconvenient. Rather, we define all the platforms in a TOML file and have meson do the downloading + setup.

  2. Apparently, having a way to describe to Meson that "the result of this test is ..." in a human readable format is useful for embedded systems. See [RFC] meson2hermetic in mesonbuild repo #14134 (reply in thread).

The first 4 commits are the convert PR, the last three are check-platforms specific. Much of the infrastructure inside mesonbuild/hermetic is shared. To run project-specific checks, one needs to pass project specific options. It may also be possible to write a custom parser that avoids optionality and JUST looks for the compiler checks. However, it was deemed easier to re-use existing paradigms.

One improvement area is that the project definition (for example, aosp_mesa3d.toml) is re-used between convert and check-platforms. That includes key-value pairs that are not immediately relevant to check-platforms (such as target_renames, handwritten_modules, or build_system). However, the hope is that as meson meta-project takes off, some of the common code can be possibly moved into the meson DSL, and the hermetic conversion TOML key-values can be more clearly isolated.

This distills what I've learned about the Meson formatting
rules into a [tool.ruff].

This is only applicable to the new meson2hermetic code
right now,  and others who want to use some formatter
in their contributions has well.

This of course is not meant to be adopted project-wide.

There is a disclaimer about trusting the tool and the
"Black"-style without auditing it's output.
This API converts meson.build into their corresponding
hermetic representation (Android Blueprint, Bazel and maybe
Buck2 in the future).

This is motivated by the need to integrate Mesa3D into
AOSP and Fuchsia trees.

The question "how to build and update Mesa3D drivers for
Android?" [1] in particular has led to several methods
over the years, none of which used Android's native build
system (Soong).  This has been an obstacle to adoption of
open-source drivers, which everyone knows are more secure,
maintainable and faster than closed alternatives.

By integrating into Mesa3D's native build system (Meson),
"meson convert" brings shocking and jaw-dropping clarity to
the question.

Technically speaking, the tool works by via series of TOML
files.  Python 3.11 has tomlib in the standard library, and
mconvert.py uses a conditional import strategy to prevent
issues on older Python versions.

These TOML files specify:

   * the Meson project that is being converted
   * where to find the dependencies in a hermetic tree
   * which compilers that a hermetic tree supports

These TOML files are used to run the Meson interpreter multiple
times.  For example, the set of C/C++ flags may be different
if the compiler targets x86_64 or ARM64.  Data from each of
meson intrepreter runs is collated to reconstruct the full
set of Soong/Bazel rules.

Although the initial implementation is focused with converting
to a existing hermetic build system, this introduces
infrastructure that could be useful if Meson itself takes
a look at remote-executed, hermetic builds.  For example,
Meson can download prebuilts from NixPkgs or grow the ability
to handle other projects.

Used in Android17+ mesa3d now [2].

[1] https://gitlab.freedesktop.org/mesa/mesa/-/issues/13776
[2] https://android.googlesource.com/platform/external/mesa3d/+/refs/heads/android17-release/Android.bp

Co-developed-by: Craig Stout <cstout@google.com>
Co-developed-by: Brandon Nguyen <bpnguyen@google.com>
For convert:

- add to mesonmain.py
- add Commands.md
This adds CI/CD + unit test for 'meson convert'.

Idea is simple:
   - have meson.build files
   - have "golden" Soong/Bazel files
   - run meson convert
   - compare with the goldens.

Test command:
   - python3 run_unittests.py ConvertTests

Regenerate goldens when needed:
  >> cd ~/meson/test cases/unit/hermetic/basic
  >> ~/meson/test cases/unit/hermetic/basic $ python3 ~/meson/meson.py convert test basic_soong
  >> ~/meson/test cases/unit/hermetic/basic $ python3 ~/meson/meson.py convert test basic_bazel
This adds the following API:

    meson check-platforms [ARGUMENTS]

This API checks the the specified toolchains and outputs a TOML
Gfile that contains an abstract reprenstation of it's properties.

An example TOML output is:

[[wrap]]
name = "android_ndk"
source_url = "https://dl.google.com/android/repository/android-ndk-r29-linux.zip"
source_filename = "android-ndk-r29.zip"
source_hash = "4abbbcdc842f3d4879206e9695d52709603e52dd68d3c1fff04b3b5e7a308ecf"

[[toolchain]]
name = "android_ndk_toolchain_aarch64"
wrap_name = "android_ndk"
ar = "toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
cc = "toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang"
cpp = "toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang++"
strip = "toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip"

[[platform]]
name = "android_arm64"

[platform.machine_info]
cpu_family = "aarch64"
cpu = "aarch64"
system = "android"
endian = "little"

[platform.c]
compiler_id = "clang"
linker_id = "ld.lld"
version = "21.0.0"
standards = [
    "none", "c89", "c99", "c11", "c17", "c18", "c2x", "c23", "c2y", "gnu89",
    "gnu99", "gnu11", "gnu17", "gnu18", "gnu2x", "gnu23", "gnu2y",
]
base_options = [
    "b_asneeded", "b_colorout", "b_coverage", "b_lto", "b_lto_mode",
    "b_lto_threads", "b_lundef", "b_ndebug", "b_pch", "b_pgo", "b_pie",
    "b_sanitize", "b_staticpic", "b_thinlto_cache", "b_thinlto_cache_dir",
]
toolchain = "android_ndk_toolchain_aarch64"
sysroot = { wrap_name = "android_ndk", path = "toolchains/llvm/prebuilt/linux-x86_64/sysroot" }

[platform.c.check_header.fails]
"pthread_np.h" = true
"sys/sysctl.h" = true

[platform.c.has_header_symbol.fails]
"errno.h" = { program_invocation_name = true }
"math.h" = { issignaling = true }
"sys/mkdev.h" = { major = true }

The [[wrap]] key specifies where to download the particular
zipfile/tarball.  The zip/tarball can contain a toolchain or SDK.
Right now only zipfile is support though since I couldn't find
SDK with tarballs, but I'm sure they exist.

The [[toolchain]] key specifies where to find a particular toolchain
binaries in particular tarball/zipfile.  Multiple toolchains may be
defined by one zipfile/tarball.

The [[platform]] defines a platform based on CPU/OS, toolchain
binaries, sysroot and the output of the various compiler checks.
Meson can reference that platform, such as "android_arm64".

Checks are project-specific.  There, check-toolchains re-uses
a lot of the work from meson convert to define a project, it's
dependencies and platforms.
For check-platforms:

- add to mesonmain.py
- add Commands.md
To ensure that the workflow is not broken, add an
unit test.

The test:

1) runs meson check-platform on the test hermetic project
2) The Android NDK is downloaded: we already know where it
   will fail checks
3) We confirm the expected checks fail

Test command:
    - python3 run_unittests.py CheckPlatformsTests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant