add windows support + use cmake_path to have colcon-cargo working
correctly
This commit is contained in:
parent
29404f1982
commit
64bc6af718
|
|
@ -1,5 +1,6 @@
|
||||||
use r2r_rcl::*;
|
use r2r_rcl::*;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Mutex, MutexGuard};
|
use std::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
@ -12,12 +13,24 @@ pub(crate) fn log_guard() -> MutexGuard<'static, ()> {
|
||||||
LOG_GUARD.lock().unwrap()
|
LOG_GUARD.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for some hidden reason g_rcutils_logging_initialized
|
||||||
|
// is not found on windows even when rcutils.lib is linked
|
||||||
|
// as a work around using onwned is_init
|
||||||
|
static IS_INIT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
/// Don't call this directly, use the logging macros instead.
|
/// Don't call this directly, use the logging macros instead.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn log(msg: &str, logger_name: &str, file: &str, line: u32, severity: LogSeverity) {
|
pub fn log(msg: &str, logger_name: &str, file: &str, line: u32, severity: LogSeverity) {
|
||||||
let _guard = log_guard();
|
let _guard = log_guard();
|
||||||
let is_init = unsafe { g_rcutils_logging_initialized };
|
let is_init = if cfg!(target_os = "windows") {
|
||||||
|
IS_INIT.load(Ordering::Relaxed)
|
||||||
|
} else {
|
||||||
|
unsafe { g_rcutils_logging_initialized }
|
||||||
|
};
|
||||||
if !is_init {
|
if !is_init {
|
||||||
|
if cfg!(target_os = "windows") {
|
||||||
|
IS_INIT.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
let ret = unsafe { rcutils_logging_initialize() };
|
let ret = unsafe { rcutils_logging_initialize() };
|
||||||
if ret != RCL_RET_OK as i32 {
|
if ret != RCL_RET_OK as i32 {
|
||||||
log::error!("could not create logging system (Err: {})", ret);
|
log::error!("could not create logging system (Err: {})", ret);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
|
use regex::*;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use regex::*;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "doc-only"))]
|
#[cfg(not(feature = "doc-only"))]
|
||||||
const SUPPORTED_ROS_DISTROS: &[&str] = &["foxy", "galactic", "humble", "rolling"];
|
const SUPPORTED_ROS_DISTROS: &[&str] = &["foxy", "galactic", "humble", "rolling"];
|
||||||
|
|
||||||
const WATCHED_ENV_VARS: &[&str] = &[
|
const WATCHED_ENV_VARS: &[&str] = &[
|
||||||
"AMENT_PREFIX_PATH",
|
"AMENT_PREFIX_PATH",
|
||||||
|
"CMAKE_PREFIX_PATH",
|
||||||
"CMAKE_INCLUDE_DIRS",
|
"CMAKE_INCLUDE_DIRS",
|
||||||
"CMAKE_LIBRARIES",
|
"CMAKE_LIBRARIES",
|
||||||
"CMAKE_IDL_PACKAGES",
|
"CMAKE_IDL_PACKAGES",
|
||||||
|
|
@ -49,10 +50,14 @@ pub fn setup_bindgen_builder() -> bindgen::Builder {
|
||||||
.default_enum_style(bindgen::EnumVariation::Rust {
|
.default_enum_style(bindgen::EnumVariation::Rust {
|
||||||
non_exhaustive: false,
|
non_exhaustive: false,
|
||||||
});
|
});
|
||||||
|
let split_char = if cfg!(target_os = "windows") {
|
||||||
|
';'
|
||||||
|
} else {
|
||||||
|
':'
|
||||||
|
};
|
||||||
if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
if let Ok(cmake_includes) = env::var("CMAKE_INCLUDE_DIRS") {
|
||||||
// we are running from cmake, do special thing.
|
// we are running from cmake, do special thing.
|
||||||
let mut includes = cmake_includes.split(':').collect::<Vec<_>>();
|
let mut includes = cmake_includes.split(split_char).collect::<Vec<_>>();
|
||||||
includes.sort_unstable();
|
includes.sort_unstable();
|
||||||
includes.dedup();
|
includes.dedup();
|
||||||
|
|
||||||
|
|
@ -63,10 +68,17 @@ pub fn setup_bindgen_builder() -> bindgen::Builder {
|
||||||
}
|
}
|
||||||
} else if !cfg!(feature = "doc-only") {
|
} else if !cfg!(feature = "doc-only") {
|
||||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||||
let ament_prefix_var =
|
let ament_prefix_var = if !cfg!(target_os = "windows") {
|
||||||
RawOsString::new(env::var_os(ament_prefix_var_name).expect("Source your ROS!"));
|
RawOsString::new(env::var_os(ament_prefix_var_name).expect("Source your ROS!"))
|
||||||
|
} else {
|
||||||
for p in ament_prefix_var.split(":") {
|
let mut ament_str = env::var_os(ament_prefix_var_name).expect("Source your ROS!");
|
||||||
|
if let Some(cmake_prefix_var) = env::var_os("CMAKE_PREFIX_PATH") {
|
||||||
|
ament_str.push(";");
|
||||||
|
ament_str.push(cmake_prefix_var);
|
||||||
|
}
|
||||||
|
RawOsString::new(ament_str)
|
||||||
|
};
|
||||||
|
for p in ament_prefix_var.split(split_char) {
|
||||||
let path = Path::new(&p.to_os_str()).join("include");
|
let path = Path::new(&p.to_os_str()).join("include");
|
||||||
|
|
||||||
let entries = std::fs::read_dir(path.clone());
|
let entries = std::fs::read_dir(path.clone());
|
||||||
|
|
@ -138,13 +150,22 @@ pub fn print_cargo_ros_distro() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_cargo_link_search() {
|
pub fn print_cargo_link_search() {
|
||||||
|
let split_char = if cfg!(target_os = "windows") {
|
||||||
|
';'
|
||||||
|
} else {
|
||||||
|
':'
|
||||||
|
};
|
||||||
if env::var_os("CMAKE_INCLUDE_DIRS").is_some() {
|
if env::var_os("CMAKE_INCLUDE_DIRS").is_some() {
|
||||||
if let Some(paths) = env::var_os("CMAKE_LIBRARIES") {
|
if let Some(paths) = env::var_os("CMAKE_LIBRARIES") {
|
||||||
let paths = RawOsString::new(paths);
|
let paths = RawOsString::new(paths);
|
||||||
|
|
||||||
paths
|
paths
|
||||||
.split(":")
|
.split(split_char)
|
||||||
.filter(|s| s.contains(".so") || s.contains(".dylib"))
|
.filter(|s| {
|
||||||
|
s.contains(".so")
|
||||||
|
|| s.contains(".dylib")
|
||||||
|
|| s.contains(".dll")
|
||||||
|
|| s.contains(".lib")
|
||||||
|
})
|
||||||
.filter_map(|l| {
|
.filter_map(|l| {
|
||||||
let l = l.to_os_str();
|
let l = l.to_os_str();
|
||||||
let parent = Path::new(&l).parent()?;
|
let parent = Path::new(&l).parent()?;
|
||||||
|
|
@ -157,11 +178,30 @@ pub fn print_cargo_link_search() {
|
||||||
} else {
|
} else {
|
||||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||||
if let Some(paths) = env::var_os(ament_prefix_var_name) {
|
if let Some(paths) = env::var_os(ament_prefix_var_name) {
|
||||||
let paths = RawOsString::new(paths);
|
let paths = if !cfg!(target_os = "windows") {
|
||||||
for path in paths.split(":") {
|
RawOsString::new(paths)
|
||||||
let lib_path = Path::new(&path.to_os_str()).join("lib");
|
} else if let Some(cmake_prefix_var) = env::var_os("CMAKE_PREFIX_PATH") {
|
||||||
if let Some(s) = lib_path.to_str() {
|
let mut cmake_paths = paths;
|
||||||
println!("cargo:rustc-link-search=native={}", s)
|
cmake_paths.push(";");
|
||||||
|
cmake_paths.push(cmake_prefix_var);
|
||||||
|
RawOsString::new(cmake_paths)
|
||||||
|
} else {
|
||||||
|
RawOsString::new(paths)
|
||||||
|
};
|
||||||
|
for path in paths.split(split_char) {
|
||||||
|
if cfg!(target_os = "windows") {
|
||||||
|
let lib_path = Path::new(&path.to_os_str()).join("Lib");
|
||||||
|
if !lib_path.exists() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(s) = lib_path.to_str() {
|
||||||
|
println!("cargo:rustc-link-search={}", s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let lib_path = Path::new(&path.to_os_str()).join("lib");
|
||||||
|
if let Some(s) = lib_path.to_str() {
|
||||||
|
println!("cargo:rustc-link-search=native={}", s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,27 +209,60 @@ pub fn print_cargo_link_search() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_wanted_messages() -> Vec<RosMsg> {
|
pub fn get_wanted_messages() -> Vec<RosMsg> {
|
||||||
|
let split_char = if cfg!(target_os = "windows") {
|
||||||
|
';'
|
||||||
|
} else {
|
||||||
|
':'
|
||||||
|
};
|
||||||
let msgs = if let Ok(cmake_package_dirs) = env::var("CMAKE_IDL_PACKAGES") {
|
let msgs = if let Ok(cmake_package_dirs) = env::var("CMAKE_IDL_PACKAGES") {
|
||||||
// CMAKE_PACKAGE_DIRS should be a (cmake) list of "cmake" dirs
|
// 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
|
// 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/
|
// we can traverse back and then look for .msg files in msg/ srv/ action/
|
||||||
let dirs = cmake_package_dirs
|
let dirs = cmake_package_dirs
|
||||||
.split(':')
|
.split(split_char)
|
||||||
.flat_map(|i| Path::new(i).parent())
|
.flat_map(|i| Path::new(i).parent())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
get_ros_msgs_files(&dirs)
|
get_ros_msgs_files(&dirs)
|
||||||
} else {
|
} else {
|
||||||
// Else we look for all msgs we can find using the ament prefix path.
|
// Else we look for all msgs we can find using the ament prefix path.
|
||||||
if let Ok(ament_prefix_var) = env::var("AMENT_PREFIX_PATH") {
|
if !cfg!(target_os = "windows") {
|
||||||
let paths = ament_prefix_var
|
if let Ok(ament_prefix_var) = env::var("AMENT_PREFIX_PATH") {
|
||||||
.split(':')
|
let paths = ament_prefix_var
|
||||||
.map(Path::new)
|
.split(split_char)
|
||||||
.collect::<Vec<_>>();
|
.map(Path::new)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
get_ros_msgs(&paths)
|
get_ros_msgs(&paths)
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
match (env::var("AMENT_PREFIX_PATH"), env::var("CMAKE_PREFIX_PATH")) {
|
||||||
|
(Ok(ament_prefix_var), Ok(cmake_prefix_var)) => {
|
||||||
|
let mut paths = ament_prefix_var
|
||||||
|
.split(split_char)
|
||||||
|
.map(Path::new)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
paths.extend(cmake_prefix_var.split(split_char).map(Path::new));
|
||||||
|
get_ros_msgs(&paths)
|
||||||
|
}
|
||||||
|
(Ok(ament_prefix_var), _) => {
|
||||||
|
let paths = ament_prefix_var
|
||||||
|
.split(split_char)
|
||||||
|
.map(Path::new)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
get_ros_msgs(&paths)
|
||||||
|
}
|
||||||
|
(_, Ok(cmake_prefix_var)) => {
|
||||||
|
let paths = cmake_prefix_var
|
||||||
|
.split(split_char)
|
||||||
|
.map(Path::new)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
get_ros_msgs(&paths)
|
||||||
|
}
|
||||||
|
_ => vec![],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -346,7 +419,7 @@ pub fn get_ros_msgs_files(paths: &[&Path]) -> Vec<String> {
|
||||||
pub fn parse_msgs(msgs: &[String]) -> Vec<RosMsg> {
|
pub fn parse_msgs(msgs: &[String]) -> Vec<RosMsg> {
|
||||||
let v: Vec<Vec<&str>> = msgs
|
let v: Vec<Vec<&str>> = msgs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.split('/').into_iter().take(3).collect())
|
.map(|l| l.split('/').take(3).collect())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// hack because I don't have time to find out the root cause of this at the moment.
|
// hack because I don't have time to find out the root cause of this at the moment.
|
||||||
|
|
@ -431,7 +504,10 @@ std_msgs/msg/String
|
||||||
fn test_camel_to_snake_case() {
|
fn test_camel_to_snake_case() {
|
||||||
assert_eq!(camel_to_snake("AB01CD02"), "ab01_cd02");
|
assert_eq!(camel_to_snake("AB01CD02"), "ab01_cd02");
|
||||||
assert_eq!(camel_to_snake("UnboundedSequences"), "unbounded_sequences");
|
assert_eq!(camel_to_snake("UnboundedSequences"), "unbounded_sequences");
|
||||||
assert_eq!(camel_to_snake("BoundedPlainUnboundedSequences"), "bounded_plain_unbounded_sequences");
|
assert_eq!(
|
||||||
|
camel_to_snake("BoundedPlainUnboundedSequences"),
|
||||||
|
"bounded_plain_unbounded_sequences"
|
||||||
|
);
|
||||||
assert_eq!(camel_to_snake("WStrings"), "w_strings");
|
assert_eq!(camel_to_snake("WStrings"), "w_strings");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use itertools::Either;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use quote::format_ident;
|
use quote::format_ident;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use r2r_common::{RosMsg, camel_to_snake};
|
use r2r_common::{camel_to_snake, RosMsg};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
|
|
||||||
|
|
@ -125,10 +125,18 @@ macro_rules! primitive_sequence {
|
||||||
primitive_sequence!(rosidl_runtime_c__float32, f32);
|
primitive_sequence!(rosidl_runtime_c__float32, f32);
|
||||||
primitive_sequence!(rosidl_runtime_c__float64, f64);
|
primitive_sequence!(rosidl_runtime_c__float64, f64);
|
||||||
|
|
||||||
#[cfg(any(all(target_os = "macos", target_arch = "aarch64"), target_arch = "arm"))]
|
#[cfg(any(
|
||||||
|
all(target_os = "macos", target_arch = "aarch64"),
|
||||||
|
target_arch = "arm",
|
||||||
|
target_os = "windows"
|
||||||
|
))]
|
||||||
primitive_sequence!(rosidl_runtime_c__long_double, f64);
|
primitive_sequence!(rosidl_runtime_c__long_double, f64);
|
||||||
|
|
||||||
#[cfg(not(any(all(target_os = "macos", target_arch = "aarch64"), target_arch = "arm")))]
|
#[cfg(not(any(
|
||||||
|
all(target_os = "macos", target_arch = "aarch64"),
|
||||||
|
target_arch = "arm",
|
||||||
|
target_os = "windows"
|
||||||
|
)))]
|
||||||
primitive_sequence!(rosidl_runtime_c__long_double, u128);
|
primitive_sequence!(rosidl_runtime_c__long_double, u128);
|
||||||
|
|
||||||
primitive_sequence!(rosidl_runtime_c__char, i8);
|
primitive_sequence!(rosidl_runtime_c__char, i8);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue