From 223909b7636df7731f7cb0ffcdb32898f7a25d20 Mon Sep 17 00:00:00 2001 From: Geoff Martin Date: Mon, 14 Oct 2024 17:01:49 +0100 Subject: [PATCH] Tidied code and set version to 0.3.2. --- Cargo.toml | 2 +- build.rs | 167 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 61 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d21f2e9..47ed5e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cyclors" -version = "0.3.1" +version = "0.3.2" authors = ["kydos "] license = "Apache-2.0" readme = "README.md" diff --git a/build.rs b/build.rs index e76cbaf..963a272 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,12 @@ extern crate bindgen; +#[allow(unused_imports)] use std::collections::HashSet; use std::fs::File; +#[allow(unused_imports)] use std::io::{LineWriter, Write}; use std::path::{Path, PathBuf}; +#[allow(unused_imports)] use std::process::Command; use std::{env, fs}; @@ -147,29 +150,28 @@ fn main() { .clang_arg(format!("-I{}", cyclocut_include.to_str().unwrap())) .generate_comments(false); - #[allow(unused_assignments)] + #[allow(unused)] let mut prefix = String::from(""); - // Prefix symbols in Iceoryx, Cyclone DDS and Cyclocut libraries to ensure uniqueness - #[cfg(target_os = "linux")] + // Prefix symbols in Cyclone DDS and Cyclocut libraries to ensure uniqueness + #[cfg(all(target_os = "linux", not(feature = "iceoryx")))] { // Prefix = cyclors__ prefix = env::var("CARGO_PKG_VERSION").unwrap().replace(".", "_"); prefix.insert_str(0, "cyclors_"); prefix.push('_'); - println!("Library prefix: {}", prefix); let mut symbols = HashSet::new(); let cyclone_symbols = get_defined_symbols(&cyclonedds_lib, "libddsc.a") .expect("Failed to get symbols from libddsc.a!"); symbols.extend(cyclone_symbols); - prefix_symbols(&cyclonedds_lib, "libddsc.a", &prefix, &symbols); + prefix_symbols(&cyclonedds_lib, "libddsc.a", &prefix, &symbols).unwrap(); let cyclocut_symbols = get_defined_symbols(&cyclocut_lib, "libcdds-util.a") .expect("Failed to get symbols from libcdds-util.a!"); symbols.extend(cyclocut_symbols); - prefix_symbols(&cyclocut_lib, "libcdds-util.a", &prefix, &symbols); + prefix_symbols(&cyclocut_lib, "libcdds-util.a", &prefix, &symbols).unwrap(); #[derive(Debug)] struct PrefixLinkNameCallback { @@ -186,7 +188,6 @@ fn main() { true => { let mut prefix = self.prefix.clone(); prefix.push_str(item_info.name); - //println!("bindgen: {prefix}"); Some(prefix) } false => None, @@ -208,7 +209,7 @@ fn main() { .blocklist_type("^(.*IMAGE_TLS_DIRECTORY.*)$"); // Set link name prefix on additional wrapStringper functions - generate_template_src(&prefix); + generate_template_src(&prefix, &out_dir).unwrap(); // Generate bindings let bindings = bindings.generate().expect("Unable to generate bindings"); @@ -218,79 +219,125 @@ fn main() { .expect("Couldn't write bindings!"); } +#[cfg(all(target_os = "linux", not(feature = "iceoryx")))] fn get_defined_symbols(lib_dir: &Path, lib_name: &str) -> Result, String> { let lib_path = lib_dir.to_path_buf().join(lib_name); - println!( - "Getting defined symbols from {}", - lib_path.to_str().unwrap() - ); - let output = Command::new("nm") + + let rc = Command::new("nm") .arg("--defined-only") .arg("--print-file-name") .arg(lib_path) - .output() - .expect("Failed to run nm"); - - let stdout = String::from_utf8_lossy(&output.stdout); - let stderr = String::from_utf8_lossy(&output.stderr); - - match stderr.is_empty() { - true => { - let mut result: HashSet = HashSet::new(); - for line in stdout.lines() { - let tokens: Vec<&str> = line.split_whitespace().collect(); - let symbol = *tokens.last().unwrap(); - result.insert(String::from(symbol)); + .output(); + + match rc { + Ok(output) => { + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + + match stderr.is_empty() { + true => { + let mut result: HashSet = HashSet::new(); + for line in stdout.lines() { + let tokens: Vec<&str> = line.split_whitespace().collect(); + let symbol = *tokens.last().unwrap(); + result.insert(String::from(symbol)); + } + Ok(result) + } + false => Err(format!( + "Failed to run nm on library {} (stderr: {})", + lib_name, + String::from(stderr) + )), } - Ok(result) } - false => Err(String::from(stderr)), + Err(_) => Err(format!("Failed to run nm on library {}", lib_name)), } } -fn prefix_symbols(lib_dir: &Path, lib_name: &str, prefix: &str, symbols: &HashSet) { +#[cfg(all(target_os = "linux", not(feature = "iceoryx")))] +fn prefix_symbols( + lib_dir: &Path, + lib_name: &str, + prefix: &str, + symbols: &HashSet, +) -> Result<(), String> { let mut objcopy_file_name = lib_name.to_owned(); objcopy_file_name.push_str(".objcopy"); let lib_file_path = lib_dir.to_path_buf().join(lib_name); let symbol_file_path = lib_dir.to_path_buf().join(objcopy_file_name); - let symbol_file = File::create(symbol_file_path.clone()).expect("Failed to create symbol file"); - let mut symbol_file = LineWriter::new(symbol_file); - - for symbol in symbols { - let mut symbol_arg = symbol.clone(); - symbol_arg.push(' '); - symbol_arg.push_str(prefix); - symbol_arg.push_str(symbol); - symbol_arg.push('\n'); - symbol_file - .write_all(symbol_arg.as_bytes()) - .expect("Failed to write symbol file"); - } - symbol_file.flush().expect("Failed to flush symbol file"); - let arg = format!("--redefine-syms={}", symbol_file_path.to_str().unwrap()); + match File::create(symbol_file_path.clone()) { + Ok(symbol_file) => { + let mut symbol_file = LineWriter::new(symbol_file); + + for symbol in symbols { + let mut symbol_arg = symbol.clone(); + symbol_arg.push(' '); + symbol_arg.push_str(prefix); + symbol_arg.push_str(symbol); + symbol_arg.push('\n'); + if symbol_file.write_all(symbol_arg.as_bytes()).is_err() { + return Err(format!( + "Failed to write symbol file for library {}", + lib_name + )); + } + } - Command::new("objcopy") - .arg(arg) - .arg(lib_file_path) - .output() - .expect("Failed to run objcopy"); + if symbol_file.flush().is_err() { + return Err(format!( + "Failed to write symbol file for library {}", + lib_name + )); + } + let arg = format!("--redefine-syms={}", symbol_file_path.to_str().unwrap()); + match Command::new("objcopy").arg(arg).arg(lib_file_path).output() { + Ok(_) => Ok(()), + Err(_) => Err(format!("Failed to run objcopy on library {}", lib_name)), + } + } + Err(_) => Err(format!( + "Failed to create symbol file for library {}", + lib_name + )), + } } -fn generate_template_src(prefix: &str) { +fn generate_template_src(prefix: &str, out_dir: &Path) -> Result<(), String> { let src_path = Path::new("src/functions.template"); - let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR not set")); let dst_path = out_dir.join("functions.rs"); - let mut contents = fs::read_to_string(src_path).expect("Failed to read the source file."); - contents = contents.replace("", prefix); - - let mut file = - File::create(&dst_path).expect("Failed to open the destination file for writing!"); - file.write_all(contents.as_bytes()) - .expect("Failed to write the modified content to the destination file."); + match fs::read_to_string(src_path) { + Ok(mut contents) => { + contents = contents.replace("", prefix); + + match File::create(&dst_path) { + Ok(mut file) => { + if file.write_all(contents.as_bytes()).is_err() { + let path = dst_path.to_str().unwrap(); + return Err(format!( + "Failed to write the modified content to the destination file {}", + path + )); + } - println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=src/functions.template"); + println!("cargo:rerun-if-changed=src/lib.rs"); + println!("cargo:rerun-if-changed=src/functions.template"); + Ok(()) + } + Err(_) => { + let path = dst_path.to_str().unwrap(); + Err(format!( + "Failed to open the destination file ({}) for writing", + path + )) + } + } + } + Err(_) => Err(String::from( + "Failed to read the source file src/functions.template", + )), + } }