google / google/xls

`xls/common/subprocess.cc` does not compile on macOS: uses `<linux/memfd.h>`, `memfd_create()` and `/proc/self/fd`

Closed
#4,991 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.9k
Forks
283
Avg merge
2d 10h
Merged PRs (30d)
135

Description

## Summary

`xls/common/subprocess.cc` unconditionally depends on three Linux-only facilities, so it cannot compile on macOS:

```
xls/common/subprocess.cc:18:10: fatal error: 'linux/memfd.h' file not found
18 | #include
| ^~~~~~~~~~~~~~~
```

Beyond the header, the same code path also uses:

- `memfd_create()` / `MFD_CLOEXEC` — a Linux syscall with no macOS equivalent
- the `/proc/self/fd/` path handed to `posix_spawnp()` — macOS has no `/proc` filesystem

So this is not just a missing include guard; the mechanism for exec'ing the embedded `subprocess_helper` out of an anonymous in-memory file descriptor does not exist on macOS.

The file still carries an `#if defined(__APPLE__)` block for `environ`, which suggests macOS support was intended. The Linux-only path came in with 2c355ce53 ("Embed subprocess_helper in subprocess.cc", 2026-04-30).

## Impact

Blocks `//xls/tools:codegen_main` on macOS, plus anything else depending on `//xls/common:subprocess`. Notably it does **not** block `interpreter_main`, `ir_converter_main` or `opt_main` — none of those depend on `subprocess` — but since Bazel aborts on the first error, a plain `bazel build` of all four appears to fail entirely.

This is one of the reasons `Nightly MacOS` is red (see also the llvm-project checksum issue).

## Reproduction

On macOS arm64, after working around the llvm-project checksum problem:

```
bazel build -c opt -- //xls/tools:codegen_main
```

## Suggested fix

Introduce a `GetSubprocessHelperPath()` that encapsulates producing an exec'able path for the embedded helper:

- **Linux**: unchanged — write the helper to a memfd, return `/proc/self/fd/`, hold the descriptor open for the lifetime of the process.
- **Apple**: materialize the helper into a temporary file with `mkstemp()` and mark it executable with `fchmod(0700)`, unlinking it via `std::atexit()` (and on the error paths).

The temporary file is unavoidable on macOS: unlike a Linux memfd it has a name and is not reclaimed automatically, it cannot be unlinked up front because exec resolves it by path, exec'ing an unlinked file through `/dev/fd/` is rejected with `EACCES`, and there is no `fexecve()`. A process killed by a signal will still leave one behind.

I have this working locally; `//xls/common:subprocess_test` (12 tests, covering non-zero exits, crashing children, large stdout/stderr, and environment variable propagation) passes on macOS arm64. Happy to send it as a PR.

Note that running that test on macOS also requires the `xls_cc_embed_data` shared-library fix filed separately.

## Related

#1434 (tracking issue: OS X aarch64 build/test status).

One note in that issue appears to be out of date: it states that the hermetic
LLVM toolchain does not work on OS X. I did not need to disable it -- building
with the hermetic toolchain on macOS arm64 worked, once the problem above and
the `xls_cc_embed_data` shared-library problem were addressed.

Also #1363 (macosx nightly builds are failing), which reports the symptom; this issue is one of the concrete causes.

## Environment

- macOS 26.6.2, arm64 (Apple Silicon)
- Bazel 8.7.0, XLS at `fc572666a`

Contributor guide

Open the contributing guide

Research direction

Start in xls/common/subprocess.cc, focusing on the embedded subprocess_helper path, Linux-only facilities, and the existing __APPLE__ handling. Run //xls/common:subprocess_test and bazel build -c opt -- //xls/tools:codegen_main on macOS; done means the target compiles and the 12 subprocess tests pass there.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, macos
Domain
build-system, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.