# dlprotoc: Download protoc for Cargo build scripts
[](https://crates.io/crates/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<dyn std::error::Error>> {
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.