# dlprotoc: Download protoc for Cargo build scripts [![Crates.io Version](https://img.shields.io/crates/v/dlprotoc)](https://crates.io/crates/dlprotoc) [![Docs.rs Link](https://img.shields.io/docsrs/dlprotoc)](https://docs.rs/dlprotoc/latest/dlprotoc/) This crate downloads the [official binary releases of `protoc` from Google's protobuf Github repo](https://github.com/protocolbuffers/protobuf), verifies a SHA256 hash, then extracts it. It is intended to be used in Cargo build scripts (`build.rs`) with Prost or Tonic, so you don't need to have `protoc` installed to build Rust projects that use Protocol Buffers. This fixes Cargo errors like the following: ``` error: failed to run custom build command for `example v0.1.0 (/home/user/example)` Caused by: process didn't exit successfully: `target/debug/build/example-3f5090329e3c4e4b/build-script-build` (exit status: 1) --- stderr Error: Custom { kind: NotFound, error: "Could not find `protoc`. If `protoc` is installed, try setting the `PROTOC` environment variable to the path of the `protoc` binary. To install it on Debian, run `apt-get install protobuf-compiler`. It is also available at https://github.com/protocolbuffers/protobuf/releases For more information: https://docs.rs/prost-build/#sourcing-protoc" } ``` An alternative is the [protobuf-src crate](https://crates.io/crates/protobuf-src), which compiles protoc from source. Unfortunately, compiling protoc is quite slow (approximately 2 minutes on my 4 core Intel desktop from 2020), and requires `cmake` and a C++ compiler. This crate only requires Rust. ## Quick Start Add `dlprotoc` to In `build.rs`, call `dlprotoc::download_protoc()` before calling `compile_protos(...)`: ```rust fn main() -> Result<(), Box> { dlprotoc::download_protoc()?; prost_build::compile_protos(&["src/example.proto"], &["src/"])?; Ok(()) } ``` For a complete example, see [protoc-cargo-example-rs](https://github.com/evanj/protoc-cargo-example-rs). ## Trust/Security This downloads pre-compiled executables on Github, which is somewhat dangerous. You need to trust: * The SHA256 hashes embedded in the source code are for protoc binaries that are non-malicious. The hashes are from Google's Github releases. * The crate does not have bugs, and will not run protoc binaries that have not been seen before. * Crates.io: Must give you a non-malicious version of this crate. * Google Protobuf maintainers: Uploads non-malicious protoc binaries to Github. ## Updating to new protoc releases (for maintainers) 1. Run: `cargo run -- (version e.g 27.0)` 2. Append the printed struct definitions into the `KNOWN_VERSIONS` array in `versions.rs`. 3. Run `make` to execute all checks. 4. Update the version in `Cargo.toml` to include the version of protoc. E.g. `"0.1.0+27.0"`. 5. Send a pull request. ## Releasing the crate (for maintainers) 1. Test it: `make && cargo publish --dry-run` 2. Publish to crates.io: `cargo publish` 3. Tag the release: `(VERSION=$(cargo pkgid | sed 's/.*@//'); git tag -a "v$VERSION" -m "release version $VERSION")` 4. Push the tag: `git push --tags` 5. Create a release from the existing tag on Github: Go to [Tags](https://github.com/evanj/dlprotoc-rs/tags), click the "..." menu, choose Create Release.