Skip to content

Commit

Permalink
feat(prost-build): Add protoc executable path to Config (#1126)
Browse files Browse the repository at this point in the history
Set the path to `protoc` executable to be used by `prost-build`

Use the provided path to find `protoc`. This can either be a file name which is
searched for in the `PATH` or an aboslute path to use a specific executable.
  • Loading branch information
caspermeijn committed Aug 20, 2024
1 parent 753bd92 commit e773f5f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
11 changes: 0 additions & 11 deletions prost-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,6 @@
a Cargo build. See the crate [documentation](https://docs.rs/prost-build/) for examples
of how to integrate `prost-build` into a Cargo project.

## `protoc`

`prost-build` uses `protoc` to parse the proto files. There are two ways to make `protoc`
available for `prost-build`:

* Include `protoc` in your `PATH`. This can be done by following the [`protoc` install instructions].
* Pass the `PROTOC=<my/path/to/protoc>` environment variable with the path to
`protoc`.

[`protoc` install instructions]: https://github.com/protocolbuffers/protobuf#protocol-compiler-installation

## License

`prost-build` is distributed under the terms of the Apache License (Version 2.0).
Expand Down
32 changes: 28 additions & 4 deletions prost-build/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Config {
pub(crate) enable_type_names: bool,
pub(crate) type_name_domains: PathMap<String>,
pub(crate) protoc_args: Vec<OsString>,
pub(crate) protoc_executable: PathBuf,
pub(crate) disable_comments: PathMap<()>,
pub(crate) skip_debug: PathMap<()>,
pub(crate) skip_protoc_run: bool,
Expand Down Expand Up @@ -703,6 +704,30 @@ impl Config {
self
}

/// Set the path to `protoc` executable to be used by `prost-build`
///
/// Use the provided path to find `protoc`. This can either be a file name which is
/// searched for in the `PATH` or an aboslute path to use a specific executable.
///
/// # Example `build.rs`
///
/// ```rust,no_run
/// # use std::io::Result;
/// fn main() -> Result<()> {
/// let mut prost_build = prost_build::Config::new();
/// prost_build.protoc_executable("protoc-27.1");
/// prost_build.compile_protos(&["src/frontend.proto", "src/backend.proto"], &["src"])?;
/// Ok(())
/// }
/// ```
pub fn protoc_executable<S>(&mut self, executable: S) -> &mut Self
where
S: Into<PathBuf>,
{
self.protoc_executable = executable.into();
self
}

/// Configures the optional module filename for easy inclusion of all generated Rust files
///
/// If set, generates a file (inside the `OUT_DIR` or `out_dir()` as appropriate) which contains
Expand Down Expand Up @@ -878,9 +903,7 @@ impl Config {
};

if !self.skip_protoc_run {
let protoc = protoc_from_env();

let mut cmd = Command::new(protoc.clone());
let mut cmd = Command::new(&self.protoc_executable);
cmd.arg("--include_imports")
.arg("--include_source_info")
.arg("-o")
Expand Down Expand Up @@ -920,7 +943,7 @@ impl Config {
)),
Err(err) => return Err(Error::new(
err.kind(),
format!("failed to invoke protoc (hint: https://docs.rs/prost-build/#sourcing-protoc): (path: {:?}): {}", &protoc, err),
format!("failed to invoke protoc (hint: https://docs.rs/prost-build/#sourcing-protoc): (path: {:?}): {}", &self.protoc_executable, err),
)),
Ok(output) => output,
};
Expand Down Expand Up @@ -1145,6 +1168,7 @@ impl default::Default for Config {
enable_type_names: false,
type_name_domains: PathMap::default(),
protoc_args: Vec::new(),
protoc_executable: protoc_from_env(),
disable_comments: PathMap::default(),
skip_debug: PathMap::default(),
skip_protoc_run: false,
Expand Down
21 changes: 13 additions & 8 deletions prost-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,29 @@
//! ## Sourcing `protoc`
//!
//! `prost-build` depends on the Protocol Buffers compiler, `protoc`, to parse `.proto` files into
//! a representation that can be transformed into Rust. If set, `prost-build` uses the `PROTOC`
//! a representation that can be transformed into Rust.
//!
//! The easiest way for `prost-build` to find `protoc` is to install it in your `PATH`.
//! This can be done by following the [`protoc` install instructions]. `prost-build` will search
//! the current path for `protoc` or `protoc.exe`.
//!
//! When `protoc` is installed in a different location, set `PROTOC` to the path of the executable.
//! If set, `prost-build` uses the `PROTOC`
//! for locating `protoc`. For example, on a macOS system where Protobuf is installed
//! with Homebrew, set the environment variables to:
//!
//! ```bash
//! PROTOC=/usr/local/bin/protoc
//! ```
//!
//! and in a typical Linux installation:
//!
//! ```bash
//! PROTOC=/usr/bin/protoc
//! ```
//! Alternatively, the path to `protoc` execuatable can be explicitly set
//! via [`Config::protoc_executable()`].
//!
//! If no `PROTOC` environment variable is set then `prost-build` will search the
//! current path for `protoc` or `protoc.exe`. If `prost-build` can not find `protoc`
//! If `prost-build` can not find `protoc`
//! via these methods the `compile_protos` method will fail.
//!
//! [`protoc` install instructions]: https://github.com/protocolbuffers/protobuf#protocol-compiler-installation
//!
//! ### Compiling `protoc` from source
//!
//! To compile `protoc` from source you can use the `protobuf-src` crate and
Expand Down

0 comments on commit e773f5f

Please sign in to comment.