ci #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Build every member on BOTH toolchains, and check what a green compile would | |
| # not: that the generator is ours, that the sonames are canonical, that the two | |
| # libraries do not overlap, and that every module produced an interface. | |
| name: ci | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Both, because the module wrappers are where the two compilers differ | |
| # most: a 300-entry `using ::name;` export block is exactly the shape | |
| # that finds a disagreement about what may be named in an export. | |
| toolchain: [default, llvm] | |
| name: build (${{ matrix.toolchain }}) | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Installed the way a user does, through xlings, rather than by | |
| # unpacking an mcpp release: these packages depend on the ECOSYSTEM | |
| # (`xim:mesa`'s GBM discovery row, the toolchains), and a pinned mcpp | |
| # tarball carries a frozen snapshot of it. Testing against the current | |
| # ecosystem is the point. | |
| # | |
| # XLINGS_NON_INTERACTIVE is what makes the installer usable here. Without | |
| # it the script takes its `curl | bash` branch — `xlings self install < | |
| # /dev/tty` — and a runner has a /dev/tty that is readable but not | |
| # connected, so it dies with "No such device or address" before anything | |
| # is installed. | |
| - name: Install xlings + mcpp | |
| env: | |
| XLINGS_NON_INTERACTIVE: "1" | |
| run: | | |
| curl -fsSL https://d2learn.org/xlings-install.sh | bash | |
| echo "$HOME/.xlings/bin" >> "$GITHUB_PATH" | |
| "$HOME/.xlings/bin/xlings" --version | |
| "$HOME/.xlings/bin/xlings" install mcpp | |
| echo "$HOME/.xlings/subos/default/bin" >> "$GITHUB_PATH" | |
| - name: Select toolchain | |
| if: matrix.toolchain != 'default' | |
| run: | | |
| mcpp toolchain install ${{ matrix.toolchain }} | |
| mcpp toolchain default ${{ matrix.toolchain }} | |
| mcpp toolchain list | |
| - name: Build the workspace | |
| run: | | |
| mcpp --version | |
| mcpp build --workspace | |
| - name: The macro mappings actually run | |
| run: mcpp test -p mcpp/util | |
| - name: wayland-scanner is ours, and is 1.26.0 | |
| run: | | |
| scanner=$(find mcpp/scanner/target -name wayland-scanner -type f | head -1) | |
| test -n "$scanner" || { echo "no wayland-scanner was built"; exit 1; } | |
| "$scanner" --version | |
| "$scanner" --version | grep -qx 'wayland-scanner 1.26.0' | |
| - name: the generated protocol code came from THIS scanner | |
| run: | | |
| scanner=$(find mcpp/scanner/target -name wayland-scanner -type f | head -1) | |
| "$scanner" -s public-code protocol/wayland.xml /tmp/wayland-protocol.c | |
| head -1 /tmp/wayland-protocol.c | |
| grep -q 'Generated by wayland-scanner 1.26.0' /tmp/wayland-protocol.c | |
| - name: both libraries carry the canonical SONAMEs | |
| run: | | |
| for pair in "client:libwayland-client.so.0" "server:libwayland-server.so.0"; do | |
| member=${pair%%:*}; want=${pair#*:} | |
| so=$(find "mcpp/$member/target" -name "${want%.0}" -type f | head -1) | |
| test -n "$so" || { echo "$member: no library built"; exit 1; } | |
| got=$(readelf -d "$so" | sed -n 's/.*SONAME.*\[\(.*\)\]/\1/p') | |
| echo "$member -> $got" | |
| test "$got" = "$want" || { echo "expected $want"; exit 1; } | |
| done | |
| - name: the two libraries do not overlap | |
| run: | | |
| # Mesa's libEGL_mesa has DT_NEEDED on both; if one carried the other's | |
| # API the process would bind to whichever loaded first. | |
| c=$(find mcpp/client/target -name libwayland-client.so -type f | head -1) | |
| s=$(find mcpp/server/target -name libwayland-server.so -type f | head -1) | |
| readelf --dyn-syms -W "$c" | grep -q ' wl_display_connect' || exit 1 | |
| readelf --dyn-syms -W "$c" | grep -q ' wl_display_create' && { echo "client leaked the server API"; exit 1; } | |
| readelf --dyn-syms -W "$s" | grep -q ' wl_display_create' || exit 1 | |
| readelf --dyn-syms -W "$s" | grep -q ' wl_display_connect' && { echo "server leaked the client API"; exit 1; } | |
| echo "client and server APIs are disjoint" | |
| - name: every module produced an interface | |
| run: | | |
| for m in client server util; do | |
| find "mcpp/$m/target" \( -name '*.gcm' -o -name '*.pcm' \) | head -1 | grep -q . \ | |
| || { echo "$m: no module interface was produced"; exit 1; } | |
| done | |
| echo "wayland.client, wayland.server and wayland.util all have interfaces" | |
| upstream: | |
| # The fork patches no upstream file, so meson must still build this tree. | |
| # If this breaks, something was modified that should not have been. | |
| name: upstream meson still builds this tree | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y -qq meson ninja-build libffi-dev libexpat1-dev | |
| meson setup build-meson -Ddocumentation=false -Ddtd_validation=false | |
| ninja -C build-meson |