From 621592bb9e40d8417ba7357e0eca3ed7f8526dc7 Mon Sep 17 00:00:00 2001 From: gaoqiangz Date: Tue, 14 Mar 2023 19:32:26 +0800 Subject: [PATCH] Optimize `openssl` linkage --- paho-mqtt-sys/build.rs | 128 +++++++++++++++++++++------------------ paho-mqtt-sys/src/lib.rs | 82 +++++++++++++++++++------ 2 files changed, 133 insertions(+), 77 deletions(-) diff --git a/paho-mqtt-sys/build.rs b/paho-mqtt-sys/build.rs index 8544f7c..ab3176e 100644 --- a/paho-mqtt-sys/build.rs +++ b/paho-mqtt-sys/build.rs @@ -87,11 +87,21 @@ fn pointer_width() -> u32 { fn link_lib_base() -> &'static str { if cfg!(feature = "ssl") { println!("debug:link Using SSL library"); - if is_windows() { "paho-mqtt3as-static" } else { "paho-mqtt3as" } + if is_windows() { + "paho-mqtt3as-static" + } + else { + "paho-mqtt3as" + } } else { println!("debug:link Using non-SSL library"); - if is_windows() { "paho-mqtt3a-static" } else { "paho-mqtt3a" } + if is_windows() { + "paho-mqtt3a-static" + } + else { + "paho-mqtt3a" + } } } @@ -99,11 +109,12 @@ fn link_lib_base() -> &'static str { // directories under the specified install path. // On success returns the path and base library name (i.e. the search path // and link library name). -fn find_link_lib

(install_path: P) -> Option<(PathBuf,&'static str)> - where P: AsRef +fn find_link_lib

(install_path: P) -> Option<(PathBuf, &'static str)> +where + P: AsRef, { let install_path = install_path.as_ref(); - let lib_dirs = &[ "lib", "lib64" ]; + let lib_dirs = &["lib", "lib64"]; let lib_base = link_lib_base(); @@ -144,19 +155,24 @@ mod bindings { let ptr_wd = pointer_width(); println!("debug:Target Pointer Width: {}", ptr_wd); - let mut bindings = format!("bindings/bindings_paho_mqtt_c_{}-{}.rs", - PAHO_MQTT_C_VERSION, target); + let mut bindings = format!( + "bindings/bindings_paho_mqtt_c_{}-{}.rs", + PAHO_MQTT_C_VERSION, target + ); if !Path::new(&bindings).exists() { - println!("No bindings exist for: {}. Using {}-bit default.", - bindings, ptr_wd); - bindings = format!("bindings/bindings_paho_mqtt_c_{}-default-{}.rs", - PAHO_MQTT_C_VERSION, ptr_wd) + println!( + "No bindings exist for: {}. Using {}-bit default.", + bindings, ptr_wd + ); + bindings = format!( + "bindings/bindings_paho_mqtt_c_{}-default-{}.rs", + PAHO_MQTT_C_VERSION, ptr_wd + ) } println!("debug:Using bindings from: {}", bindings); - fs::copy(&bindings, out_path) - .expect("Could not copy bindings to output directory"); + fs::copy(&bindings, out_path).expect("Could not copy bindings to output directory"); } } @@ -167,7 +183,7 @@ mod bindings { use super::*; use std::{ - fs, env, + env, fs, path::{Path, PathBuf}, }; @@ -188,7 +204,8 @@ mod bindings { .trust_clang_mangling(false) // The input header we would like to generate // bindings for. - .header("wrapper.h").clang_arg(inc_search) + .header("wrapper.h") + .clang_arg(inc_search) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. @@ -198,7 +215,8 @@ mod bindings { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let out_path = out_dir.join("bindings.rs"); - bindings.write_to_file(out_path.clone()) + bindings + .write_to_file(out_path.clone()) .expect("Couldn't write bindings!"); // Save a copy of the bindings file into the bindings/ dir @@ -207,8 +225,10 @@ mod bindings { let target = env::var("TARGET").unwrap(); println!("debug:Target: {}", target); - let bindings = format!("bindings/bindings_paho_mqtt_c_{}-{}.rs", - PAHO_MQTT_C_VERSION, target); + let bindings = format!( + "bindings/bindings_paho_mqtt_c_{}-{}.rs", + PAHO_MQTT_C_VERSION, target + ); if !Path::new(&bindings).exists() { if let Err(err) = fs::copy(out_path, &bindings) { @@ -231,7 +251,7 @@ mod build { use super::*; use std::{ -// path::Path, + // path::Path, process, process::Command, }; @@ -240,7 +260,26 @@ mod build { // but it only seems to set a variable for the path to the include files. // We assume the directory above that one is the SSL root. fn openssl_root_dir() -> Option { - env::var("DEP_OPENSSL_INCLUDE").ok().and_then(|path| { + use std::ffi::OsString; + + fn env_inner(name: &str) -> Option { + let var = env::var_os(name); + println!("cargo:rerun-if-env-changed={}", name); + + match var { + Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), + None => println!("{} unset", name), + } + + var + } + fn env(name: &str) -> Option { + let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_"); + let prefixed = format!("{}_{}", prefix, name); + env_inner(&prefixed).or_else(|| env_inner(name)) + } + + env("OPENSSL_INCLUDE_DIR").and_then(|path| { Path::new(&path) .parent() .map(|path| path.display().to_string()) @@ -262,8 +301,8 @@ mod build { // Mske sure that the Git submodule is checked out if !Path::new("paho.mqtt.c/.git").exists() { let _ = Command::new("git") - .args(&["submodule", "update", "--init"]) - .status(); + .args(&["submodule", "update", "--init"]) + .status(); } // Configure cmake to build the Paho C lib @@ -294,10 +333,14 @@ mod build { _ => { println!("Error building Paho C library."); process::exit(103); - }, + } }; - println!("debug:Using Paho C library at: {} [{}]", lib_path.display(), link_lib); + println!( + "debug:Using Paho C library at: {} [{}]", + lib_path.display(), + link_lib + ); // Get bundled bindings or regenerate let inc_dir = cmk_install_path.join("include"); @@ -305,54 +348,19 @@ mod build { bindings::place_bindings(&inc_dir); - // Link in the SSL libraries if configured for it. - if cfg!(feature = "ssl") { - if let Some(openssl_root_dir) = openssl_root_dir() { - println!("cargo:rustc-link-search={}/lib", openssl_root_dir); - } - - // See if static SSL linkage was requested - let linkage = match env::var("OPENSSL_STATIC") - .as_ref() - .map(|s| s.as_str()) - { - Ok("0") => "", - Ok(_) => "=static", - Err(_) => "" - }; - - let prefix = if is_msvc() { "lib" } else { "" }; - - println!("cargo:rustc-link-lib{}={}ssl", linkage, prefix); - println!("cargo:rustc-link-lib{}={}crypto", linkage, prefix); - - if is_windows() { - if !is_msvc() { - // required for mingw builds - println!("cargo:rustc-link-lib{}=crypt32", linkage); - println!("cargo:rustc-link-lib{}=rpcrt4", linkage); - } - println!("cargo:rustc-link-lib=User32"); - } - } - // we add the folder where all the libraries are built to the path search println!("cargo:rustc-link-search=native={}", lib_path.display()); println!("cargo:rustc-link-lib=static={}", link_lib); } } - // Here we're building with an existing Paho C library. // This can be a library installed on the system or the location might be // specified with some environment variables, like: "PAHO_MQTT_C_DIR" #[cfg(not(feature = "bundled"))] mod build { use super::*; - use std::{ - env, - path::Path, - }; + use std::{env, path::Path}; // Set the library path, and return the location of the header, // if found. diff --git a/paho-mqtt-sys/src/lib.rs b/paho-mqtt-sys/src/lib.rs index c1f568f..fd2c028 100644 --- a/paho-mqtt-sys/src/lib.rs +++ b/paho-mqtt-sys/src/lib.rs @@ -23,16 +23,20 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] - // Weirdness in the bindgen bindings #![allow(deref_nullptr)] - // Temporary #![allow(dead_code)] -use std::ptr; use std::fmt; use std::os::raw::{c_char, c_int}; +use std::ptr; + +#[cfg(feature = "ssl")] +mod __make_openssl_linkage_work { + #[allow(unused_imports)] + use openssl_sys::*; +} include!(concat!(env!("OUT_DIR"), "/bindings.rs")); @@ -52,7 +56,12 @@ impl Default for MQTTAsync_createOptions { /// Creates a client that can connect using MQTT v3.x or v5 fn default() -> Self { Self { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'C' as c_char, b'O' as c_char], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'C' as c_char, + b'O' as c_char, + ], struct_version: CREATE_OPTIONS_STRUCT_VERSION, sendWhileDisconnected: 0, maxBufferedMessages: 100, @@ -98,7 +107,12 @@ pub const CONNECT_OPTIONS_STRUCT_VERSION: i32 = 8; impl Default for MQTTAsync_connectOptions { fn default() -> Self { Self { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'C' as c_char], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'C' as c_char, + ], struct_version: CONNECT_OPTIONS_STRUCT_VERSION, keepAliveInterval: 60, cleansession: 1, @@ -181,7 +195,12 @@ pub const WILL_OPTIONS_STRUCT_VERSION: i32 = 1; impl Default for MQTTAsync_willOptions { fn default() -> MQTTAsync_willOptions { MQTTAsync_willOptions { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'W' as c_char ], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'W' as c_char, + ], struct_version: WILL_OPTIONS_STRUCT_VERSION, topicName: ptr::null(), message: ptr::null(), @@ -190,7 +209,7 @@ impl Default for MQTTAsync_willOptions { payload: MQTTAsync_willOptions__bindgen_ty_1 { len: 0, data: ptr::null(), - } + }, } } } @@ -201,7 +220,12 @@ pub const SSL_OPTIONS_STRUCT_VERSION: i32 = 5; impl Default for MQTTAsync_SSLOptions { fn default() -> MQTTAsync_SSLOptions { MQTTAsync_SSLOptions { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'S' as c_char ], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'S' as c_char, + ], struct_version: SSL_OPTIONS_STRUCT_VERSION, trustStore: ptr::null(), keyStore: ptr::null(), @@ -230,7 +254,12 @@ pub const SUBSCRIBE_OPTIONS_STRUCT_VERSION: i32 = 0; impl Default for MQTTSubscribe_options { fn default() -> MQTTSubscribe_options { MQTTSubscribe_options { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'S' as c_char, b'O' as c_char ], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'S' as c_char, + b'O' as c_char, + ], struct_version: SUBSCRIBE_OPTIONS_STRUCT_VERSION, noLocal: 0, retainAsPublished: 0, @@ -245,7 +274,12 @@ pub const RESPONSE_OPTIONS_STRUCT_VERSION: i32 = 1; impl Default for MQTTAsync_responseOptions { fn default() -> MQTTAsync_responseOptions { MQTTAsync_responseOptions { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'R' as c_char ], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'R' as c_char, + ], struct_version: RESPONSE_OPTIONS_STRUCT_VERSION, onSuccess: None, onFailure: None, @@ -284,7 +318,10 @@ impl Default for MQTTProperties { impl Default for MQTTLenString { fn default() -> MQTTLenString { - MQTTLenString { len: 0, data: ptr::null_mut(), } + MQTTLenString { + len: 0, + data: ptr::null_mut(), + } } } @@ -297,7 +334,12 @@ pub const MESSAGE_STRUCT_VERSION: i32 = 1; impl Default for MQTTAsync_message { fn default() -> MQTTAsync_message { MQTTAsync_message { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'M' as c_char ], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'M' as c_char, + ], struct_version: MESSAGE_STRUCT_VERSION, payloadlen: 0, payload: ptr::null_mut(), @@ -319,7 +361,12 @@ pub const DISCONNECT_OPTIONS_STRUCT_VERSION: i32 = 1; impl Default for MQTTAsync_disconnectOptions { fn default() -> MQTTAsync_disconnectOptions { MQTTAsync_disconnectOptions { - struct_id: [ b'M' as c_char, b'Q' as c_char, b'T' as c_char, b'D' as c_char], + struct_id: [ + b'M' as c_char, + b'Q' as c_char, + b'T' as c_char, + b'D' as c_char, + ], struct_version: DISCONNECT_OPTIONS_STRUCT_VERSION, timeout: 0, onSuccess: None, @@ -363,7 +410,10 @@ impl MQTTAsync_nameValue { impl Default for MQTTAsync_nameValue { fn default() -> Self { - Self { name: ptr::null(), value: ptr::null() } + Self { + name: ptr::null(), + value: ptr::null(), + } } } @@ -371,6 +421,4 @@ impl Default for MQTTAsync_nameValue { // Unit Tests #[cfg(test)] -mod tests { -} - +mod tests {}