1
+ use cargo_metadata:: MetadataCommand ;
1
2
use std:: env:: var;
2
- use std:: fs:: { read_dir , rename } ;
3
+ use std:: fs:: { copy , read_dir } ;
3
4
use std:: path:: PathBuf ;
5
+ use tracing:: { info, Level } ;
6
+ use tracing_appender:: rolling:: { RollingFileAppender , Rotation } ;
4
7
5
8
fn 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 ( ) ;
6
34
// build dylib
7
35
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" ) ) ;
10
36
let mut cargo = std:: process:: Command :: new ( "cargo" ) ;
11
37
let mut cmd = cargo. arg ( "build" ) . arg ( "--target" ) . arg ( target. clone ( ) ) ;
12
38
if cfg ! ( not( debug_assertions) ) {
13
39
cmd = cmd. arg ( "--release" ) ;
14
40
}
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" ) ;
29
123
}
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
31
136
let hook_deps = out_dir
32
137
. join ( target)
33
138
. join ( if cfg ! ( debug_assertions) {
@@ -44,53 +149,38 @@ fn main() {
44
149
. parent ( )
45
150
. expect ( "can not find deps dir" )
46
151
. 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
- ] ;
52
152
for entry in read_dir ( hook_deps. clone ( ) )
53
- . expect ( "Failed to read deps" )
153
+ . expect ( "can not find deps dir " )
54
154
. flatten ( )
55
155
{
56
156
let file_name = entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
57
157
if !file_name. contains ( "open_coroutine_hook" ) {
58
158
continue ;
59
159
}
60
- if lib_names. contains ( & file_name) {
61
- break ;
62
- }
63
- if file_name. eq ( "open_coroutine_hook.dll" ) {
64
- continue ;
65
- }
66
160
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) ;
72
165
} 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) ;
78
170
} else if cfg ! ( windows) {
79
171
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) ;
85
176
} 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) ;
91
181
}
92
182
}
93
183
}
94
- //link hook dylib
184
+ // link dylib
95
185
println ! ( "cargo:rustc-link-lib=dylib=open_coroutine_hook" ) ;
96
186
}
0 commit comments