Generate formatted bindings + fix dead code warnings

This commit is contained in:
Martin Dahl 2023-06-26 12:05:21 +02:00
parent d720848bb6
commit f19b256139
3 changed files with 70 additions and 30 deletions

View File

@ -39,6 +39,9 @@ r2r_msg_gen = { path = "../r2r_msg_gen", version = "0.3.11" }
rayon = "1.7.0" rayon = "1.7.0"
force-send-sync = "1.0.0" force-send-sync = "1.0.0"
quote = "1.0.28" quote = "1.0.28"
proc-macro2 = "1.0.58"
syn = "2.0.18"
prettyplease = "0.2.6"
[features] [features]
save-bindgen = ["r2r_rcl/save-bindgen", "r2r_msg_gen/save-bindgen", "r2r_actions/save-bindgen"] save-bindgen = ["r2r_rcl/save-bindgen", "r2r_msg_gen/save-bindgen", "r2r_actions/save-bindgen"]

View File

@ -1,33 +1,48 @@
use quote::format_ident;
use quote::quote;
use rayon::prelude::*;
use std::fs::{File, OpenOptions};
use std::io::{self, prelude::*, BufWriter};
use std::path::{Path, PathBuf};
use std::{env, fmt, fs};
const LIST_FILENAME: &str = "files.txt"; #[cfg(not(feature = "doc-only"))]
const MSGS_FILENAME: &str = "_r2r_generated_msgs.rs"; use {
const UNTYPED_FILENAME: &str = "_r2r_generated_untyped_helper.rs"; quote::{format_ident, quote},
const UNTYPED_SERVICE_FILENAME: &str = "_r2r_generated_service_helper.rs"; rayon::prelude::*,
const UNTYPED_ACTION_FILENAME: &str = "_r2r_generated_action_helper.rs"; std::fs::{File, OpenOptions},
const GENERATED_FILES: &[&str] = &[ std::io::{self, prelude::*, BufWriter},
MSGS_FILENAME, std::fmt,
UNTYPED_FILENAME, };
UNTYPED_SERVICE_FILENAME,
UNTYPED_ACTION_FILENAME, use std::path::{Path, PathBuf};
]; use std::{env, fs};
#[cfg(feature = "doc-only")]
mod filenames {
pub const LIST_FILENAME: &str = "files.txt";
}
#[cfg(not(feature = "doc-only"))]
mod filenames {
pub const LIST_FILENAME: &str = "files.txt";
pub const MSGS_FILENAME: &str = "_r2r_generated_msgs.rs";
pub const UNTYPED_FILENAME: &str = "_r2r_generated_untyped_helper.rs";
pub const UNTYPED_SERVICE_FILENAME: &str = "_r2r_generated_service_helper.rs";
pub const UNTYPED_ACTION_FILENAME: &str = "_r2r_generated_action_helper.rs";
pub const GENERATED_FILES: &[&str] = &[
MSGS_FILENAME,
UNTYPED_FILENAME,
UNTYPED_SERVICE_FILENAME,
UNTYPED_ACTION_FILENAME,
];
}
use filenames::*;
fn main() { fn main() {
r2r_common::print_cargo_watches(); r2r_common::print_cargo_watches();
r2r_common::print_cargo_ros_distro(); r2r_common::print_cargo_ros_distro();
let env_hash = r2r_common::get_env_hash();
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
#[cfg(any(feature = "doc-only", feature = "save-bindgen"))]
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let bindgen_dir = out_dir.join(env_hash); #[cfg(any(feature = "doc-only", feature = "save-bindgen"))]
let save_dir = manifest_dir.join("bindings"); let save_dir = manifest_dir.join("bindings");
let mark_file = bindgen_dir.join("done");
#[cfg(feature = "doc-only")] #[cfg(feature = "doc-only")]
{ {
@ -37,6 +52,9 @@ fn main() {
#[cfg(not(feature = "doc-only"))] #[cfg(not(feature = "doc-only"))]
{ {
let env_hash = r2r_common::get_env_hash();
let bindgen_dir = out_dir.join(env_hash);
let mark_file = bindgen_dir.join("done");
// If bindgen was done before, use cached files. // If bindgen was done before, use cached files.
if !mark_file.exists() { if !mark_file.exists() {
eprintln!("Generate bindings in '{}'", bindgen_dir.display()); eprintln!("Generate bindings in '{}'", bindgen_dir.display());
@ -85,7 +103,7 @@ fn generate_bindings(bindgen_dir: &Path) {
}; };
let msgs_file = bindgen_dir.join(MSGS_FILENAME); let msgs_file = bindgen_dir.join(MSGS_FILENAME);
write_to_file(&msgs_file, &modules).unwrap(); write_to_file(&msgs_file, &pretty_tokenstream(modules)).unwrap();
} }
let mod_files: Vec<_> = msgs let mod_files: Vec<_> = msgs
@ -224,7 +242,7 @@ fn generate_bindings(bindgen_dir: &Path) {
let mod_content = quote! { #(#snipplets)* }; let mod_content = quote! { #(#snipplets)* };
let file_name = format!("{}.rs", module); let file_name = format!("{}.rs", module);
let mod_file = bindgen_dir.join(&file_name); let mod_file = bindgen_dir.join(&file_name);
write_to_file(&mod_file, &mod_content).unwrap(); write_to_file(&mod_file, &pretty_tokenstream(mod_content)).unwrap();
file_name file_name
}) })
@ -234,19 +252,19 @@ fn generate_bindings(bindgen_dir: &Path) {
{ {
let untyped_helper = r2r_msg_gen::generate_untyped_helper(&msg_list); let untyped_helper = r2r_msg_gen::generate_untyped_helper(&msg_list);
let untyped_file = bindgen_dir.join(UNTYPED_FILENAME); let untyped_file = bindgen_dir.join(UNTYPED_FILENAME);
write_to_file(&untyped_file, &untyped_helper).unwrap(); write_to_file(&untyped_file, &pretty_tokenstream(untyped_helper)).unwrap();
} }
{ {
let untyped_service_helper = r2r_msg_gen::generate_untyped_service_helper(&msg_list); let untyped_service_helper = r2r_msg_gen::generate_untyped_service_helper(&msg_list);
let untyped_service_file = bindgen_dir.join(UNTYPED_SERVICE_FILENAME); let untyped_service_file = bindgen_dir.join(UNTYPED_SERVICE_FILENAME);
write_to_file(&untyped_service_file, &untyped_service_helper).unwrap(); write_to_file(&untyped_service_file, &pretty_tokenstream(untyped_service_helper)).unwrap();
} }
{ {
let untyped_action_helper = r2r_msg_gen::generate_untyped_action_helper(&msg_list); let untyped_action_helper = r2r_msg_gen::generate_untyped_action_helper(&msg_list);
let untyped_action_file = bindgen_dir.join(UNTYPED_ACTION_FILENAME); let untyped_action_file = bindgen_dir.join(UNTYPED_ACTION_FILENAME);
write_to_file(&untyped_action_file, &untyped_action_helper).unwrap(); write_to_file(&untyped_action_file, &pretty_tokenstream(untyped_action_helper)).unwrap();
} }
// Save file list // Save file list
@ -285,6 +303,7 @@ fn copy_files(src_dir: &Path, tgt_dir: &Path) {
fs::copy(&src_list_file, &tgt_list_file).unwrap(); fs::copy(&src_list_file, &tgt_list_file).unwrap();
} }
#[cfg(not(feature = "doc-only"))]
fn touch(path: &Path) { fn touch(path: &Path) {
OpenOptions::new() OpenOptions::new()
.create(true) .create(true)
@ -293,6 +312,7 @@ fn touch(path: &Path) {
.unwrap_or_else(|_| panic!("Unable to create file '{}'", path.display())); .unwrap_or_else(|_| panic!("Unable to create file '{}'", path.display()));
} }
#[cfg(not(feature = "doc-only"))]
fn write_to_file(path: &Path, content: impl fmt::Display) -> io::Result<()> { fn write_to_file(path: &Path, content: impl fmt::Display) -> io::Result<()> {
let mut writer = BufWriter::new(File::create(path)?); let mut writer = BufWriter::new(File::create(path)?);
write!(writer, "{}", content)?; write!(writer, "{}", content)?;
@ -300,6 +320,12 @@ fn write_to_file(path: &Path, content: impl fmt::Display) -> io::Result<()> {
Ok(()) Ok(())
} }
#[cfg(not(feature = "doc-only"))]
unsafe fn force_send<T>(value: T) -> force_send_sync::Send<T> { unsafe fn force_send<T>(value: T) -> force_send_sync::Send<T> {
force_send_sync::Send::new(value) force_send_sync::Send::new(value)
} }
#[cfg(not(feature = "doc-only"))]
fn pretty_tokenstream(stream: proc_macro2::TokenStream) -> String {
prettyplease::unparse(&syn::parse2::<syn::File>(stream).unwrap())
}

View File

@ -16,16 +16,21 @@ include!(concat!(env!("OUT_DIR"), "/constants.rs"));
mod introspection; mod introspection;
use crate::introspection::MemberType; #[cfg(not(feature = "doc-only"))]
use crate::introspection::MessageMember; use {
crate::introspection::{MemberType, MessageMember},
rayon::prelude::*,
std::mem,
};
use quote::format_ident; use quote::format_ident;
use quote::quote; use quote::quote;
use r2r_common::RosMsg; use r2r_common::RosMsg;
use r2r_rcl::*; use r2r_rcl::*;
use rayon::prelude::*;
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::CStr; use std::ffi::CStr;
use std::mem;
use std::slice; use std::slice;
// Copied from bindgen. // Copied from bindgen.
@ -665,15 +670,21 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> proc_macr
} }
fn create_msg() -> *mut #c_struct { fn create_msg() -> *mut #c_struct {
#[cfg(not(feature = "doc-only"))]
unsafe { unsafe {
#create_func () #create_func ()
} }
#[cfg(feature = "doc-only")]
#create_func ()
} }
fn destroy_msg(msg: *mut #c_struct) -> () { fn destroy_msg(msg: *mut #c_struct) -> () {
#[cfg(not(feature = "doc-only"))]
unsafe { unsafe {
#destroy_func (msg) #destroy_func (msg)
}; };
#[cfg(feature = "doc-only")]
#destroy_func (msg)
} }
#from_native #from_native