enable native libstdc++ cpp2v in macos - #246
Conversation
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. |
|
(posted by codex) I tested a fully public reproduction of the use case: native Apple Silicon docker create --platform linux/amd64 ubuntu:25.10 ...
apt-get install -y --no-install-recommends gcc-15 g++-15 libc6-dev linux-libc-devThen 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 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.shIt creates the Docker sysroot, exports the #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/cpp2vThe generated AST contained GCC/libstdc++ implementation names including |
(created by codex-cli)
Summary
Add an environment-based toolchain configuration path to
cpp2v.This introduces the following
CPP2V_*variables:CPP2V_RESOURCE_DIRCPP2V_TARGETCPP2V_SYSROOTCPP2V_GCC_TOOLCHAINCPP2V_CXX_INCLUDE_DIRSWhen set,
cpp2vtranslates them into the corresponding Clang frontend arguments before parsing:-resource-dir=...--target=...--sysroot=...--gcc-toolchain=...-nostdinc++-isystem ...entries for the configured C++ include directoriesIf a target/sysroot/toolchain is configured through the environment,
cpp2vskips 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,
cpp2vruns 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:
cpp2vitself is built against Homebrew LLVM and runs natively.CPP2V_TARGET=x86_64-linux-gnumakes Clang use Linux/x86 target assumptions.CPP2V_SYSROOTandCPP2V_GCC_TOOLCHAINpoint Clang at the target filesystem/toolchain.CPP2V_CXX_INCLUDE_DIRSforces C++ standard-library ASTs to come from Linux GCC/libstdc++ rather than macOS/Homebrew libc++.This is also useful when
cpp2vis 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 fromcompile_commands.json, but generated build rules may not be convenient to rewrite after generation. Environment-based configuration gives allcpp2vinvocations 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