bazel-created binaries and Linux packaging

205 views
Skip to first unread message

David Given

unread,
Jun 8, 2022, 2:23:49 PM6/8/22
to bazel-discuss
I originally asked this on SO, but they suggested this might work better here, so:

I'm investigating the use of bazel to build some of my software. Unfortunately, I think I've come across a show-stopping issue, which is that bazel binaries can't be packaged for distributions like Debian.

The issue is that bazel is very keen on downloading external dependencies as source code and then compiling and linking them into the resulting binary. The protobuf libraries are an example of this. This is strictly forbidden for most Linux (and other) distributions; legally packaged binaries need to link to the system libraries rather than embedding their own copies.

Is there any way around this? Is it possible, for example, to tell bazel that instead of using a certain remote dependency (e.g. com_github_protocolbuffers_protobuf), it should instead use a custom one which refers to the system version? This would of course require telling bazel to ignore the hash in the http_archive line, which is terrible.

Philipp Schrader

unread,
Jun 9, 2022, 1:28:54 AM6/9/22
to bazel-discuss
I am confused. Isn't the default for bazel to link against stuff on the host? I.e. if you add `linkopts = ["-lpng"]` to a bazel setup without a libpng external repo, wouldn't this link against the host's libpng?

Andreas Ames

unread,
Jun 9, 2022, 2:24:04 AM6/9/22
to David Given, bazel-discuss
IMHO, this "eager-building" feature is one of the big plusses of Bazel.

In most cases I have seen, Bazel will buid external dependencies (in C/C++) as shared libraries.  Usually, it does quite specific things with the RPATH in the resulting binaries built from your own code.  What I am doing is:
1. Use the eager-build feature and profit from being able to test my binaries in-place (because of the default RPATH, Bazel configures)
2. For creating Debian packages I use rules_pkg to create debs only for my binaries (not 3rd-party ones)
3. I am only loading shared libraries, which are handled by /etc/ld.so.conf but there is nothing preventing you from setting your own RPATH in your binaries (which isn' allowed though for official debs, AFAIK). For debs installed from the official repositories the default ld.so config should probably be sufficient.

If you are using the right version of the external dependencies (the same ones as are used in your targeted Debian version) I guess you should be fine.  Otherwise, I have misunderstood your issue; sorry, if so.
 

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/21cdb1bc-eb51-4688-996f-8bd6661d4b62n%40googlegroups.com.

david...@gmail.com

unread,
Jun 9, 2022, 9:45:34 AM6/9/22
to Philipp Schrader, bazel-discuss
bazel will only link to system libraries if you explicitly tell it to --- as you say, linkopts = [ "-lpng" ].

The issue I'm facing is situations like with rules_proto:

- the developer wants to use protobufs in their program.
- they pull in rules_proto (as is recommended).
- rules_proto pulls in com_github_protocolbuffers_protobuf 3.20.0.
- this is compiled for both the host, for use in protoc, and for the target.
- target binaries are then linked against this local version of com_github_protocolbuffers_protobuf.

(This linking may be static or dynamic-to-a-.so-in-runfiles, which is essentially the same thing.)

Now, with my package maintainer hat on, I need to make this produce legal binaries to go into a package. If the binary uses dynamic-to-a-.so-in-runfiles linking, then it's theoretically possible to pull the binary out and point it at the system shared library; but on the Debian system I'm typing this on, the latest version of libprotobuf-dev is 3.12.4-1+build7, which is rather older than the one bazel used, and even then the idea of distributing official binaries which are built against a different version of the headers than the library they're linked to is terrible. It's not as if, as a maintainer, I can patch out the dependency on protobuf 3.20.0 --- that dependency is buried deep inside rules_proto, which is in turn pulled from an external repository. Remember, I am not the author here; I'm just the maintainer.

As a Debian maintainer I always want binaries to be built against system libraries except when absolutely necessary. But it looks like bazel is designed to never build against system libraries (unless the developer opted for this up front). I don't think these design goals are compatible.

I recently discovered that meson actually has support for this built in; the developer can declare a dependency on an embedded library ('subproject' in meson terminology), which is then distributed along with the source. But, if a system library version of the dependency is available, then that is used in preference to the embedded subproject. Is anything like that available in bazel?

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.

David Given

unread,
Feb 14, 2023, 10:33:25 AM2/14/23
to bazel-discuss
<gentle prod to see if anyone is thinking about this>

One option I've been considering is to add a workspace rule which will download and unpack a specific system library package and make it available for linking. This would allow programs built with bazel to produce binaries which are distributable, but still in a hermetic environment. This would allow cross-compilation. This should be easily extensible to multiple operating systems, including, say, mingw.

The biggest issue, though, is that it would be opt-in for developers. They would have to start from the very beginning planning to produce distributable binaries, and would have to avoid using the wider bazel ecosystem ---- for example, using rules_proto would still statically link the library and render the binaries undistributable. Ideally there would be a solution where the developer doesn't have to think about any of this because the distribution packager could override the developer's choice. For the specific case of debian this would be doable by patching the build files, but ew.

Is there a better way?
Reply all
Reply to author
Forward
0 new messages