-
Notifications
You must be signed in to change notification settings - Fork 524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proto-build: optionally unbundle protoc #576
Conversation
This commit makes it possible to opt out of downloading the bundled pre-compiled protoc binaries. This is useful for downstream users with strict supply chain security requirements (see tokio-rs#575 for details). The approach taken is to move the pre-compiled binaries to a new crate called `protoc-bin`. prost-build depends on this crate only if the `protoc-vendored-bin` feature is enabled (which it is by default). While it was always possible to avoid the vendored binaries by specifying the `PROTOC` environment variable, the feature is a bit more foolproof; security-concious users can audit their Cargo.lock to ensure that the protc-bin crate is never even downloaded. This commit also adds a new feature called `protoc-vendored-src`, which uses the new `protobuf-src` crate to compile a copy of protoc from source on the fly. This feature makes `cargo build` seamless on all platforms that Protobuf supports, not just those that protoc-bin distributed pre-compiled binaries for, but has the downside of requiring a C++ toolchain and increasing compile times. If neither of the new vendored features are enabled, `prost-build` fails unless `PROTOC` and `PROTOC_INCLUDE` are explicitly specified.
This PR is a good first step to solving the supply chain security concerns in #562 and #575! I have some comments below. Environment variables instead of cargo featuresOnly the "root" of the dependency of graph (AKA the executable being built) should have control over how Each crate Also, there is no good way to resolve conflicting features. Due to how cargo resolves feature unification, the prost crate may be compiled with with the features to use source and binary The end-user is the one who can make the best security decisions as to how Fail closedThis would be a breaking change, but I vote that this feature "fails closed" (be secure-by-default). For example:
The openssl-sys crate does a good job of emitting a descriptive error message when OpenSSL cannot be found: On a side note, I think it's reasonable to expect that a user has a C++ compiler available to compile protobuf from source. If the user is already compiling Rust, then they probably have a C++ compiler. A C compiler is essentially required to link Rust binaries (which is probably accompanied by a C++ compiler). |
I agree wholeheartedly with this. Unfortunately it's a nonstarter for us to move to a model where environment variables are required for a successful compile. We maintain the invariant for Materialize that a
I think using features is unavoidable, though, because otherwise you'll be stuck downloading both the binary blobs and compiling protobuf from source, even if you know you only want one or the other (or neither). I.e., you can't depend on the I think it makes sense to expose environment variables as additional layers of control, though, on top of the features that are selected. That could allow you to enable both the I do wonder if the Prost maintainers and users would be happy enough with the default always being to compile protobuf from source. I agree that a C++ compiler is not terribly much to ask; indeed you've probably already got one if you've got a C compiler. Somewhat relatedly, I'm working on C++ bindings for libprotobuf that will make it possible to "invoke" protoc by just calling into the appropriate C++ APIs. That could prove useful here. |
I think you can set both cfg flags and env vars from build scripts.
By setting cfg flags in a build script, you can at least avoid compiling
I agree. If you are already in a mode of "compiling code" (AKA Could you update your PR to use |
I don’t think it works like that. The cfg flags and env vars you set in a build script only apply to the one crate that is being built.
I’m happy to do that, but I’d like @LucioFranco or another maintainer could weigh in on their desired approach before I take the time! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay on reviewing this! I'd like to get something like this in the next breaking release. I left a few questions nothing blocking, I think this approach looks pretty good.
Could you update your PR to use protobuf-src by default? That way, there does not need to be a PROST_BUILD_PROTOC_FROM_SRC variable/feature. The only feature would be the non-default "protbuf-bin" feature.
I’m happy to do that, but I’d like @LucioFranco or another maintainer could weigh in on their desired approach before I take the time!
Honestly, on a pure user experience end I would not want to default to compiling c++ code since this is usually quite a hit to the build experience. That said, in practice I am not sure if it would be that big of a deal.
I'd love to hear more from people more integrated in the build process to chime in.
cc @jonhoo
[![Documentation](https://docs.rs/prost-build/badge.svg)](https://docs.rs/prost-build/) | ||
[![Crate](https://img.shields.io/crates/v/prost-build.svg)](https://crates.io/crates/prost-build) | ||
|
||
# `prost-build` | ||
|
||
`prost-build` makes it easy to generate Rust code from `.proto` files as part of | ||
a Cargo build. See the crate [documentation](https://docs.rs/prost-build/) for examples | ||
of how to integrate `prost-build` into a Cargo project. | ||
|
||
## License | ||
|
||
`prost-build` is distributed under the terms of the Apache License (Version 2.0). | ||
|
||
See [LICENSE](../LICENSE) for details. | ||
|
||
Copyright 2017 Dan Burkert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this whole file needs to be updated for the protoc-bin
crate?
@@ -0,0 +1,59 @@ | |||
//! `protoc-bin` vendors `protoc` binaries for common architectures. | |||
//! | |||
//! It is intended for use as a build dependency for libraries like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//! It is intended for use as a build dependency for libraries like | |
//! It is intended for use as a build dependency for libraries like |
//! * Linux aarch64 | ||
//! * macOS x86_64 | ||
//! * macOS aarch64 | ||
//! * Windows 32-bit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No windows 64-bit?
I wrote an update here #575 (comment) I think for now we can close this PR and start with a new one. Thanks for taking the start on this @benesch. |
This is a proposed solution to #575. I expect there will be lots of opinions here, but I at least wanted to whip something up as a show of good faith! With something like this in place we'd be able to take the dependency on prost in MaterializeInc/materialize.
This commit makes it possible to opt out of downloading the bundled
pre-compiled protoc binaries. This is useful for downstream users with
strict supply chain security requirements (see #575 for details).
The approach taken is to move the pre-compiled binaries to a new crate
called
protoc-bin
. prost-build depends on this crate only if theprotoc-vendored-bin
feature is enabled (which it is by default).While it was always possible to avoid the vendored binaries by
specifying the
PROTOC
environment variable, the feature is a bit morefoolproof; security-concious users can audit their Cargo.lock to ensure
that the protc-bin crate is never even downloaded.
This commit also adds a new feature called
protoc-vendored-src
, whichuses the new
protobuf-src
crate to compile a copy of protoc fromsource on the fly. This feature makes
cargo build
seamless on allplatforms that Protobuf supports, not just those that protoc-bin
distributed pre-compiled binaries for, but has the downside of requiring
a C++ toolchain and increasing compile times.
If neither of the new vendored features are enabled,
prost-build
failsunless
PROTOC
andPROTOC_INCLUDE
are explicitly specified.