Problem
ParserOptions::preprocess() hardcodes the preprocessor command to cc -E (clang) or cpp (GCC):
https://github.com/p4lang/p4c/blob/main/frontends/common/parser_options.cpp#L419-L422
#ifdef __clang__
std::string cmd("cc -E -x c -Wno-comment");
#else
std::string cmd("cpp");
#endif
There is no CLI flag to override this. Callers that need to provide a specific C preprocessor — most commonly because they're running in a hermetic sandbox without a system cc on PATH — have to resort to workarounds.
p4c's own p4_library.bzl works around this with a bash shell function:
function cc () {{ "{cc}" "$@"; }}
export -f cc
This works for ctx.actions.run_shell (Bazel actions) but breaks in contexts where the caller can't inject shell functions — e.g., Java/Kotlin ProcessBuilder, non-bash shells, or any environment where export -f isn't available.
Proposal
Add a --cc <path> flag (or --preprocessor <path>) that lets the caller specify the C preprocessor binary. When set, preprocess() would use the provided path instead of the hardcoded cc/cpp.
This would let Bazel rules pass the CC toolchain's compiler_executable directly, eliminating the shell function workaround in both p4_library.bzl and downstream rules.
Motivation
- Hermetic build environments (Bazel remote execution, google3/blaze) don't have
cc on PATH. Every consumer of p4c in these environments needs to work around this independently.
- Non-shell callers (JVM
ProcessBuilder, Python subprocess, etc.) can't use export -f and have to manipulate PATH to inject a shim script — fragile and error-prone.
- p4c already knows about this problem — the shell function pattern in
p4_library.bzl is the proof. A first-class flag would be cleaner for p4c's own Bazel rules too.
Problem
ParserOptions::preprocess()hardcodes the preprocessor command tocc -E(clang) orcpp(GCC):https://github.com/p4lang/p4c/blob/main/frontends/common/parser_options.cpp#L419-L422
There is no CLI flag to override this. Callers that need to provide a specific C preprocessor — most commonly because they're running in a hermetic sandbox without a system
ccon PATH — have to resort to workarounds.p4c's own
p4_library.bzlworks around this with a bash shell function:This works for
ctx.actions.run_shell(Bazel actions) but breaks in contexts where the caller can't inject shell functions — e.g., Java/KotlinProcessBuilder, non-bash shells, or any environment whereexport -fisn't available.Proposal
Add a
--cc <path>flag (or--preprocessor <path>) that lets the caller specify the C preprocessor binary. When set,preprocess()would use the provided path instead of the hardcodedcc/cpp.This would let Bazel rules pass the CC toolchain's
compiler_executabledirectly, eliminating the shell function workaround in bothp4_library.bzland downstream rules.Motivation
ccon PATH. Every consumer of p4c in these environments needs to work around this independently.ProcessBuilder, Pythonsubprocess, etc.) can't useexport -fand have to manipulate PATH to inject a shim script — fragile and error-prone.p4_library.bzlis the proof. A first-class flag would be cleaner for p4c's own Bazel rules too.