Skip to content

enable native libstdc++ cpp2v in macos - #246

Open
aa755 wants to merge 1 commit into
SkyLabsAI:mainfrom
aa755:codex/cpp2v-env-toolchain-config
Open

enable native libstdc++ cpp2v in macos#246
aa755 wants to merge 1 commit into
SkyLabsAI:mainfrom
aa755:codex/cpp2v-env-toolchain-config

Conversation

@aa755

@aa755 aa755 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

(created by codex-cli)

Summary

Add an environment-based toolchain configuration path to cpp2v.

This introduces the following CPP2V_* variables:

  • CPP2V_RESOURCE_DIR
  • CPP2V_TARGET
  • CPP2V_SYSROOT
  • CPP2V_GCC_TOOLCHAIN
  • CPP2V_CXX_INCLUDE_DIRS

When set, cpp2v translates them into the corresponding Clang frontend arguments before parsing:

  • -resource-dir=...
  • --target=...
  • --sysroot=...
  • --gcc-toolchain=...
  • -nostdinc++
  • explicit -isystem ... entries for the configured C++ include directories

If a target/sysroot/toolchain is configured through the environment, cpp2v skips the host-system default setup path. This avoids mixing host defaults, such as macOS/Darwin headers, with an explicitly configured Linux target sysroot.

Use case

In our use case, cpp2v runs as a native macOS executable, but Clang's frontend needs to parse C++ sources as Linux amd64 code using GCC/libstdc++ headers.

Concretely, on Apple Silicon macOS:

  • cpp2v itself is built against Homebrew LLVM and runs natively.
  • The source being translated is intended for Linux amd64.
  • A Linux amd64 sysroot provides the target headers and GCC/libstdc++ 15 headers.
  • CPP2V_TARGET=x86_64-linux-gnu makes Clang use Linux/x86 target assumptions.
  • CPP2V_SYSROOT and CPP2V_GCC_TOOLCHAIN point Clang at the target filesystem/toolchain.
  • CPP2V_CXX_INCLUDE_DIRS forces C++ standard-library ASTs to come from Linux GCC/libstdc++ rather than macOS/Homebrew libc++.

This is also useful when cpp2v is invoked indirectly by generated build rules, such as generated Dune rules. Some direct callers can pass --extra-arg-before=... flags explicitly, and some compile flags can come from compile_commands.json, but generated build rules may not be convenient to rewrite after generation. Environment-based configuration gives all cpp2v invocations in the build one central way to select the target, sysroot, GCC toolchain, Clang resource directory, and C++ standard-library include paths.

Testing

  • dune build @fmdeps/BRiCk/rocq-skylabs-cpp2v/cpp2v

@aa755
aa755 marked this pull request as ready for review July 1, 2026 22:19
@aa755 aa755 changed the title Add CPP2V_* environment toolchain configuration enable native libstdc++ cpp2v in macos Jul 1, 2026
@pgiarrusso-sl

Copy link
Copy Markdown
Contributor

cc @rlepigre-skylabs-ai

  • We have a different setup running cpp2v in docker (not available here), but this could be an idea.

  • How does one use this correctly and get a setup that matches a real compiler (say, clang on Linux)? I think we would need something more — the testing in the description is not enough.

I think we could merge this but make the pitfalls clear to users.

We don't even have a way to test that we got the right AST after preprocessing — but that's a pre-existing issue, so filed #254.

@aa755

aa755 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

(posted by codex)

I tested a fully public reproduction of the use case: native Apple Silicon
macOS running cpp2v built against Homebrew LLVM, but parsing sources as Linux
amd64 with Ubuntu 25.10 GCC 15/libstdc++ headers. The sysroot is created from a
public Docker image:

docker create --platform linux/amd64 ubuntu:25.10 ...
apt-get install -y --no-install-recommends gcc-15 g++-15 libc6-dev linux-libc-dev

Then cpp2v is run with:

export CPP2V_RESOURCE_DIR="$(/opt/homebrew/opt/llvm/bin/clang++ -print-resource-dir)"
export CPP2V_TARGET=x86_64-linux-gnu
export CPP2V_SYSROOT="$HOME/sysroots/ubuntu-25.10-amd64-gcc15"
export CPP2V_GCC_TOOLCHAIN="$CPP2V_SYSROOT/usr"
export CPP2V_CXX_INCLUDE_DIRS="$CPP2V_SYSROOT/usr/include/c++/15:$CPP2V_SYSROOT/usr/include/x86_64-linux-gnu/c++/15:$CPP2V_SYSROOT/usr/include/c++/15/backward"

The important bit is CPP2V_CXX_INCLUDE_DIRS: this PR turns it into
-nostdinc++ plus explicit -isystem entries. Without -nostdinc++, Clang can
silently use macOS/Homebrew libc++ headers, which is exactly the failure mode
we want to avoid.

I used the following standalone demo script locally; the public source is in this gist: demo-linux-libstdcxx-macos.sh (README).

./demo-linux-libstdcxx-macos.sh

It creates the Docker sysroot, exports the CPP2V_* variables, checks the same
configuration with native Clang using -fsyntax-only, then runs native cpp2v
on a small test file:

#include <cstdint>
#include <vector>

#ifndef __linux__
#error "cpp2v should parse this as Linux"
#endif

#ifndef __x86_64__
#error "cpp2v should parse this as x86_64"
#endif

std::uint64_t sum_vector(const std::vector<std::uint64_t> &xs) {
  std::uint64_t total = 0;
  for (std::uint64_t x : xs) {
    total += x;
  }
  return total;
}

The Docker-backed run succeeded:

./demo-linux-libstdcxx-macos.sh \
  --sysroot "$HOME/sysroots/ubuntu-25.10-amd64-gcc15" \
  --rebuild-sysroot \
  --cpp2v /path/to/cpp2v

The generated AST contained GCC/libstdc++ implementation names including
std::__glibcxx_assert_fail and std::_Vector_base, and the test source would
fail preprocessing if Clang were not seeing the Linux amd64 target.

@pgiarrusso-sl
pgiarrusso-sl requested review from gmalecha-at-skylabs and pgiarrusso-sl and removed request for gmalecha-at-skylabs July 13, 2026 14:19
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.

2 participants