7
7
// Eventually we should see an argument that looks like `@` as we switch from
8
8
// passing literal arguments to passing everything in the file.
9
9
10
+ use std:: collections:: HashSet ;
10
11
use std:: env;
11
12
use std:: fs:: { self , File } ;
12
- use std:: io:: { BufWriter , Write , Read } ;
13
- use std:: path:: PathBuf ;
13
+ use std:: io:: { BufWriter , Write } ;
14
+ use std:: path:: { Path , PathBuf } ;
14
15
use std:: process:: Command ;
15
16
17
+ fn write_test_case ( file : & Path , n : usize ) -> HashSet < String > {
18
+ let mut libs = HashSet :: new ( ) ;
19
+ let mut f = BufWriter :: new ( File :: create ( & file) . unwrap ( ) ) ;
20
+ let mut prefix = String :: new ( ) ;
21
+ for _ in 0 ..n {
22
+ prefix. push_str ( "foo" ) ;
23
+ }
24
+ for i in 0 ..n {
25
+ writeln ! ( f, "#[link(name = \" {}{}\" )]" , prefix, i) . unwrap ( ) ;
26
+ libs. insert ( format ! ( "{}{}" , prefix, i) ) ;
27
+ }
28
+ writeln ! ( f, "extern {{}}\n fn main() {{}}" ) . unwrap ( ) ;
29
+ f. into_inner ( ) . unwrap ( ) ;
30
+
31
+ libs
32
+ }
33
+
34
+ fn read_linker_args ( path : & Path ) -> String {
35
+ let contents = fs:: read ( path) . unwrap ( ) ;
36
+ if cfg ! ( target_env = "msvc" ) {
37
+ let mut i = contents. chunks ( 2 ) . map ( |c| {
38
+ c[ 0 ] as u16 | ( ( c[ 1 ] as u16 ) << 8 )
39
+ } ) ;
40
+ assert_eq ! ( i. next( ) , Some ( 0xfeff ) , "Expected UTF-16 BOM" ) ;
41
+ String :: from_utf16 ( & i. collect :: < Vec < u16 > > ( ) ) . unwrap ( )
42
+ } else {
43
+ String :: from_utf8 ( contents) . unwrap ( )
44
+ }
45
+ }
46
+
16
47
fn main ( ) {
17
48
let tmpdir = PathBuf :: from ( env:: var_os ( "TMPDIR" ) . unwrap ( ) ) ;
18
49
let ok = tmpdir. join ( "ok" ) ;
@@ -29,16 +60,7 @@ fn main() {
29
60
for i in ( 1 ..) . map ( |i| i * 100 ) {
30
61
println ! ( "attempt: {}" , i) ;
31
62
let file = tmpdir. join ( "bar.rs" ) ;
32
- let mut f = BufWriter :: new ( File :: create ( & file) . unwrap ( ) ) ;
33
- let mut lib_name = String :: new ( ) ;
34
- for _ in 0 ..i {
35
- lib_name. push_str ( "foo" ) ;
36
- }
37
- for j in 0 ..i {
38
- writeln ! ( f, "#[link(name = \" {}{}\" )]" , lib_name, j) . unwrap ( ) ;
39
- }
40
- writeln ! ( f, "extern {{}}\n fn main() {{}}" ) . unwrap ( ) ;
41
- f. into_inner ( ) . unwrap ( ) ;
63
+ let mut expected_libs = write_test_case ( & file, i) ;
42
64
43
65
drop ( fs:: remove_file ( & ok) ) ;
44
66
let output = Command :: new ( & rustc)
@@ -67,25 +89,22 @@ fn main() {
67
89
continue
68
90
}
69
91
70
- let mut contents = Vec :: new ( ) ;
71
- File :: open ( & ok) . unwrap ( ) . read_to_end ( & mut contents) . unwrap ( ) ;
72
-
73
- for j in 0 ..i {
74
- let exp = format ! ( "{}{}" , lib_name, j) ;
75
- let exp = if cfg ! ( target_env = "msvc" ) {
76
- let mut out = Vec :: with_capacity ( exp. len ( ) * 2 ) ;
77
- for c in exp. encode_utf16 ( ) {
78
- // encode in little endian
79
- out. push ( c as u8 ) ;
80
- out. push ( ( c >> 8 ) as u8 ) ;
81
- }
82
- out
83
- } else {
84
- exp. into_bytes ( )
85
- } ;
86
- assert ! ( contents. windows( exp. len( ) ) . any( |w| w == & exp[ ..] ) ) ;
92
+ for mut arg in read_linker_args ( & ok) . lines ( ) {
93
+ if arg. starts_with ( "-l" ) {
94
+ arg = & arg[ "-l" . len ( ) ..] ;
95
+ }
96
+ if arg. ends_with ( ".lib" ) {
97
+ arg = & arg[ ..arg. len ( ) - ".lib" . len ( ) ] ;
98
+ }
99
+ expected_libs. remove ( arg) ;
87
100
}
88
101
102
+ assert ! (
103
+ expected_libs. is_empty( ) ,
104
+ "expected but missing libraries: {:#?}" ,
105
+ expected_libs,
106
+ ) ;
107
+
89
108
break
90
109
}
91
110
}
0 commit comments