diff --git a/Cargo.toml b/Cargo.toml index 6b497de3..59b0a539 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "0.6.0" +version = "0.6.8" edition = "2021" authors = ["zhangzicheng@apache.org"] repository = "https://github.com/acl-dev/open-coroutine" @@ -22,6 +22,8 @@ open-coroutine-macros = { path = "macros", version = "0.6.0" } tracing = { version = "0.1", default-features = false } tracing-subscriber = { version = "0.3", default-features = false } +tracing-appender = { version = "0.2", default-features = false } +cargo_metadata = { version = "0.18", default-features = false } mio = { version = "1.0", default-features = false } cfg-if = "1.0.0" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 37a7f0fa..8b623975 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -47,13 +47,9 @@ )] //! see `https://github.com/acl-dev/open-coroutine` -#[macro_use] -extern crate quote; -#[macro_use] -extern crate syn; - use proc_macro::TokenStream; -use syn::{ItemFn, LitBool, LitInt}; +use quote::quote; +use syn::{parse_macro_input, ItemFn, LitBool, LitInt}; /// use this macro like `#[open_coroutine::main(event_loop_size = 2, max_size = 2, keep_alive_time = 0)]`. #[proc_macro_attribute] diff --git a/open-coroutine/Cargo.toml b/open-coroutine/Cargo.toml index e2d14a85..8dacd906 100644 --- a/open-coroutine/Cargo.toml +++ b/open-coroutine/Cargo.toml @@ -25,6 +25,16 @@ windows-sys = { workspace = true, features = [ "Win32_System_Diagnostics_Debug", ] } +[build-dependencies] +tracing = { workspace = true, default-features = false } +tracing-subscriber = { workspace = true, features = [ + "fmt", + "local-time" +], default-features = false } +tracing-appender.workspace = true +time.workspace = true +cargo_metadata.workspace = true + [dev-dependencies] tempfile.workspace = true diff --git a/open-coroutine/build.rs b/open-coroutine/build.rs index fa7f3ab5..e7a5c161 100644 --- a/open-coroutine/build.rs +++ b/open-coroutine/build.rs @@ -1,33 +1,113 @@ +use cargo_metadata::MetadataCommand; use std::env::var; -use std::fs::{read_dir, rename}; +use std::fs::{copy, read_dir}; use std::path::PathBuf; +use tracing::{info, Level}; +use tracing_appender::rolling::{RollingFileAppender, Rotation}; fn main() { + // init log + let out_dir = PathBuf::from(var("OUT_DIR").expect("OUT_DIR not found")); + let target_dir = out_dir + .parent() + .expect("can not find deps dir") + .parent() + .expect("can not find deps dir") + .parent() + .expect("can not find deps dir") + .parent() + .expect("can not find deps dir"); + _ = tracing_subscriber::fmt() + .with_writer(RollingFileAppender::new( + Rotation::NEVER, + target_dir, + "open-coroutine-build.log", + )) + .with_thread_names(true) + .with_line_number(true) + .with_max_level(Level::INFO) + .with_timer(tracing_subscriber::fmt::time::OffsetTime::new( + time::UtcOffset::from_hms(8, 0, 0).expect("create UtcOffset failed !"), + time::format_description::well_known::Rfc2822, + )) + .try_init(); // build dylib let target = var("TARGET").expect("env not found"); - let out_dir = PathBuf::from(var("OUT_DIR").expect("env not found")); - let cargo_manifest_dir = PathBuf::from(var("CARGO_MANIFEST_DIR").expect("env not found")); let mut cargo = std::process::Command::new("cargo"); let mut cmd = cargo.arg("build").arg("--target").arg(target.clone()); if cfg!(not(debug_assertions)) { cmd = cmd.arg("--release"); } - if let Err(e) = cmd - .arg("--manifest-path") - .arg( - cargo_manifest_dir - .parent() - .expect("parent not found") - .join("hook") - .join("Cargo.toml"), - ) - .arg("--target-dir") - .arg(out_dir.clone()) - .status() - { - panic!("failed to build build dylib {e}"); + let mut hook_toml = PathBuf::from(var("CARGO_MANIFEST_DIR").expect("env not found")) + .parent() + .expect("parent not found") + .join("hook") + .join("Cargo.toml"); + if !hook_toml.exists() { + info!("{hook_toml:?} not exists, find open-coroutine-hook's Cargo.toml in $CARGO_HOME"); + // 使用cargo_metadata读到依赖版本,结合CARGO_HOME获取open-coroutine-hook的toml + let mut dep_src_dir = PathBuf::from(var("CARGO_HOME").expect("CARGO_HOME not found")) + .join("registry") + .join("src"); + let rustup_dist_server = var("RUSTUP_DIST_SERVER").expect("RUSTUP_DIST_SERVER not found"); + let host = rustup_dist_server + .split("://") + .last() + .expect("host not found"); + dep_src_dir = dep_src_dir.join( + read_dir(dep_src_dir.clone()) + .expect("Failed to read deps") + .flatten() + .find(|entry| { + let file_name = entry.file_name().to_string_lossy().to_string(); + file_name.contains(host) + }) + .expect("host dir not found") + .file_name() + .to_string_lossy() + .to_string(), + ); + info!("dep_src_dir:{dep_src_dir:?}"); + let metadata = MetadataCommand::default() + .no_deps() + .exec() + .expect("read cargo metadata failed"); + let package = metadata + .packages + .first() + .expect("read current package failed"); + info!("read package:{:#?}", package); + let dependency = package + .dependencies + .iter() + .find(|dep| dep.name.eq("open-coroutine-hook")) + .expect("open-coroutine-hook not found"); + let version = &dependency + .req + .comparators + .first() + .expect("version not found"); + hook_toml = dep_src_dir + .join(format!( + "open-coroutine-hook-{}.{}.{}", + version.major, + version.minor.unwrap_or(0), + version.patch.unwrap_or(0) + )) + .join("Cargo.toml"); } - //fix dylib name + info!("open-coroutine-hook's Cargo.toml is here:{hook_toml:?}"); + assert!( + cmd.arg("--manifest-path") + .arg(hook_toml) + .arg("--target-dir") + .arg(out_dir.clone()) + .status() + .expect("failed to build dylib") + .success(), + "failed to build dylib" + ); + // link dylib let hook_deps = out_dir .join(target) .join(if cfg!(debug_assertions) { @@ -44,50 +124,35 @@ fn main() { .parent() .expect("can not find deps dir") .join("deps"); - let lib_names = [ - String::from("libopen_coroutine_hook.so"), - String::from("libopen_coroutine_hook.dylib"), - String::from("open_coroutine_hook.lib"), - ]; for entry in read_dir(hook_deps.clone()) - .expect("Failed to read deps") + .expect("can not find deps dir") .flatten() { let file_name = entry.file_name().to_string_lossy().to_string(); if !file_name.contains("open_coroutine_hook") { continue; } - if lib_names.contains(&file_name) { - break; - } - if file_name.eq("open_coroutine_hook.dll") { - continue; - } if cfg!(target_os = "linux") && file_name.ends_with(".so") { - rename( - hook_deps.join(file_name), - deps.join("libopen_coroutine_hook.so"), - ) - .expect("rename to libopen_coroutine_hook.so failed!"); + let from = hook_deps.join(file_name); + let to = deps.join("libopen_coroutine_hook.so"); + copy(from.clone(), to.clone()).expect("copy to libopen_coroutine_hook.so failed!"); + info!("copy {:?} to {:?} success!", from, to); } else if cfg!(target_os = "macos") && file_name.ends_with(".dylib") { - rename( - hook_deps.join(file_name), - deps.join("libopen_coroutine_hook.dylib"), - ) - .expect("rename to libopen_coroutine_hook.dylib failed!"); + let from = hook_deps.join(file_name); + let to = deps.join("libopen_coroutine_hook.dylib"); + copy(from.clone(), to.clone()).expect("copy to libopen_coroutine_hook.dylib failed!"); + info!("copy {:?} to {:?} success!", from, to); } else if cfg!(windows) { if file_name.ends_with(".dll") { - rename( - hook_deps.join(file_name), - deps.join("open_coroutine_hook.dll"), - ) - .expect("rename to open_coroutine_hook.dll failed!"); + let from = hook_deps.join(file_name); + let to = deps.join("open_coroutine_hook.dll"); + copy(from.clone(), to.clone()).expect("copy to open_coroutine_hook.dll failed!"); + info!("copy {:?} to {:?} success!", from, to); } else if file_name.ends_with(".lib") { - rename( - hook_deps.join(file_name), - deps.join("open_coroutine_hook.lib"), - ) - .expect("rename to open_coroutine_hook.lib failed!"); + let from = hook_deps.join(file_name); + let to = deps.join("open_coroutine_hook.lib"); + copy(from.clone(), to.clone()).expect("copy to open_coroutine_hook.lib failed!"); + info!("copy {:?} to {:?} success!", from, to); } } }