1+ use cargo_metadata:: MetadataCommand ;
12use std:: env:: var;
2- use std:: fs:: { read_dir , rename } ;
3+ use std:: fs:: { copy , read_dir } ;
34use std:: path:: PathBuf ;
5+ use tracing:: { info, Level } ;
6+ use tracing_appender:: rolling:: { RollingFileAppender , Rotation } ;
47
58fn main ( ) {
9+ // init log
10+ let out_dir = PathBuf :: from ( var ( "OUT_DIR" ) . expect ( "OUT_DIR not found" ) ) ;
11+ let target_dir = out_dir
12+ . parent ( )
13+ . expect ( "can not find deps dir" )
14+ . parent ( )
15+ . expect ( "can not find deps dir" )
16+ . parent ( )
17+ . expect ( "can not find deps dir" )
18+ . parent ( )
19+ . expect ( "can not find deps dir" ) ;
20+ _ = tracing_subscriber:: fmt ( )
21+ . with_writer ( RollingFileAppender :: new (
22+ Rotation :: NEVER ,
23+ target_dir,
24+ "open-coroutine-build.log" ,
25+ ) )
26+ . with_thread_names ( true )
27+ . with_line_number ( true )
28+ . with_max_level ( Level :: INFO )
29+ . with_timer ( tracing_subscriber:: fmt:: time:: OffsetTime :: new (
30+ time:: UtcOffset :: from_hms ( 8 , 0 , 0 ) . expect ( "create UtcOffset failed !" ) ,
31+ time:: format_description:: well_known:: Rfc2822 ,
32+ ) )
33+ . try_init ( ) ;
634 // build dylib
735 let target = var ( "TARGET" ) . expect ( "env not found" ) ;
8- let out_dir = PathBuf :: from ( var ( "OUT_DIR" ) . expect ( "env not found" ) ) ;
9- let cargo_manifest_dir = PathBuf :: from ( var ( "CARGO_MANIFEST_DIR" ) . expect ( "env not found" ) ) ;
1036 let mut cargo = std:: process:: Command :: new ( "cargo" ) ;
1137 let mut cmd = cargo. arg ( "build" ) . arg ( "--target" ) . arg ( target. clone ( ) ) ;
1238 if cfg ! ( not( debug_assertions) ) {
1339 cmd = cmd. arg ( "--release" ) ;
1440 }
15- if let Err ( e) = cmd
16- . arg ( "--manifest-path" )
17- . arg (
18- cargo_manifest_dir
19- . parent ( )
20- . expect ( "parent not found" )
21- . join ( "hook" )
22- . join ( "Cargo.toml" ) ,
23- )
24- . arg ( "--target-dir" )
25- . arg ( out_dir. clone ( ) )
26- . status ( )
27- {
28- panic ! ( "failed to build build dylib {e}" ) ;
41+ let mut hook_toml = PathBuf :: from ( var ( "CARGO_MANIFEST_DIR" ) . expect ( "env not found" ) )
42+ . parent ( )
43+ . expect ( "parent not found" )
44+ . join ( "hook" )
45+ . join ( "Cargo.toml" ) ;
46+ if !hook_toml. exists ( ) {
47+ info ! (
48+ "{:?} not exists, find open-coroutine-hook's Cargo.toml in $CARGO_HOME" ,
49+ hook_toml
50+ ) ;
51+ // 使用cargo_metadata读到依赖版本,结合CARGO_HOME获取open-coroutine-hook的toml
52+ let dep_src_dir = PathBuf :: from ( var ( "CARGO_HOME" ) . expect ( "CARGO_HOME not found" ) )
53+ . join ( "registry" )
54+ . join ( "src" ) ;
55+ let crates_parent_dirs = Vec :: from_iter (
56+ read_dir ( dep_src_dir. clone ( ) )
57+ . expect ( "Failed to read deps" )
58+ . flatten ( ) ,
59+ ) ;
60+ let crates_parent = if crates_parent_dirs. len ( ) == 1 {
61+ crates_parent_dirs. first ( ) . expect ( "host dir not found" )
62+ } else {
63+ let rustup_dist_server =
64+ var ( "RUSTUP_DIST_SERVER" ) . expect ( "RUSTUP_DIST_SERVER not found" ) ;
65+ let host = rustup_dist_server
66+ . split ( "://" )
67+ . last ( )
68+ . expect ( "host not found" ) ;
69+ crates_parent_dirs
70+ . iter ( )
71+ . find ( |entry| {
72+ entry
73+ . file_name ( )
74+ . to_string_lossy ( )
75+ . to_string ( )
76+ . contains ( host)
77+ } )
78+ . unwrap_or_else ( || {
79+ crates_parent_dirs
80+ . iter ( )
81+ . find ( |entry| {
82+ entry
83+ . file_name ( )
84+ . to_string_lossy ( )
85+ . to_string ( )
86+ . contains ( "crates.io" )
87+ } )
88+ . expect ( "host dir not found" )
89+ } )
90+ }
91+ . file_name ( )
92+ . to_string_lossy ( )
93+ . to_string ( ) ;
94+ info ! ( "crates parent dirs:{:?}" , crates_parent_dirs) ;
95+ let metadata = MetadataCommand :: default ( )
96+ . no_deps ( )
97+ . exec ( )
98+ . expect ( "read cargo metadata failed" ) ;
99+ let package = metadata
100+ . packages
101+ . first ( )
102+ . expect ( "read current package failed" ) ;
103+ info ! ( "read package:{:#?}" , package) ;
104+ let dependency = package
105+ . dependencies
106+ . iter ( )
107+ . find ( |dep| dep. name . eq ( "open-coroutine-hook" ) )
108+ . expect ( "open-coroutine-hook not found" ) ;
109+ let version = & dependency
110+ . req
111+ . comparators
112+ . first ( )
113+ . expect ( "version not found" ) ;
114+ hook_toml = dep_src_dir
115+ . join ( crates_parent)
116+ . join ( format ! (
117+ "open-coroutine-hook-{}.{}.{}" ,
118+ version. major,
119+ version. minor. unwrap_or( 0 ) ,
120+ version. patch. unwrap_or( 0 )
121+ ) )
122+ . join ( "Cargo.toml" ) ;
29123 }
30- //fix dylib name
124+ info ! ( "open-coroutine-hook's Cargo.toml is here:{:?}" , hook_toml) ;
125+ assert ! (
126+ cmd. arg( "--manifest-path" )
127+ . arg( hook_toml)
128+ . arg( "--target-dir" )
129+ . arg( out_dir. clone( ) )
130+ . status( )
131+ . expect( "failed to build dylib" )
132+ . success( ) ,
133+ "failed to build dylib"
134+ ) ;
135+ // correct dylib path
31136 let hook_deps = out_dir
32137 . join ( target)
33138 . join ( if cfg ! ( debug_assertions) {
@@ -44,53 +149,38 @@ fn main() {
44149 . parent ( )
45150 . expect ( "can not find deps dir" )
46151 . join ( "deps" ) ;
47- let lib_names = [
48- String :: from ( "libopen_coroutine_hook.so" ) ,
49- String :: from ( "libopen_coroutine_hook.dylib" ) ,
50- String :: from ( "open_coroutine_hook.lib" ) ,
51- ] ;
52152 for entry in read_dir ( hook_deps. clone ( ) )
53- . expect ( "Failed to read deps" )
153+ . expect ( "can not find deps dir " )
54154 . flatten ( )
55155 {
56156 let file_name = entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
57157 if !file_name. contains ( "open_coroutine_hook" ) {
58158 continue ;
59159 }
60- if lib_names. contains ( & file_name) {
61- break ;
62- }
63- if file_name. eq ( "open_coroutine_hook.dll" ) {
64- continue ;
65- }
66160 if cfg ! ( target_os = "linux" ) && file_name. ends_with ( ".so" ) {
67- rename (
68- hook_deps. join ( file_name) ,
69- deps. join ( "libopen_coroutine_hook.so" ) ,
70- )
71- . expect ( "rename to libopen_coroutine_hook.so failed!" ) ;
161+ let from = hook_deps. join ( file_name) ;
162+ let to = deps. join ( "libopen_coroutine_hook.so" ) ;
163+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to libopen_coroutine_hook.so failed!" ) ;
164+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
72165 } else if cfg ! ( target_os = "macos" ) && file_name. ends_with ( ".dylib" ) {
73- rename (
74- hook_deps. join ( file_name) ,
75- deps. join ( "libopen_coroutine_hook.dylib" ) ,
76- )
77- . expect ( "rename to libopen_coroutine_hook.dylib failed!" ) ;
166+ let from = hook_deps. join ( file_name) ;
167+ let to = deps. join ( "libopen_coroutine_hook.dylib" ) ;
168+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to libopen_coroutine_hook.dylib failed!" ) ;
169+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
78170 } else if cfg ! ( windows) {
79171 if file_name. ends_with ( ".dll" ) {
80- rename (
81- hook_deps. join ( file_name) ,
82- deps. join ( "open_coroutine_hook.dll" ) ,
83- )
84- . expect ( "rename to open_coroutine_hook.dll failed!" ) ;
172+ let from = hook_deps. join ( file_name) ;
173+ let to = deps. join ( "open_coroutine_hook.dll" ) ;
174+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to open_coroutine_hook.dll failed!" ) ;
175+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
85176 } else if file_name. ends_with ( ".lib" ) {
86- rename (
87- hook_deps. join ( file_name) ,
88- deps. join ( "open_coroutine_hook.lib" ) ,
89- )
90- . expect ( "rename to open_coroutine_hook.lib failed!" ) ;
177+ let from = hook_deps. join ( file_name) ;
178+ let to = deps. join ( "open_coroutine_hook.lib" ) ;
179+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to open_coroutine_hook.lib failed!" ) ;
180+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
91181 }
92182 }
93183 }
94- //link hook dylib
184+ // link dylib
95185 println ! ( "cargo:rustc-link-lib=dylib=open_coroutine_hook" ) ;
96186}
0 commit comments