Skip to content

Commit

Permalink
Have pure-rust-build job find what compiles C code
Browse files Browse the repository at this point in the history
This adds more checks to the `pure-rust-build` CI job to reveal
what dependencies of `max-pure` are building C code. The new checks
are failing. They relate to GitoxideLabs#1681 and should pass once that bug is
fixed. The main goal is to produce information helpful for GitoxideLabs#1681.

As currently written, the new steps do not fail the job, because
the failing steps have `continue-on-error: true`. This is so that
regressions (that would fail the preexisting steps) remain readily
detected. This should ideally be temporary; the new steps, if kept,
should eventually be strengthened so they can fail the job.

Currently this includes both regular and build dependencies.

There are two new checks:

1. Search the `max-pure` dependency tree for packages that require
   a C or C++ compiler, or that are in practice only likely to be
   used to build C or C++ code. If any are found, display the whole
   tree, with matching lines highlighted, and fail the step.

2. After all steps that need it to be in working order, break GCC
   in the container by removing the `cc1` binary, then attempt a
   clean `max-pure` build, to reveal the first failure, if any, and
   let it fail the step.

   The `gcc` command itself is needed, because `rustc` calls the
   linker through it, even when no non-Rust code is compiled as
   part of the build.

   As discussed in GitoxideLabs#1664 comments, installing GCC in a way that is
   not broken but omits the ability to compile even C code, while
   it may be possible, is not commonly done and may require long
   running build steps or a new Docker image.

   Fortunately, the `gcc` command is just a "compiler driver"; the
   C compiler in GCC is `cc1`, and this can be removed without
   breaking most uses of GCC that don't involve actual compilation.

   This likewise removes `cc1plus` if found, even though it may not
   be present since we already verified that `g++` is not
   installed. (The deletion of `cc1` is the important part.)

Since the job now cleans and starts a build that fails due to the
absence of `cc1`, this removes the `rust-cache` step. (Caching
would probably still confer some benefit, since it caches
dependencies. Even after running `cargo clean` between the builds,
most of these should be reacquired when building with `cc1`.
However, to make the whole thing easier to reason about, the step
is removed. It can be re-added if the job runs too slowly.)

This considers any `-sys` crate to be a dependency that needs to
build C. This is in principle not always the case, since they may
use existing shared library binaries, though there may still be
stub code that has to be built in C. The relevance of the new
steps varies depending on precisely how one conceptualizes "pure"
in `max-pure`, which is another reason for them to start out as
`continue-on-error`.

The `-sys` crates this finds in the `max-pure` dependency tree are:

- `libsqlite3-sys` via `rusqlite`. This was reported in GitoxideLabs#1681 and
  strongly seems to be unintended for `max-pure`.

- `linux-raw-sys` via `rustix` and `xattr`. It's less clear whether
  this should be considered impure, since its purpose is to
  interact with an operating system facility, and it may be
  comparable to the use of `libc` (on Unix-like systems). However,
  this does seem like it would not be able to build without a C
  compiler.

The dependency tree also has an occurrence of the `cc` crate
without a related `-sys` dependency, as required by `ring`. The
`ring` crate contains a C test program that is built when building
`ring`. That is currently the first build error shown in the output
of the "Do max-pure build without being able to compile C or C++"
step.
  • Loading branch information
EliahKagan committed Nov 17, 2024
1 parent 275a0c5 commit e1555bd
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,24 @@ jobs:
done
- name: Install Rust via Rustup
run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
- uses: Swatinem/rust-cache@v2
- run: /github/home/.cargo/bin/cargo install --debug --locked --no-default-features --features max-pure --path .
- name: Add Rust tools to path
run: echo "PATH=$HOME/.cargo/bin:$PATH" >> "$GITHUB_ENV"
- name: Generate dependency tree
run: cargo tree --locked --no-default-features --features max-pure > tree.txt
- name: Scan for dependencies that build C or C++ code
run: |
pattern='.*\b(-sys|cc|cmake|pkg-config|vcpkg)\b.*'
! GREP_COLORS='ms=30;48;5;214' grep --color=always -Ex -C 1000000 -e "$pattern" tree.txt
continue-on-error: true
- name: Do max-pure build with minimal environment
run: cargo install --debug --locked --no-default-features --features max-pure --path .
- name: Clear target
run: cargo clean
- name: Break GCC's ability to compile C or C++
run: find /usr/lib/gcc \( -name cc1 -o -name cc1plus \) -print -delete
- name: Do max-pure build without being able to compile C or C++
run: cargo install --debug --locked --no-default-features --features max-pure --path .
continue-on-error: true

test:
runs-on: ubuntu-latest
Expand Down

0 comments on commit e1555bd

Please sign in to comment.