Handle path changes to support Humble release
This commit is contained in:
parent
aa812a2e8f
commit
7678acfb12
25
build.rs
25
build.rs
|
|
@ -1,32 +1,13 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
r2r_common::print_cargo_watches();
|
||||
|
||||
let msg_list = if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||
let packages = cmake_includes
|
||||
.split(':')
|
||||
.flat_map(|i| Path::new(i).parent())
|
||||
.collect::<Vec<_>>();
|
||||
let deps = env::var("CMAKE_IDL_PACKAGES").unwrap_or_default();
|
||||
let deps = deps.split(':').collect::<Vec<_>>();
|
||||
let msgs = r2r_common::get_ros_msgs(&packages);
|
||||
r2r_common::parse_msgs(&msgs)
|
||||
.into_iter()
|
||||
.filter(|msg| deps.contains(&msg.module.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
let ament_prefix_var = env::var("AMENT_PREFIX_PATH").expect("Source your ROS!");
|
||||
let paths = ament_prefix_var
|
||||
.split(':')
|
||||
.map(Path::new)
|
||||
.collect::<Vec<_>>();
|
||||
let msgs = r2r_common::get_ros_msgs(&paths);
|
||||
r2r_common::parse_msgs(&msgs)
|
||||
};
|
||||
let msg_list = r2r_common::get_wanted_messages();
|
||||
|
||||
let msgs = r2r_common::as_map(&msg_list);
|
||||
|
||||
let mut modules = String::new();
|
||||
|
|
|
|||
|
|
@ -16,5 +16,4 @@ r2r_msg_gen = { path = "../r2r_msg_gen", version = "0.3.2" }
|
|||
|
||||
[build-dependencies]
|
||||
bindgen = "0.59.2"
|
||||
itertools = "0.10.3"
|
||||
r2r_common = { path = "../r2r_common", version = "0.3.1" }
|
||||
|
|
|
|||
|
|
@ -1,58 +1,11 @@
|
|||
use itertools::Itertools;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.header("src/action_wrapper.h")
|
||||
.derive_copy(false)
|
||||
.size_t_is_usize(true)
|
||||
.default_enum_style(bindgen::EnumVariation::Rust {
|
||||
non_exhaustive: false,
|
||||
});
|
||||
r2r_common::print_cargo_watches();
|
||||
|
||||
if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||
// we are running from cmake, do special thing.
|
||||
let mut includes = cmake_includes.split(':').collect::<Vec<_>>();
|
||||
includes.sort_unstable();
|
||||
includes.dedup();
|
||||
|
||||
for x in &includes {
|
||||
let clang_arg = format!("-I{}", x);
|
||||
println!("adding clang arg: {}", clang_arg);
|
||||
builder = builder.clang_arg(clang_arg);
|
||||
}
|
||||
|
||||
env::var("CMAKE_LIBRARIES")
|
||||
.unwrap_or_default()
|
||||
.split(':')
|
||||
.into_iter()
|
||||
.filter(|s| s.contains(".so") || s.contains(".dylib"))
|
||||
.flat_map(|l| Path::new(l).parent().and_then(|p| p.to_str()))
|
||||
.unique()
|
||||
.for_each(|pp| {
|
||||
println!("cargo:rustc-link-search=native={}", pp)
|
||||
// we could potentially do the below instead of hardcoding which libs we rely on.
|
||||
// let filename = path.file_stem().and_then(|f| f.to_str()).unwrap();
|
||||
// let without_lib = filename.strip_prefix("lib").unwrap();
|
||||
// println!("cargo:rustc-link-lib=dylib={}", without_lib);
|
||||
});
|
||||
} else {
|
||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||
let ament_prefix_var = env::var(ament_prefix_var_name).expect("Source your ROS!");
|
||||
|
||||
for ament_prefix_path in ament_prefix_var.split(':') {
|
||||
if let Some(include_path) = r2r_common::guess_cmake_include_path(Path::new(ament_prefix_path)) {
|
||||
if let Some(s) = include_path.to_str() {
|
||||
builder = builder.clang_arg(format!("-I{}", s));
|
||||
};
|
||||
}
|
||||
let lib_path = Path::new(ament_prefix_path).join("lib");
|
||||
lib_path.to_str().map(|s| {
|
||||
println!("cargo:rustc-link-search=native={}", s);
|
||||
});
|
||||
}
|
||||
}
|
||||
let mut builder = r2r_common::setup_bindgen_builder();
|
||||
builder = builder.header("src/action_wrapper.h");
|
||||
|
||||
println!("cargo:rustc-link-lib=dylib=rcl_action");
|
||||
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ readme = "README.md"
|
|||
homepage = "https://github.com/sequenceplanner/r2r"
|
||||
repository = "https://github.com/sequenceplanner/r2r"
|
||||
documentation = "https://sequenceplanner.github.io/r2r/"
|
||||
|
||||
[dependencies]
|
||||
bindgen = "0.59.2"
|
||||
itertools = "0.10.3"
|
||||
|
|
|
|||
|
|
@ -1,35 +1,9 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// Hack to build rolling after https://github.com/ros2/rcl/pull/959 was merged.
|
||||
//
|
||||
// The problem is that now we need to use CMAKE to properly find the
|
||||
// include paths. But we don't want to do that so we hope that the ros
|
||||
// developers use the same convention everytime they move the include
|
||||
// files to a subdirectory.
|
||||
//
|
||||
// The convention is to put include files in include/${PROJECT_NAME}
|
||||
//
|
||||
// So we check if there is a double directory on the form
|
||||
// include/${PROJECT_NAME}/${PROJECT_NAME}, and if so append it only once.
|
||||
//
|
||||
// Should work mostly, and shouldn't really change often, so manual
|
||||
// intervention could be applied. But yes it is hacky.
|
||||
pub fn guess_cmake_include_path(path: &Path) -> Option<PathBuf> {
|
||||
if let Some(leaf) = path.file_name() {
|
||||
let double_include_path = Path::new(path).join("include").join(leaf).join(leaf);
|
||||
if double_include_path.is_dir() {
|
||||
// double dir detected, append the package name
|
||||
return Some(path.to_owned().join("include").join(leaf));
|
||||
} else {
|
||||
// dont append
|
||||
return Some(path.to_owned().join("include"));
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
use std::path::Path;
|
||||
use std::env;
|
||||
use itertools::Itertools;
|
||||
|
||||
pub fn print_cargo_watches() {
|
||||
println!("cargo:rerun-if-env-changed=AMENT_PREFIX_PATH");
|
||||
|
|
@ -38,6 +12,115 @@ pub fn print_cargo_watches() {
|
|||
println!("cargo:rerun-if-env-changed=CMAKE_RECURSIVE_DEPENDENCIES");
|
||||
}
|
||||
|
||||
pub fn setup_bindgen_builder() -> bindgen::Builder {
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.derive_copy(false)
|
||||
.size_t_is_usize(true)
|
||||
.default_enum_style(bindgen::EnumVariation::Rust {
|
||||
non_exhaustive: false,
|
||||
});
|
||||
|
||||
if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||
// we are running from cmake, do special thing.
|
||||
let mut includes = cmake_includes.split(':').collect::<Vec<_>>();
|
||||
includes.sort_unstable();
|
||||
includes.dedup();
|
||||
|
||||
for x in &includes {
|
||||
let clang_arg = format!("-I{}", x);
|
||||
println!("adding clang arg: {}", clang_arg);
|
||||
builder = builder.clang_arg(clang_arg);
|
||||
}
|
||||
|
||||
env::var("CMAKE_LIBRARIES")
|
||||
.unwrap_or_default()
|
||||
.split(':')
|
||||
.into_iter()
|
||||
.filter(|s| s.contains(".so") || s.contains(".dylib"))
|
||||
.flat_map(|l| Path::new(l).parent().and_then(|p| p.to_str()))
|
||||
.unique()
|
||||
.for_each(|pp| println!("cargo:rustc-link-search=native={}", pp));
|
||||
} else {
|
||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||
let ament_prefix_var = env::var(ament_prefix_var_name).expect("Source your ROS!");
|
||||
|
||||
for p in ament_prefix_var.split(':') {
|
||||
let path = Path::new(p).join("include");
|
||||
|
||||
let entries = std::fs::read_dir(path.clone());
|
||||
if let Ok(e) = entries {
|
||||
let dirs = e.filter_map(|a| {
|
||||
let path = a.unwrap().path();
|
||||
if path.is_dir() {
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
builder = dirs.iter().fold(builder, |builder, d| {
|
||||
// Hack to build rolling after https://github.com/ros2/rcl/pull/959 was merged.
|
||||
//
|
||||
// The problem is that now we need to use CMAKE to properly find the
|
||||
// include paths. But we don't want to do that so we hope that the ros
|
||||
// developers use the same convention everytime they move the include
|
||||
// files to a subdirectory.
|
||||
//
|
||||
// The convention is to put include files in include/${PROJECT_NAME}
|
||||
//
|
||||
// So we check if there is a double directory on the form
|
||||
// include/${PROJECT_NAME}/${PROJECT_NAME}, and if so append it only once.
|
||||
//
|
||||
// Should work mostly, and shouldn't really change often, so manual
|
||||
// intervention could be applied. But yes it is hacky.
|
||||
if let Some(leaf) = d.file_name() {
|
||||
let double_include_path = Path::new(d).join(leaf);
|
||||
if double_include_path.is_dir() {
|
||||
let temp = d.to_str().unwrap();
|
||||
builder.clang_arg(format!("-I{}", temp))
|
||||
} else {
|
||||
// pre humble case, where we did not have include/package/package
|
||||
let temp = d.parent().unwrap().to_str().unwrap();
|
||||
builder.clang_arg(format!("-I{}", temp))
|
||||
}
|
||||
} else { builder }
|
||||
});
|
||||
}
|
||||
|
||||
let lib_path = Path::new(p).join("lib");
|
||||
lib_path.to_str().map(|s| {
|
||||
println!("cargo:rustc-link-search=native={}", s);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
pub fn get_wanted_messages() -> Vec<RosMsg> {
|
||||
let msgs = if let Ok(cmake_package_dirs) = env::var("CMAKE_IDL_PACKAGES") {
|
||||
// CMAKE_PACKAGE_DIRS should be a (cmake) list of "cmake" dirs
|
||||
// e.g. For each dir install/r2r_minimal_node_msgs/share/r2r_minimal_node_msgs/cmake
|
||||
// we can traverse back and then look for .msg files in msg/ srv/ action/
|
||||
let dirs = cmake_package_dirs.split(':')
|
||||
.flat_map(|i| Path::new(i).parent())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
get_ros_msgs_files(&dirs)
|
||||
} else {
|
||||
// Else we look for all msgs we can find using the ament prefix path.
|
||||
let ament_prefix_var = env::var("AMENT_PREFIX_PATH").expect("Source your ROS!");
|
||||
let paths = ament_prefix_var
|
||||
.split(':')
|
||||
.map(Path::new)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
get_ros_msgs(&paths)
|
||||
};
|
||||
|
||||
parse_msgs(&msgs)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RosMsg {
|
||||
pub module: String, // e.g. std_msgs
|
||||
|
|
@ -57,13 +140,10 @@ fn get_msgs_from_package(package: &Path) -> Vec<String> {
|
|||
|
||||
if let Ok(paths) = fs::read_dir(path) {
|
||||
for path in paths {
|
||||
// println!("PATH Name: {}", path.unwrap().path().display());
|
||||
|
||||
let path = path.unwrap().path();
|
||||
let path2 = path.clone();
|
||||
let file_name = path2.file_name().unwrap();
|
||||
|
||||
// println!("Messages for: {:?}", file_name);
|
||||
if let Ok(mut file) = File::open(path) {
|
||||
let mut s = String::new();
|
||||
file.read_to_string(&mut s).unwrap();
|
||||
|
|
@ -109,9 +189,7 @@ pub fn get_ros_msgs(paths: &[&Path]) -> Vec<String> {
|
|||
let mut msgs: Vec<String> = Vec::new();
|
||||
|
||||
for p in paths {
|
||||
println!("looking at prefix: {:?}", p);
|
||||
let package_msgs = get_msgs_from_package(p);
|
||||
println!("... found {:?}", package_msgs);
|
||||
msgs.extend(package_msgs)
|
||||
}
|
||||
msgs.sort();
|
||||
|
|
@ -119,6 +197,47 @@ pub fn get_ros_msgs(paths: &[&Path]) -> Vec<String> {
|
|||
msgs
|
||||
}
|
||||
|
||||
|
||||
fn get_msgs_in_dir(base: &Path, subdir: &str, package: &str) -> Vec<String> {
|
||||
let path = base.to_owned();
|
||||
let path = path.join(subdir);
|
||||
|
||||
let mut msgs = vec![];
|
||||
|
||||
if let Ok(paths) = fs::read_dir(path) {
|
||||
for path in paths {
|
||||
let path = path.unwrap().path();
|
||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||
|
||||
// message name.idl or name.msg
|
||||
if !filename.ends_with(".idl") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let substr = &filename[0..filename.len() - 4];
|
||||
|
||||
msgs.push(format!("{}/{}/{}",package, subdir, substr));
|
||||
}
|
||||
}
|
||||
msgs
|
||||
}
|
||||
|
||||
pub fn get_ros_msgs_files(paths: &[&Path]) -> Vec<String> {
|
||||
let mut msgs: Vec<String> = Vec::new();
|
||||
|
||||
for p in paths {
|
||||
if let Some(package_name) = p.file_name() {
|
||||
let package_name = package_name.to_str().unwrap();
|
||||
msgs.extend(get_msgs_in_dir(p, "msg", package_name));
|
||||
msgs.extend(get_msgs_in_dir(p, "srv", package_name));
|
||||
msgs.extend(get_msgs_in_dir(p, "action", package_name));
|
||||
}
|
||||
}
|
||||
msgs.sort();
|
||||
msgs.dedup();
|
||||
msgs
|
||||
}
|
||||
|
||||
pub fn parse_msgs(msgs: &[String]) -> Vec<RosMsg> {
|
||||
let v: Vec<Vec<&str>> = msgs
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -3,45 +3,14 @@ use heck::ToSnakeCase;
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
r2r_common::print_cargo_watches();
|
||||
|
||||
let mut builder = bindgen::Builder::default();
|
||||
|
||||
let msg_list = if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||
let packages = cmake_includes
|
||||
.split(':')
|
||||
.flat_map(|i| Path::new(i).parent())
|
||||
.collect::<Vec<_>>();
|
||||
for p in cmake_includes.split(':') {
|
||||
builder = builder.clang_arg(format!("-I{}", p));
|
||||
}
|
||||
let deps = env::var("CMAKE_IDL_PACKAGES").unwrap_or_default();
|
||||
let deps = deps.split(':').collect::<Vec<_>>();
|
||||
let msgs = r2r_common::get_ros_msgs(&packages);
|
||||
r2r_common::parse_msgs(&msgs)
|
||||
.into_iter()
|
||||
.filter(|msg| deps.contains(&msg.module.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
let ament_prefix_var = env::var("AMENT_PREFIX_PATH").expect("Source your ROS!");
|
||||
for p in ament_prefix_var.split(':') {
|
||||
let path = Path::new(p).join("include");
|
||||
if let Some(s) = path.to_str() {
|
||||
builder = builder.clang_arg(format!("-I{}", s));
|
||||
}
|
||||
}
|
||||
let paths = ament_prefix_var
|
||||
.split(':')
|
||||
.map(Path::new)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let msgs = r2r_common::get_ros_msgs(&paths);
|
||||
r2r_common::parse_msgs(&msgs)
|
||||
};
|
||||
let mut builder = r2r_common::setup_bindgen_builder();
|
||||
|
||||
let msg_list = r2r_common::get_wanted_messages();
|
||||
let msg_map = r2r_common::as_map(&msg_list);
|
||||
|
||||
for module in msg_map.keys() {
|
||||
|
|
|
|||
|
|
@ -16,5 +16,4 @@ widestring = "0.5.1"
|
|||
|
||||
[build-dependencies]
|
||||
bindgen = "0.59.2"
|
||||
itertools = "0.10.3"
|
||||
r2r_common = { path = "../r2r_common", version = "0.3.1" }
|
||||
|
|
|
|||
|
|
@ -1,63 +1,11 @@
|
|||
extern crate bindgen;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
r2r_common::print_cargo_watches();
|
||||
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.header("src/rcl_wrapper.h")
|
||||
.derive_copy(false)
|
||||
.size_t_is_usize(true)
|
||||
.default_enum_style(bindgen::EnumVariation::Rust {
|
||||
non_exhaustive: false,
|
||||
});
|
||||
|
||||
if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||
// we are running from cmake, do special thing.
|
||||
let mut includes = cmake_includes.split(':').collect::<Vec<_>>();
|
||||
includes.sort_unstable();
|
||||
includes.dedup();
|
||||
|
||||
for x in &includes {
|
||||
let clang_arg = format!("-I{}", x);
|
||||
println!("adding clang arg: {}", clang_arg);
|
||||
builder = builder.clang_arg(clang_arg);
|
||||
}
|
||||
|
||||
env::var("CMAKE_LIBRARIES")
|
||||
.unwrap_or_default()
|
||||
.split(':')
|
||||
.into_iter()
|
||||
.filter(|s| s.contains(".so") || s.contains(".dylib"))
|
||||
.flat_map(|l| Path::new(l).parent().and_then(|p| p.to_str()))
|
||||
.unique()
|
||||
.for_each(|pp| {
|
||||
println!("cargo:rustc-link-search=native={}", pp)
|
||||
// we could potentially do the below instead of hardcoding which libs we rely on.
|
||||
// let filename = path.file_stem().and_then(|f| f.to_str()).unwrap();
|
||||
// let without_lib = filename.strip_prefix("lib").unwrap();
|
||||
// println!("cargo:rustc-link-lib=dylib={}", without_lib);
|
||||
});
|
||||
} else {
|
||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||
let ament_prefix_var = env::var(ament_prefix_var_name).expect("Source your ROS!");
|
||||
|
||||
for ament_prefix_path in ament_prefix_var.split(':') {
|
||||
if let Some(include_path) = r2r_common::guess_cmake_include_path(Path::new(ament_prefix_path)) {
|
||||
if let Some(s) = include_path.to_str() {
|
||||
builder = builder.clang_arg(format!("-I{}", s));
|
||||
};
|
||||
}
|
||||
let lib_path = Path::new(ament_prefix_path).join("lib");
|
||||
lib_path.to_str().map(|s| {
|
||||
println!("cargo:rustc-link-search=native={}", s);
|
||||
});
|
||||
}
|
||||
}
|
||||
let mut builder = r2r_common::setup_bindgen_builder();
|
||||
builder = builder.header("src/rcl_wrapper.h");
|
||||
|
||||
println!("cargo:rustc-link-lib=dylib=rcl");
|
||||
println!("cargo:rustc-link-lib=dylib=rcl_logging_spdlog");
|
||||
|
|
|
|||
Loading…
Reference in New Issue