<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Protoc on despatches</title><link>https://icle.es/tags/protoc/</link><description>Recent content in Protoc on despatches</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 20 Jun 2025 08:42:17 +0100</lastBuildDate><atom:link href="https://icle.es/tags/protoc/index.xml" rel="self" type="application/rss+xml"/><item><title>Use `protoc` bin instead of building from source in `bazel`</title><link>https://icle.es/2025/06/09/use-protoc-bin-in-bazel/</link><pubDate>Mon, 09 Jun 2025 20:57:53 +0000</pubDate><guid>https://icle.es/2025/06/09/use-protoc-bin-in-bazel/</guid><description>&lt;p>I work on a project that uses &lt;code>pulumi&lt;/code> automation api, which in turn uses
&lt;code>protobuf&lt;/code>. I think there are other bits in &lt;code>bazel&lt;/code> that also uses it.&lt;/p>
&lt;p>For a while, it was fine - except that some &lt;code>CI&lt;/code> runs would take 15 minutes and
we couldn&amp;rsquo;t quite figure out why.&lt;/p>
&lt;p>I finally had to update &lt;code>bazel&lt;/code> from 7.x to 8 and in that process (which
honestly could have been easier, but oh well), I ran into a problem with
compiling protobuf.&lt;/p>
&lt;p>Namely, I kept running into this error:&lt;/p>
```
error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
```
&lt;p>I tried many things but was not able to get past this error. In the end, I was
able to narrow it down to devbox/nix and how it messes with the environment that
doesn&amp;rsquo;t quite agree with &lt;code>bazel&lt;/code>.&lt;/p>
&lt;h2 id="what-didnt-work">What didn&amp;rsquo;t work&lt;/h2>
&lt;ul>
&lt;li>installing &lt;code>gcc&lt;/code> from devbox&lt;/li>
&lt;li>installing &lt;code>stdenv.cc.cc.lib&lt;/code>&lt;/li>
&lt;li>Setting &lt;code>LD_LIBRARY_PATH&lt;/code> (to
&lt;code>&amp;lt;workspace-dir&amp;gt;/.devbox/nix/profile/default/lib&lt;/code>, which is where the devbo
version of &lt;code>libstdc++.so.6&lt;/code> is installed by &lt;code>stdenv.cc.cc.lib&lt;/code>)&lt;/li>
&lt;li>Using the &lt;code>--action-env=&lt;/code>&lt;/li>
&lt;li>&lt;a href="https://github.com/tweag/rules_nixpkgs">rules-nixpkgs&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>None of which really worked.&lt;/p>
&lt;p>Disabling &lt;code>devbox&lt;/code> &lt;strong>did&lt;/strong> work, which was at least partly encouraging. I also
found a bunch of evidence online around this issue
(&lt;a href="https://github.com/bazelbuild/bazel/issues/12978">1&lt;/a>,
&lt;a href="https://github.com/jetify-com/devbox/issues/1100">2&lt;/a>,
&lt;a href="https://github.com/jetify-com/devbox/issues/1596">3&lt;/a>,
&lt;a href="https://github.com/jetify-com/devbox/issues/710">4&lt;/a>,
&lt;a href="https://github.com/tweag/rules_nixpkgs/issues/573">5&lt;/a>). Bazel seems to
&lt;a href="https://discuss.ray.io/t/bazel-protobuf-build-errors-libstdc-with-non-system-gcc/3329">generally dislike non-system gcc&lt;/a>.&lt;/p></description><content:encoded><![CDATA[<p>I work on a project that uses <code>pulumi</code> automation api, which in turn uses
<code>protobuf</code>. I think there are other bits in <code>bazel</code> that also uses it.</p>
<p>For a while, it was fine - except that some <code>CI</code> runs would take 15 minutes and
we couldn&rsquo;t quite figure out why.</p>
<p>I finally had to update <code>bazel</code> from 7.x to 8 and in that process (which
honestly could have been easier, but oh well), I ran into a problem with
compiling protobuf.</p>
<p>Namely, I kept running into this error:</p>
```
error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
```
<p>I tried many things but was not able to get past this error. In the end, I was
able to narrow it down to devbox/nix and how it messes with the environment that
doesn&rsquo;t quite agree with <code>bazel</code>.</p>
<h2 id="what-didnt-work">What didn&rsquo;t work</h2>
<ul>
<li>installing <code>gcc</code> from devbox</li>
<li>installing <code>stdenv.cc.cc.lib</code></li>
<li>Setting <code>LD_LIBRARY_PATH</code> (to
<code>&lt;workspace-dir&gt;/.devbox/nix/profile/default/lib</code>, which is where the devbo
version of <code>libstdc++.so.6</code> is installed by <code>stdenv.cc.cc.lib</code>)</li>
<li>Using the <code>--action-env=</code></li>
<li><a href="https://github.com/tweag/rules_nixpkgs">rules-nixpkgs</a></li>
</ul>
<p>None of which really worked.</p>
<p>Disabling <code>devbox</code> <strong>did</strong> work, which was at least partly encouraging. I also
found a bunch of evidence online around this issue
(<a href="https://github.com/bazelbuild/bazel/issues/12978">1</a>,
<a href="https://github.com/jetify-com/devbox/issues/1100">2</a>,
<a href="https://github.com/jetify-com/devbox/issues/1596">3</a>,
<a href="https://github.com/jetify-com/devbox/issues/710">4</a>,
<a href="https://github.com/tweag/rules_nixpkgs/issues/573">5</a>). Bazel seems to
<a href="https://discuss.ray.io/t/bazel-protobuf-build-errors-libstdc-with-non-system-gcc/3329">generally dislike non-system gcc</a>.</p>
<h2 id="a-ray-of-hope">A ray of hope</h2>
<p>I was just about ready to throw in the towel when ChatGPT, in passing suggested
using the <code>protobuf</code> binary directly. I wasn&rsquo;t even using this binary - it was
being pulled in as a dependency and I just needed it to work. I did not need it
to be built from source.</p>
<p>Furthermore, I found, from my research into trying to solve this that building
<code>protobuf</code> was the likely culprit in the <code>CI</code> taking 15 minutes.</p>
<p>I also remembered that someone else on the team had issues trying to get it to
build on a mac at some point.</p>
<p>All in all, it was a problematic piece of software and I was seriously
considering switching to <code>opentofu</code> - but they might be using it too.</p>
<h2 id="bin-protoc">bin <code>protoc</code></h2>
<p>It was difficult to find decent documentation about how to achieve this though,
apart from a partially answered on:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/68918369/is-it-possible-to-use-bazel-without-compiling-protobuf-compiler">stackoverflow question</a>,</li>
<li><a href="https://groups.google.com/g/bazel-discuss/c/3Q_GEqNZrC0">google groups for bazel-discuss</a>
<ul>
<li>which also led me to
<a href="https://gitlab.com/mvfwd/issue-bazel-protobuf-compile/-/tree/main">a gitlab repo with some code</a></li>
</ul>
</li>
</ul>
<p>These resources gave me just enough to be able to cobble together a working
solution, which needs:</p>
<h3 id="install-protoc">Install <code>protoc</code></h3>
<p>The first thing we need is a locally installed <code>protoc</code> bin (I&rsquo;ll used devbox to
install it for consistency across dev environments)</p>
```bash
devbox add protobuf
```
<p>You can add a version specifier for better reproducibility.</p>
<h3 id="runnable-target">Runnable Target</h3>
<p>We also need a shell target that will execute this correctly. The <code>bazel</code> flag
to override <code>protoc</code> takes a local target, not a bin.</p>
<p><code>third_party/tools/BUILD.bazel</code></p>
```python
package(default_visibility = ["//visibility:public"])

sh_binary(
    name = "protoc",
    srcs = ["protoc.sh"],
)

# https://github.com/protocolbuffers/protobuf/blob/b4b0e304be5a68de3d0ee1af9b286f958750f5e4/BUILD#L773
proto_lang_toolchain(
    name = "cc_toolchain",
    command_line = "--cpp_out=$(OUT)",
    runtime = ":protoc",
    visibility = ["//visibility:public"],
)
```
<p><code>third_party/tools/protoc.sh</code></p>
```bash
#!/bin/env bash
protoc "$@"
```
<h3 id="override-protoc">Override protoc</h3>
<p>You should now be able to override <code>protoc</code> with:</p>
```bash
bazel build --proto_compiler=//third_party/tools:protoc ...
```
<p>Having to pass in a flag each time is annoying though, and you can add it to
your <code>.bazelrc</code></p>
```
build --proto_compiler=//third_party/tools:protoc
```
<h3 id="sample-code">Sample code</h3>
<p>You can find the sample code in
<a href="https://github.com/drone-ah/wordsonsand">the wordsonsand repo</a> which uses this
exact solution to override <code>protoc</code> and get the <code>pulumi</code> sample code to work ;)</p>
<p>PS: It also includes a fully migrated <code>MODULES.bazel</code> with support for <code>golang</code>.
You will also want to check out <code>BUILD</code> in the root.</p>]]></content:encoded></item></channel></rss>