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 ( )
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. iter ( ) . find ( |entry| {
70
+ entry
71
+ . file_name ( )
72
+ . to_string_lossy ( )
73
+ . to_string ( )
74
+ . contains ( host)
75
+ } )
76
+ }
77
+ . expect ( "host dir not found" )
78
+ . file_name ( )
79
+ . to_string_lossy ( )
80
+ . to_string ( ) ;
81
+ info ! ( "crates parent dirs:{:?}" , crates_parent_dirs) ;
82
+ let metadata = MetadataCommand :: default ( )
83
+ . no_deps ( )
84
+ . exec ( )
85
+ . expect ( "read cargo metadata failed" ) ;
86
+ let package = metadata
87
+ . packages
88
+ . first ( )
89
+ . expect ( "read current package failed" ) ;
90
+ info ! ( "read package:{:#?}" , package) ;
91
+ let dependency = package
92
+ . dependencies
93
+ . iter ( )
94
+ . find ( |dep| dep. name . eq ( "open-coroutine-hook" ) )
95
+ . expect ( "open-coroutine-hook not found" ) ;
96
+ let version = & dependency
97
+ . req
98
+ . comparators
99
+ . first ( )
100
+ . expect ( "version not found" ) ;
101
+ hook_toml = dep_src_dir
102
+ . join ( crates_parent)
103
+ . join ( format ! (
104
+ "open-coroutine-hook-{}.{}.{}" ,
105
+ version. major,
106
+ version. minor. unwrap_or( 0 ) ,
107
+ version. patch. unwrap_or( 0 )
108
+ ) )
109
+ . join ( "Cargo.toml" ) ;
29
110
}
30
- //fix dylib name
111
+ info ! ( "open-coroutine-hook's Cargo.toml is here:{:?}" , hook_toml) ;
112
+ assert ! (
113
+ cmd. arg( "--manifest-path" )
114
+ . arg( hook_toml)
115
+ . arg( "--target-dir" )
116
+ . arg( out_dir. clone( ) )
117
+ . status( )
118
+ . expect( "failed to build dylib" )
119
+ . success( ) ,
120
+ "failed to build dylib"
121
+ ) ;
122
+ // correct dylib path
31
123
let hook_deps = out_dir
32
124
. join ( target)
33
125
. join ( if cfg ! ( debug_assertions) {
@@ -44,53 +136,38 @@ fn main() {
44
136
. parent ( )
45
137
. expect ( "can not find deps dir" )
46
138
. 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
139
for entry in read_dir ( hook_deps. clone ( ) )
53
- . expect ( "Failed to read deps" )
140
+ . expect ( "can not find deps dir " )
54
141
. flatten ( )
55
142
{
56
143
let file_name = entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
57
144
if !file_name. contains ( "open_coroutine_hook" ) {
58
145
continue ;
59
146
}
60
- if lib_names. contains ( & file_name) {
61
- break ;
62
- }
63
- if file_name. eq ( "open_coroutine_hook.dll" ) {
64
- continue ;
65
- }
66
147
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!" ) ;
148
+ let from = hook_deps. join ( file_name) ;
149
+ let to = deps. join ( "libopen_coroutine_hook.so" ) ;
150
+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to libopen_coroutine_hook.so failed!" ) ;
151
+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
72
152
} 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!" ) ;
153
+ let from = hook_deps. join ( file_name) ;
154
+ let to = deps. join ( "libopen_coroutine_hook.dylib" ) ;
155
+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to libopen_coroutine_hook.dylib failed!" ) ;
156
+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
78
157
} else if cfg ! ( windows) {
79
158
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!" ) ;
159
+ let from = hook_deps. join ( file_name) ;
160
+ let to = deps. join ( "open_coroutine_hook.dll" ) ;
161
+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to open_coroutine_hook.dll failed!" ) ;
162
+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
85
163
} 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!" ) ;
164
+ let from = hook_deps. join ( file_name) ;
165
+ let to = deps. join ( "open_coroutine_hook.lib" ) ;
166
+ copy ( from. clone ( ) , to. clone ( ) ) . expect ( "copy to open_coroutine_hook.lib failed!" ) ;
167
+ info ! ( "copy {:?} to {:?} success!" , from, to) ;
91
168
}
92
169
}
93
170
}
94
- //link hook dylib
171
+ // link dylib
95
172
println ! ( "cargo:rustc-link-lib=dylib=open_coroutine_hook" ) ;
96
173
}
0 commit comments