diff --git a/.cargo/config.toml b/.cargo/config.toml index e69de29..9dce705 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -0,0 +1,4 @@ +[env] +# This is set for this repository so it does not always have to be set in the command line. +# It is required for building libcsp-rust. +CSP_CONFIG_DIR = { value = "examples", relative = true } diff --git a/examples/autoconfig.rs b/examples/autoconfig.rs new file mode 100644 index 0000000..1357eaa --- /dev/null +++ b/examples/autoconfig.rs @@ -0,0 +1,7 @@ +const CSP_CONN_RXQUEUE_LEN: usize = 16 +const CSP_QFIFO_LEN: usize = 16 +const CSP_PORT_MAX_BIND: usize = 16 +const CSP_CONN_MAX: usize = 8 +const CSP_BUFFER_SIZE: usize = 256 +const CSP_RDP_MAX_WINDOW: usize = 5 +const CSP_RTABLE_SIZE: usize = 10 diff --git a/examples/build.rs b/examples/build.rs index 06e27e6..4cb4162 100644 --- a/examples/build.rs +++ b/examples/build.rs @@ -4,8 +4,18 @@ use libcsp_cargo_build::Builder; fn main() { let out_dir = env::var("OUT_DIR").unwrap_or_default(); - + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_default(); let libcsp_path = "../lib/libcsp"; - let mut csp_builder = Builder::new(PathBuf::from(libcsp_path), PathBuf::from(out_dir)); + let mut csp_builder = Builder::new(PathBuf::from(libcsp_path), PathBuf::from(&out_dir)); + let update_autoconf = match env::var("UPDATE_CSP_AUTOCONF") { + Ok(update_autoconf) => update_autoconf == "1", + Err(_e) => false, + }; + if update_autoconf { + csp_builder + .generate_autoconf_rust_file(PathBuf::from(&manifest_dir)) + .expect("generating autoconfig.rs failed"); + println!("cargo:warning=autoconfig.rs updated"); + } csp_builder.compile().expect("compiling libcsp failed"); } diff --git a/libcsp-cargo-build/src/lib.rs b/libcsp-cargo-build/src/lib.rs index 1ba5686..6de6d84 100644 --- a/libcsp-cargo-build/src/lib.rs +++ b/libcsp-cargo-build/src/lib.rs @@ -199,12 +199,15 @@ impl Builder { self.build.include(&autoconf_dir); autoconf_dir.push("csp"); std::fs::create_dir_all(&autoconf_dir)?; - generate_autoconf_file(autoconf_dir, &self.cfg) + generate_autoconf_header_file(autoconf_dir, &self.cfg) + } + + pub fn generate_autoconf_rust_file(&self, out_dir: PathBuf) -> io::Result<()> { + generate_autoconf_rust_file(out_dir, &self.cfg) } } -pub fn generate_autoconf_file(out_dir: PathBuf, cfg: &Config) -> io::Result<()> { - // panic!("cargo:warning=outdir for autoconf file: {:?}", out_dir); +pub fn generate_autoconf_header_file(out_dir: PathBuf, cfg: &Config) -> io::Result<()> { let mut autoconf_file_string = String::new(); #[cfg(unix)] autoconf_file_string.push_str("#define CSP_POSIX 1\n"); @@ -307,6 +310,49 @@ pub fn generate_autoconf_file(out_dir: PathBuf, cfg: &Config) -> io::Result<()> Ok(()) } +pub fn generate_autoconf_rust_file(out_dir: PathBuf, cfg: &Config) -> io::Result<()> { + let mut autoconf_file_string = String::new(); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_CONN_RXQUEUE_LEN, + cfg.conn_rx_queue_len + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_QFIFO_LEN, + cfg.qfifo_len + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_PORT_MAX_BIND, + cfg.port_max_bind + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_CONN_MAX, + cfg.conn_max + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_BUFFER_SIZE, + cfg.buffer_size + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_RDP_MAX_WINDOW, + cfg.rdp_max_window + )); + autoconf_file_string.push_str(&format!( + "const {}: usize = {}\n", + autoconf::CFG_RTABLE_SIZE, + cfg.rtable_size + )); + let out_file = out_dir.join("autoconfig.rs"); + let mut file = std::fs::File::create(out_file)?; + file.write_all(autoconf_file_string.as_bytes())?; + Ok(()) +} + #[cfg(test)] mod tests { // TODO: Unittest autoconf generator. diff --git a/libcsp-rust/build.rs b/libcsp-rust/build.rs index ea1fe36..7648fcc 100644 --- a/libcsp-rust/build.rs +++ b/libcsp-rust/build.rs @@ -1,3 +1,29 @@ +use std::{env, path::PathBuf}; + +pub const ENV_KEY_CSP_CONFIG_DIR: &str = "CSP_CONFIG_DIR"; + fn main() { - println!("cargo:rustc-link-lib=csp") + println!("cargo:rustc-link-lib=csp"); + + let out_path = env::var("OUT_DIR").unwrap(); + let csp_conf_dir = match env::var("CSP_CONFIG_DIR") { + Ok(conf_path) => conf_path, + Err(_e) => { + println!("cargo:warning=CSP_CONFIG_DIR not set, using CARGO_MANIFEST_DIR to search for autoconfig.rs"); + env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set") + } + }; + println!("cargo:warning=CSP_CONFIG_DIR={}", csp_conf_dir); + let mut csp_conf_path = PathBuf::new(); + csp_conf_path.push(csp_conf_dir); + csp_conf_path.push("autoconfig.rs"); + if !csp_conf_path.exists() { + panic!( + "autoconfig.rs not found at {:?}, is required for library build", + csp_conf_path + ); + } + let out_path_full = PathBuf::from(&out_path).join("autoconfig.rs"); + std::fs::copy(&csp_conf_path, out_path_full).expect("failed to copy autoconfig.rs to OUT_DIR"); + println!("cargo::rerun-if-changed={:?}", &csp_conf_path); } diff --git a/libcsp-rust/src/config.rs b/libcsp-rust/src/config.rs new file mode 100644 index 0000000..1a8a24e --- /dev/null +++ b/libcsp-rust/src/config.rs @@ -0,0 +1,3 @@ +/// This environbment variable should be set by the user. If it is not set, the library will +/// try to find an autoconfig.rs file inside the CARGO_TARGET_DIR directory. +pub const ENV_KEY_CSP_CONFIG_DIR: &str = "CSP_CONFIG_DIR"; diff --git a/libcsp-rust/src/ffi.rs b/libcsp-rust/src/ffi.rs index 65ec200..790d609 100644 --- a/libcsp-rust/src/ffi.rs +++ b/libcsp-rust/src/ffi.rs @@ -2,10 +2,10 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] -// These constants come from the autoconfig file, which is supposed to be configurable.. -// How do we deal with this? Rust libraries are not supposed to be configured like this. -pub const CSP_BUFFER_SIZE: usize = 256; -pub const CSP_CONN_RXQUEUE_LEN: usize = 16; +// This file will be created by the build script by copying a user-provided file to the output +// directory. It contains important compile time constants. Compilation of the library is not +// possible without these constants. +include!(concat!(env!("OUT_DIR"), "/autoconfig.rs")); #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/libcsp-rust/src/lib.rs b/libcsp-rust/src/lib.rs index 30848cf..a7b187c 100644 --- a/libcsp-rust/src/lib.rs +++ b/libcsp-rust/src/lib.rs @@ -6,6 +6,8 @@ extern crate alloc; extern crate std; pub mod ffi; +pub mod config; + use core::time::Duration; use num_enum::{IntoPrimitive, TryFromPrimitive}; diff --git a/libcsp-rust/templates/autoconfig.rs b/libcsp-rust/templates/autoconfig.rs new file mode 100644 index 0000000..681f2df --- /dev/null +++ b/libcsp-rust/templates/autoconfig.rs @@ -0,0 +1,8 @@ +pub const CSP_CONN_RXQUEUE_LEN: usize = 16; +pub const CSP_QFIFO_LEN: usize = 15; +pub const CSP_PORT_MAX_BIND: usize = 16; +pub const CSP_CONN_MAX: usize = 8; +pub const CSP_BUFFER_SIZE: usize = 256; +pub const CSP_BUFFER_COUNT: usize = 15; +pub const CSP_RDP_MAX_WINDOW: usize = 5; +pub const CSP_RTABLE_SIZE: usize = 10;