77// Eventually we should see an argument that looks like `@` as we switch from
88// passing literal arguments to passing everything in the file.
99
10+ use std:: collections:: HashSet ;
1011use std:: env;
1112use 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 } ;
1415use std:: process:: Command ;
1516
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+
1647fn main ( ) {
1748 let tmpdir = PathBuf :: from ( env:: var_os ( "TMPDIR" ) . unwrap ( ) ) ;
1849 let ok = tmpdir. join ( "ok" ) ;
@@ -29,16 +60,7 @@ fn main() {
2960 for i in ( 1 ..) . map ( |i| i * 100 ) {
3061 println ! ( "attempt: {}" , i) ;
3162 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) ;
4264
4365 drop ( fs:: remove_file ( & ok) ) ;
4466 let output = Command :: new ( & rustc)
@@ -67,25 +89,22 @@ fn main() {
6789 continue
6890 }
6991
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) ;
87100 }
88101
102+ assert ! (
103+ expected_libs. is_empty( ) ,
104+ "expected but missing libraries: {:#?}" ,
105+ expected_libs,
106+ ) ;
107+
89108 break
90109 }
91110}
0 commit comments