-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #135 from Carter12s/build-rs-example
Add an example for build.rs usage
- Loading branch information
Showing
8 changed files
with
127 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
[workspace] | ||
|
||
members = [ | ||
"example_package", | ||
"roslibrust", | ||
"roslibrust_codegen", | ||
"roslibrust_codegen_macro", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "example_package" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
# This is what we need for using this package in our mono-repo | ||
roslibrust = { path = "../roslibrust" } | ||
# Normally you would have: roslibrust = "0.7" | ||
# TODO in the current state of this example, we don't actually need roslibrust | ||
# These dependencies are needed by the code that roslibrust_codegen autogenerates | ||
# They are silently "leaked dependencies of the crate" | ||
# See https://github.com/Carter12s/roslibrust/issues/72 for resolution path | ||
serde = "1.0" | ||
smart-default = "0.7" | ||
roslibrust_codegen = { path = "../roslibrust_codegen" } | ||
|
||
[build-dependencies] | ||
# We depend on codegen as a build dependency as we (should) only need it to generate our types | ||
roslibrust_codegen = { path = "../roslibrust_codegen" } | ||
# This crate is very helpful for build.rs files but not required | ||
cargo-emit = "0.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Example RosLibRust Package | ||
The point of this package is provide a good example of how to integrate roslibrust into a package using a build.rs file. | ||
|
||
This package also serves as a testbed for maintainers of roslibrust to refine build.rs integration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// This is an example / template build script that other projects looking to incorporate roslibrust into their codebase | ||
// are recommended to adopt. Using build.rs is currently the preferred / recommended approach as there is not currently | ||
// a mechanism for proc_macros to indicate they need to be re-run when an external file changes. With build.rs it is | ||
// possible to robustly trigger re-builds when dependent message files are changed. | ||
// It is highly recommended to read the Cargo Book section on build scripts before attempting this approach as some | ||
// care is needed: https://doc.rust-lang.org/cargo/reference/build-scripts.html | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Define our search paths, for this example we're using out test_msgs and std_msgs for ros1 | ||
// These can be pulled either from ROS_PACKAGE_PATH or given manually. | ||
// While ROS_PACKAGE_PATH can be very convenient, it can also be VERY confusing | ||
// We recommend using explicit paths only for more reliable and reproducible builds. | ||
let p = vec![ | ||
"../assets/ros1_common_interfaces/std_msgs".into(), | ||
"../assets/ros1_test_msgs".into(), | ||
]; | ||
|
||
// Actually invoke code generation on our search paths. | ||
// What we get back is a TokenStream the type normally returned by a proc_macro in rust. | ||
// For a build.rs we typically want to serialize this data to a file for later import | ||
// MAJOR TODO need to incorporate error handling here when that PR is merged | ||
let tokens = roslibrust_codegen::find_and_generate_ros_messages_without_ros_package_path(p); | ||
|
||
// It is important for build scripts to only output files to OUT_DIR. | ||
// This guidance can be ignored for end applications. However, crates published and downloaded with cargo | ||
// will not work if they rely on output files to other folders. | ||
let out_dir = std::env::var_os("OUT_DIR").unwrap(); | ||
let dest_path = std::path::Path::new(&out_dir).join("messages.rs"); | ||
// Write the generate code to disk | ||
// Note: it will not be nicely formatted at this point which can affect readability when debugging | ||
std::fs::write(dest_path, tokens.to_string())?; | ||
// Optionally rustfmt could be invoked to format the file at this point | ||
// Or https://github.com/dtolnay/prettyplease used on the TokenStream ahead of writing to disk | ||
|
||
// If we stopped at this point, our code would still work, but Cargo would not know to rebuild | ||
// our package when a message file changed. | ||
// MAJOR TODO need to get codegen methods to return list of dependent files | ||
// Also probably want to merge down function names to single function with more args / builder | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//! This file shows how to correctly import files generated by build.rs: | ||
// This macro trick correctly "imports" messages.rs into our crate | ||
// This should only be invoked once in the crate and other locations can access the | ||
// messages via `use` | ||
include!(concat!(env!("OUT_DIR"), "/messages.rs")); | ||
|
||
// Example of 'use' pointing to code created by the include! macro | ||
mod submodule { | ||
#[allow(unused_imports)] | ||
use crate::std_msgs::Header; | ||
} | ||
|
||
// Our actual "main" here doesn't do much, just shows the generate types | ||
// are here and real. | ||
fn main() { | ||
// Note: within our assets there is a folder named ros1_test_msgs which contains a ros package | ||
// The ros package in its package.xml refers to the name of that package as test_msgs | ||
// The module that is generated will use the name in package.xml and not the directory | ||
let data = test_msgs::Constants::TEST_STR; | ||
println!("Hello World! {data}"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters