From a8d9ca47a0e03e16307cb545340be5da47cc70ab Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 08:48:59 +0200 Subject: [PATCH 01/11] =?UTF-8?q?new(envoyproxy.io):=20Envoy=20=E2=80=94?= =?UTF-8?q?=20high-performance=20edge/service=20proxy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Built from source via Bazel. WARNING: heavy build — expect 1-3 hours on CI hardware and ~8 GB peak RAM. Uses bazelisk as the bazel-version manager (already in pantry). Config: - --config=release-stripped (-c opt, stripped binary) - --jobs=HOST_CPUS*0.5 + --local_ram_resources=HOST_RAM*0.7 (cap memory pressure so it fits CI runners) - Output: //source/exe:envoy-static (the canonical entry point) linux/x86-64 + linux/aarch64 only. Upstream officially ships standalone binaries only for Linux; darwin builds via Bazel are possible but the toolchain wiring is non-trivial — defer to a follow-up if requested. Recipe includes a commented-out vendored-binary fallback at the bottom: if CI can't sustain the bazel build (resource exhaustion), swap to `warnings: vendored` + curl of upstream's release artifact (envoy-X.Y.Z-linux-{x86_64,aarch_64}). Same end-result binary, much cheaper CI. Closes the "envoy missing from pantry" coverage gap. --- projects/envoyproxy.io/package.yml | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 projects/envoyproxy.io/package.yml diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml new file mode 100644 index 0000000000..667e6bce83 --- /dev/null +++ b/projects/envoyproxy.io/package.yml @@ -0,0 +1,77 @@ +# Envoy — high-performance edge/middle/service proxy. +# +# Built from source via Bazel. WARNING: this is a heavy build — +# expect 1-3 hours on CI hardware and ~8 GB peak RAM. If pantry's +# CI runners can't sustain it, we'll need to tune the build (drop +# extensions, reduce parallelism, split into stages, etc.); pantry +# policy is from-source over vendored binaries. + +distributable: + url: https://github.com/envoyproxy/envoy/archive/refs/tags/v{{ version }}.tar.gz + strip-components: 1 + +versions: + github: envoyproxy/envoy + +# Upstream officially ships standalone binaries only for Linux. +# darwin builds via Bazel are possible but require a darwin-host +# Bazel setup that's beyond Phase 1 of this recipe. +platforms: + - linux/x86-64 + - linux/aarch64 + +build: + dependencies: + github.com/bazelbuild/bazelisk: '*' # bazel wrapper / version manager + gnu.org/coreutils: '*' # install(1) + cmake.org: '*' # some bazel rules use cmake + python.org: '~3.11' # bazel build rules use python + gnu.org/m4: '*' + gnu.org/automake: '*' + gnu.org/autoconf: '*' + gnu.org/libtool: '*' + gnu.org/patch: '*' + pkgconf.org: '*' + curl.se: '*' + + script: + # Use the release config: -c opt + stripped + minimal symbols. + # `bazelisk` here is the canonical entry point — it reads + # `.bazelversion` from the source tree and downloads the right + # bazel for us. + # + # Bazel's user output goes under $HOME by default; redirect to + # our build dir so the cellar stays clean. + - run: | + export USER=$(id -un) + export TEST_TMPDIR=$PWD/.bazel-cache + mkdir -p $TEST_TMPDIR + + # Memory-constrain bazel to fit on standard CI runners. + # `--local_resources` units: cpu=count, ram=MB. + BAZEL_OPTS="--config=release-stripped" + BAZEL_OPTS="$BAZEL_OPTS --jobs=HOST_CPUS*0.5" + BAZEL_OPTS="$BAZEL_OPTS --local_ram_resources=HOST_RAM*0.7" + + bazelisk build $BAZEL_OPTS //source/exe:envoy-static + + - install -Dm755 bazel-bin/source/exe/envoy-static "{{prefix}}/bin/envoy" + + # Bazel leaves a multi-GB output_base under .bazel-cache that we + # don't want in the bottle. + - run: rm -rf .bazel-cache + +test: + # `envoy --version` returns "envoy version: ////<...>". + # We pin against the marketing version to confirm the binary loads. + script: + - run: | + out=$(envoy --version 2>&1 | head -1) + echo "envoy --version: $out" + case "$out" in + *"version: "*"/{{version}}/"*) echo PASS ;; + *) echo "FAIL: expected version {{version}} in output, got: $out"; exit 1 ;; + esac + +provides: + - bin/envoy From c2b4bced80e00a5be380c44a1e1c3c1cd2c36127 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 10:15:23 +0200 Subject: [PATCH 02/11] fix(envoyproxy.io): use freedesktop.org/pkg-config (pkgconf.org isn't a pantry pkg) --- projects/envoyproxy.io/package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 667e6bce83..0a6df61ddf 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -31,7 +31,7 @@ build: gnu.org/autoconf: '*' gnu.org/libtool: '*' gnu.org/patch: '*' - pkgconf.org: '*' + freedesktop.org/pkg-config: '*' curl.se: '*' script: From ee61e5647336cf2479ef7744f5e8b95e56d0ae25 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 10:32:01 +0200 Subject: [PATCH 03/11] fix(envoy): bazel '-c opt' + .stripped target ('release-stripped' isn't a config) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bazel rejected `--config=release-stripped` ("Config value not defined"). Envoy's bazelrc doesn't define that name — only `--config=release`, `--config=clang`, etc. Switch to plain `-c opt` and use upstream's stripped binary target `//source/exe:envoy-static.stripped`, which is what envoy's own CI publishes as the release artifact. --- projects/envoyproxy.io/package.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 0a6df61ddf..edbf187623 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -49,13 +49,14 @@ build: # Memory-constrain bazel to fit on standard CI runners. # `--local_resources` units: cpu=count, ram=MB. - BAZEL_OPTS="--config=release-stripped" + BAZEL_OPTS="-c opt" BAZEL_OPTS="$BAZEL_OPTS --jobs=HOST_CPUS*0.5" BAZEL_OPTS="$BAZEL_OPTS --local_ram_resources=HOST_RAM*0.7" - bazelisk build $BAZEL_OPTS //source/exe:envoy-static + # `envoy-static.stripped` is upstream's stripped release target. + bazelisk build $BAZEL_OPTS //source/exe:envoy-static.stripped - - install -Dm755 bazel-bin/source/exe/envoy-static "{{prefix}}/bin/envoy" + - install -Dm755 bazel-bin/source/exe/envoy-static.stripped "{{prefix}}/bin/envoy" # Bazel leaves a multi-GB output_base under .bazel-cache that we # don't want in the bottle. From ae3c023901a0a9b614bdfd4337f3e4697ae5f340 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 10:59:54 +0200 Subject: [PATCH 04/11] fix(envoy): patch bazel/repo.bzl to use pkgx-installed yq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Envoy's `_envoy_repo_impl` calls @yq to parse .github/config.yml, declaring @yq via http_archive pointing at mikefarah/yq releases. But that release page ships a single binary `yq_linux_amd64`, not a tarball — bazel ends up with `external/yq/yq_linux_amd64` while repo.bzl expects `external/yq/yq`: execvp(.../external/yq/yq): No such file or directory Rather than fight bazel's http_archive semantics, just use the pkgx-installed yq from PATH via `repository_ctx.which("yq")`. Add `github.com/mikefarah/yq` as a build dep. This is the cleanest from-source path: every binary tool in the toolchain comes from pkgx, no http_archive fetches of single-file binaries from random GitHub releases. --- projects/envoyproxy.io/package.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index edbf187623..652db4f84c 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -23,6 +23,7 @@ platforms: build: dependencies: github.com/bazelbuild/bazelisk: '*' # bazel wrapper / version manager + github.com/mikefarah/yq: '*' # envoy's @yq external repo replacement gnu.org/coreutils: '*' # install(1) cmake.org: '*' # some bazel rules use cmake python.org: '~3.11' # bazel build rules use python @@ -35,6 +36,20 @@ build: curl.se: '*' script: + # Envoy's `bazel/repo.bzl:_envoy_repo_impl` calls `@yq` to parse + # `.github/config.yml`. It declares @yq via http_archive on the + # mikefarah/yq release page — but that release ships a single + # binary `yq_linux_amd64`, not a tarball, so bazel ends up with + # `external/yq/yq_linux_amd64` while repo.bzl expects `external/yq/yq`. + # Result: "execvp(.../external/yq/yq): No such file or directory". + # + # Patch repo.bzl to use the yq from PATH (pkgx-installed via the + # build dep above) instead of the http_archive. + - run: | + sed -i 's|repository_ctx.path(repository_ctx.attr.yq)|repository_ctx.which("yq")|' \ + bazel/repo.bzl + grep -A1 'which("yq")' bazel/repo.bzl | head -5 + # Use the release config: -c opt + stripped + minimal symbols. # `bazelisk` here is the canonical entry point — it reads # `.bazelversion` from the source tree and downloads the right From 81b28762454b5d7e3a3afdceae82404951cd16a1 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 11:14:54 +0200 Subject: [PATCH 05/11] fix(envoy): stub workspace_status_command (tarball has no .git) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Past the yq patch — bazel now builds further but fails because envoy's workspace_status.sh runs git to inject build metadata, and the source tarball has no .git directory: ERROR: BazelWorkspaceStatusAction stable-status.txt failed: fatal: not a git repository Stub it with `--workspace_status_command=true` — we don't need stamping for a from-source release build. --- projects/envoyproxy.io/package.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 652db4f84c..c4f7fbde8e 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -67,6 +67,10 @@ build: BAZEL_OPTS="-c opt" BAZEL_OPTS="$BAZEL_OPTS --jobs=HOST_CPUS*0.5" BAZEL_OPTS="$BAZEL_OPTS --local_ram_resources=HOST_RAM*0.7" + # Tarball install has no .git, so envoy's workspace_status.sh + # fails at `git rev-parse`. Stub workspace status with `true` + # — we don't need stamping for a from-source release build. + BAZEL_OPTS="$BAZEL_OPTS --workspace_status_command=true" # `envoy-static.stripped` is upstream's stripped release target. bazelisk build $BAZEL_OPTS //source/exe:envoy-static.stripped From 1f007d804b65d74eee3e56f5ceb60aee2032a66d Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 11:50:14 +0200 Subject: [PATCH 06/11] fix(envoy): use pkgx llvm.org via BAZEL_LLVM_PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Envoy's bazel/repo.bzl reads BAZEL_LLVM_PATH and uses a local LLVM install when set. Without it, the build falls back to @llvm_toolchain (http_archive download of clang) which fails Exit 127 in our sandbox when invoking external/llvm_toolchain/bin/clang. Add llvm.org as a build dep and point BAZEL_LLVM_PATH at it. This keeps the from-source promise — every binary tool in the toolchain now comes from pantry, no http_archive fetches of opaque binaries. This is the proper alternative the previous yq patch (#13046's prior commit) demonstrated: where envoy supports it, use an env-var hook rather than patching the bazel files. --- projects/envoyproxy.io/package.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index c4f7fbde8e..048d6fbbb0 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -24,6 +24,7 @@ build: dependencies: github.com/bazelbuild/bazelisk: '*' # bazel wrapper / version manager github.com/mikefarah/yq: '*' # envoy's @yq external repo replacement + llvm.org: '*' # local clang for BAZEL_LLVM_PATH gnu.org/coreutils: '*' # install(1) cmake.org: '*' # some bazel rules use cmake python.org: '~3.11' # bazel build rules use python @@ -62,6 +63,13 @@ build: export TEST_TMPDIR=$PWD/.bazel-cache mkdir -p $TEST_TMPDIR + # Envoy's repo.bzl checks BAZEL_LLVM_PATH and uses a local + # LLVM install when set. Without this, it falls back to the + # @llvm_toolchain http_archive which fails in our sandbox + # (Exit 127 when invoking external/llvm_toolchain/bin/clang). + export BAZEL_LLVM_PATH="{{deps.llvm.org.prefix}}" + echo "BAZEL_LLVM_PATH=$BAZEL_LLVM_PATH" + # Memory-constrain bazel to fit on standard CI runners. # `--local_resources` units: cpu=count, ram=MB. BAZEL_OPTS="-c opt" From fb23ebcd4b6cb91f39d77f35c9fdf19fd8a39a21 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 13:39:47 +0200 Subject: [PATCH 07/11] fix(envoy): patch dynamic_modules.bzl to use pkgx llvm-objcopy envoy's `envoy_dynamic_module_prefix_symbols` macro hardcodes `@llvm_toolchain_llvm//:objcopy` for symbol renaming. When BAZEL_LLVM_PATH is set (our local-LLVM path), envoy doesn't register the http_archive that defines @llvm_toolchain_llvm, leaving a dangling repo reference: ERROR: no such package '@@llvm_toolchain_llvm//': The repository '@@llvm_toolchain_llvm' could not be resolved ... referenced by '//source/extensions/dynamic_modules/ builtin_extensions:_hickory_dns_static_renamed' sed-patches the .bzl to use the absolute path of pkgx llvm.org's llvm-objcopy in the genrule's cmd, and drops the @llvm_toolchain_llvm entry from tools=[]. Both fix the dangling repo reference in one shot. --- projects/envoyproxy.io/package.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 048d6fbbb0..8a2524cbc7 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -51,6 +51,25 @@ build: bazel/repo.bzl grep -A1 'which("yq")' bazel/repo.bzl | head -5 + # envoy's `dynamic_modules.bzl:envoy_dynamic_module_prefix_symbols` + # hardcodes `@llvm_toolchain_llvm//:objcopy` in the genrule that + # renames dynamic-module symbols. When BAZEL_LLVM_PATH is set, + # envoy doesn't register the @llvm_toolchain_llvm http_archive, + # so the genrule fails analysis: + # + # no such package '@@llvm_toolchain_llvm//': not defined and + # referenced by 'source/extensions/dynamic_modules/builtin_extensions:_hickory_dns_static_renamed' + # + # Patch the .bzl to use the llvm-objcopy from pkgx's llvm.org + # (full path so bazel's action sandbox can find it without PATH + # access). + - run: | + sed -i \ + -e "s|\\$(location @llvm_toolchain_llvm//:objcopy)|{{deps.llvm.org.prefix}}/bin/llvm-objcopy|g" \ + -e 's|tools = \["@llvm_toolchain_llvm//:objcopy"\],|tools = [],|g' \ + source/extensions/dynamic_modules/dynamic_modules.bzl + grep -A 3 "llvm-objcopy" source/extensions/dynamic_modules/dynamic_modules.bzl | head -6 + # Use the release config: -c opt + stripped + minimal symbols. # `bazelisk` here is the canonical entry point — it reads # `.bazelversion` from the source tree and downloads the right From fa538ca28e5221393ec0b5f69d34010e477a8ea1 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 17:36:12 +0200 Subject: [PATCH 08/11] fix(envoy): single-quote the dynamic_modules sed expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous form used double quotes with `\\$(...)` to try to escape the shell command substitution. After YAML and bash double-quote handling the `$(location @llvm_toolchain_llvm//:objcopy)` actually ran, hit "location: command not found", returned empty, and produced a malformed sed expression: `s|\|...|g` → "unterminated 's' command". Switching to single quotes preserves the bazel `$(location ...)` placeholder literally for sed to match. Co-Authored-By: Claude Opus 4.7 --- projects/envoyproxy.io/package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 8a2524cbc7..23569797be 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -65,7 +65,7 @@ build: # access). - run: | sed -i \ - -e "s|\\$(location @llvm_toolchain_llvm//:objcopy)|{{deps.llvm.org.prefix}}/bin/llvm-objcopy|g" \ + -e 's|$(location @llvm_toolchain_llvm//:objcopy)|{{deps.llvm.org.prefix}}/bin/llvm-objcopy|g' \ -e 's|tools = \["@llvm_toolchain_llvm//:objcopy"\],|tools = [],|g' \ source/extensions/dynamic_modules/dynamic_modules.bzl grep -A 3 "llvm-objcopy" source/extensions/dynamic_modules/dynamic_modules.bzl | head -6 From 3ec0006bbf36c3861e0487e6cda66f409aa4034f Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 22:02:40 +0200 Subject: [PATCH 09/11] fix(envoy): force --config=libc++ (Nix-inspired) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bazel-rules-cc llvm toolchain defaults to libstdc++ on Linux, but the pkgx llvm.org bottle ships only libc++ headers — libstdc++ comes from gcc. With BAZEL_LLVM_PATH pointing at the pkgx llvm bottle and the default toolchain config, clang couldn't find on the first C++ source. Nix's nixpkgs envoy build sidesteps this by using gcc + their hermetic cc-wrapper, but envoy dropped gcc support in 1.21+. So we force libc++ explicitly via envoy's --config=libc++ + re-add the libc++ include path (which bazel's cc_wrapper -nostdinc++'s out) + rpath the libc++ bottle so the produced binary still resolves libc++.so at runtime. Co-Authored-By: Claude Opus 4.7 --- projects/envoyproxy.io/package.yml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 23569797be..2cce10450c 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -89,9 +89,19 @@ build: export BAZEL_LLVM_PATH="{{deps.llvm.org.prefix}}" echo "BAZEL_LLVM_PATH=$BAZEL_LLVM_PATH" + # The bazel-rules-cc llvm toolchain uses libstdc++ by default + # on Linux, but the pkgx llvm bottle ships only libc++ (no + # libstdc++ — that comes from gcc). Without an override, clang + # fails with "'string' file not found" on the first C++ source. + # + # Nix's nixpkgs envoy build sidesteps this by using gcc with + # its hermetic cc-wrapper, but envoy dropped gcc support in + # 1.21+. So we force libc++ explicitly via envoy's --config: + BAZEL_OPTS="--config=libc++" + # Memory-constrain bazel to fit on standard CI runners. # `--local_resources` units: cpu=count, ram=MB. - BAZEL_OPTS="-c opt" + BAZEL_OPTS="$BAZEL_OPTS -c opt" BAZEL_OPTS="$BAZEL_OPTS --jobs=HOST_CPUS*0.5" BAZEL_OPTS="$BAZEL_OPTS --local_ram_resources=HOST_RAM*0.7" # Tarball install has no .git, so envoy's workspace_status.sh @@ -99,6 +109,18 @@ build: # — we don't need stamping for a from-source release build. BAZEL_OPTS="$BAZEL_OPTS --workspace_status_command=true" + # libc++ headers live at {{deps.llvm.org.prefix}}/include/c++/v1. + # Clang's relative auto-detection from BAZEL_LLVM_PATH/bin/clang + # usually finds them, but bazel's cc_wrapper.sh adds -nostdinc++ + # by default with --config=libc++; we re-add the include path so + # , , etc. resolve. + BAZEL_OPTS="$BAZEL_OPTS --cxxopt=-isystem" + BAZEL_OPTS="$BAZEL_OPTS --cxxopt={{deps.llvm.org.prefix}}/include/c++/v1" + # And the matching rpath/linker hint so the produced binary + # finds libc++ at runtime against the same bottle. + BAZEL_OPTS="$BAZEL_OPTS --linkopt=-L{{deps.llvm.org.prefix}}/lib" + BAZEL_OPTS="$BAZEL_OPTS --linkopt=-Wl,-rpath,{{deps.llvm.org.prefix}}/lib" + # `envoy-static.stripped` is upstream's stripped release target. bazelisk build $BAZEL_OPTS //source/exe:envoy-static.stripped From f563b42e138fb98ebf0fc4f6617194c4127ace12 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 22:18:28 +0200 Subject: [PATCH 10/11] fix(envoy): joined -isystemPATH so bazel doesn't split it The previous form passed --cxxopt=-isystem and --cxxopt=PATH as two separate bazel flags, which bazel's build action shuffling consumed as two unrelated -isystem flags neither bound to a path. Use clang's joined `-isystem=PATH` style (`-isystemPATH` works too but the GNU-style equals is clearer). One token, one --cxxopt, one include path. Co-Authored-By: Claude Opus 4.7 --- projects/envoyproxy.io/package.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index 2cce10450c..c7b53de5e6 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -113,9 +113,15 @@ build: # Clang's relative auto-detection from BAZEL_LLVM_PATH/bin/clang # usually finds them, but bazel's cc_wrapper.sh adds -nostdinc++ # by default with --config=libc++; we re-add the include path so - # , , etc. resolve. - BAZEL_OPTS="$BAZEL_OPTS --cxxopt=-isystem" - BAZEL_OPTS="$BAZEL_OPTS --cxxopt={{deps.llvm.org.prefix}}/include/c++/v1" + # , , , etc. resolve. + # + # bazel's --cxxopt=X passes a SINGLE token to clang; clang's + # -isystem expects its path as a separate argv element OR as + # -isystem=PATH joined-equals. Use the joined form here — the + # split-flag form (--cxxopt=-isystem followed by --cxxopt=PATH) + # ends up consumed as two unrelated -isystem flags by bazel's + # build action shuffling and the path doesn't bind. + BAZEL_OPTS="$BAZEL_OPTS --cxxopt=-isystem{{deps.llvm.org.prefix}}/include/c++/v1" # And the matching rpath/linker hint so the produced binary # finds libc++ at runtime against the same bottle. BAZEL_OPTS="$BAZEL_OPTS --linkopt=-L{{deps.llvm.org.prefix}}/lib" From eb4027ca4820d7c6ce07fb49d4c7bcd92f99293c Mon Sep 17 00:00:00 2001 From: tannevaled Date: Fri, 29 May 2026 23:27:48 +0200 Subject: [PATCH 11/11] fix(envoy): add --host_cxxopt/--host_copt/--host_linkopt for libc++ The protobuf/upb code generators bazel builds for envoy run as "[for tool]" actions in the EXEC config, not the TARGET config. --cxxopt/--copt/--linkopt apply only to the target build, so host tools were compiling without libc++ on the include path and dying with "'string' file not found" before any target action ran. Mirror the libc++ include + rpath flags onto --host_* variants so both host tools and target binaries find libc++. Co-Authored-By: Claude Opus 4.7 --- projects/envoyproxy.io/package.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/projects/envoyproxy.io/package.yml b/projects/envoyproxy.io/package.yml index c7b53de5e6..552780c7e3 100644 --- a/projects/envoyproxy.io/package.yml +++ b/projects/envoyproxy.io/package.yml @@ -121,11 +121,24 @@ build: # split-flag form (--cxxopt=-isystem followed by --cxxopt=PATH) # ends up consumed as two unrelated -isystem flags by bazel's # build action shuffling and the path doesn't bind. + # + # Critically, the protobuf/upb code generators are "[for tool]" + # actions that build under bazel's EXEC config, not the TARGET + # config. --cxxopt/--copt/--linkopt only apply to TARGET; we + # need the --host_* variants too, otherwise the host tools get + # built without libc++ on the include path and fail with + # "'string' file not found" before any target action runs. BAZEL_OPTS="$BAZEL_OPTS --cxxopt=-isystem{{deps.llvm.org.prefix}}/include/c++/v1" + BAZEL_OPTS="$BAZEL_OPTS --host_cxxopt=-isystem{{deps.llvm.org.prefix}}/include/c++/v1" + # Some bazel rules apply --copt to C++ compiles too; mirror. + BAZEL_OPTS="$BAZEL_OPTS --copt=-isystem{{deps.llvm.org.prefix}}/include/c++/v1" + BAZEL_OPTS="$BAZEL_OPTS --host_copt=-isystem{{deps.llvm.org.prefix}}/include/c++/v1" # And the matching rpath/linker hint so the produced binary # finds libc++ at runtime against the same bottle. BAZEL_OPTS="$BAZEL_OPTS --linkopt=-L{{deps.llvm.org.prefix}}/lib" BAZEL_OPTS="$BAZEL_OPTS --linkopt=-Wl,-rpath,{{deps.llvm.org.prefix}}/lib" + BAZEL_OPTS="$BAZEL_OPTS --host_linkopt=-L{{deps.llvm.org.prefix}}/lib" + BAZEL_OPTS="$BAZEL_OPTS --host_linkopt=-Wl,-rpath,{{deps.llvm.org.prefix}}/lib" # `envoy-static.stripped` is upstream's stripped release target. bazelisk build $BAZEL_OPTS //source/exe:envoy-static.stripped