@@ -5,7 +5,8 @@ use std::fmt::Display;
55use std:: path:: { Path , PathBuf } ;
66use std:: process:: { Command , Output , Stdio } ;
77use std:: str:: SplitWhitespace ;
8- use std:: vec:: IntoIter ;
8+
9+ use shlex:: Shlex ;
910
1011const OPTIONAL_COMPONENTS : & [ & str ] = & [
1112 "x86" ,
@@ -121,9 +122,8 @@ enum LlvmConfigOutput {
121122 UnquotedPaths ( String ) ,
122123}
123124
124- #[ derive( Clone ) ]
125125enum SplitLlvmConfigOutput < ' a > {
126- QuotedPaths ( IntoIter < String > ) ,
126+ QuotedPaths ( Shlex < ' a > ) ,
127127 UnquotedPaths ( SplitWhitespace < ' a > ) ,
128128}
129129
@@ -137,14 +137,22 @@ impl<'a> Iterator for SplitLlvmConfigOutput<'a> {
137137 }
138138}
139139
140+ impl Drop for SplitLlvmConfigOutput < ' _ > {
141+ fn drop ( & mut self ) {
142+ if let Self :: QuotedPaths ( shlex) = self {
143+ assert ! ( !shlex. had_error, "error parsing llvm-config output" ) ;
144+ }
145+ }
146+ }
147+
140148impl < ' a > IntoIterator for & ' a LlvmConfigOutput {
141149 type Item = Cow < ' a , str > ;
142150 type IntoIter = SplitLlvmConfigOutput < ' a > ;
143151 fn into_iter ( self ) -> Self :: IntoIter {
144152 match self {
145- LlvmConfigOutput :: QuotedPaths ( output) => SplitLlvmConfigOutput :: QuotedPaths (
146- shell_words :: split ( & output) . expect ( "matched quotes" ) . into_iter ( ) ,
147- ) ,
153+ LlvmConfigOutput :: QuotedPaths ( output) => {
154+ SplitLlvmConfigOutput :: QuotedPaths ( Shlex :: new ( output) )
155+ }
148156 LlvmConfigOutput :: UnquotedPaths ( output) => {
149157 SplitLlvmConfigOutput :: UnquotedPaths ( output. split_whitespace ( ) )
150158 }
@@ -229,7 +237,6 @@ fn main() {
229237 let mut cmd = Command :: new ( & llvm_config) ;
230238 cmd. arg ( "--cxxflags" ) ;
231239 let cxxflags = quoted_split ( cmd) ;
232- let mut cxxflags_iter = cxxflags. into_iter ( ) ;
233240 let mut cfg = cc:: Build :: new ( ) ;
234241 cfg. warnings ( false ) ;
235242
@@ -242,7 +249,7 @@ fn main() {
242249 if std:: env:: var_os ( "CI" ) . is_some ( ) && !target. contains ( "msvc" ) {
243250 cfg. warnings_into_errors ( true ) ;
244251 }
245- for flag in cxxflags_iter . clone ( ) {
252+ for flag in & cxxflags {
246253 // Ignore flags like `-m64` when we're doing a cross build
247254 if is_crossed && flag. starts_with ( "-m" ) {
248255 continue ;
@@ -435,13 +442,16 @@ fn main() {
435442 // dependencies.
436443 let llvm_linker_flags = tracked_env_var_os ( "LLVM_LINKER_FLAGS" ) ;
437444 if let Some ( s) = llvm_linker_flags {
438- for lib in shell_words:: split ( & s. into_string ( ) . unwrap ( ) ) . expect ( "matched quotes" ) {
445+ let linker_flags = s. into_string ( ) . unwrap ( ) ;
446+ let mut shlex = Shlex :: new ( & linker_flags) ;
447+ for lib in shlex. by_ref ( ) {
439448 if let Some ( stripped) = lib. strip_prefix ( "-l" ) {
440449 println ! ( "cargo:rustc-link-lib={stripped}" ) ;
441450 } else if let Some ( stripped) = lib. strip_prefix ( "-L" ) {
442451 println ! ( "cargo:rustc-link-search=native={stripped}" ) ;
443452 }
444453 }
454+ assert ! ( !shlex. had_error, "error parsing LLVM_LINKER_FLAGS" ) ;
445455 }
446456
447457 let llvm_static_stdcpp = tracked_env_var_os ( "LLVM_STATIC_STDCPP" ) ;
@@ -476,15 +486,15 @@ fn main() {
476486 // C++ runtime library
477487 if !target. contains ( "msvc" ) {
478488 if let Some ( s) = llvm_static_stdcpp {
479- assert ! ( cxxflags_iter . all( |flag| flag != "-stdlib=libc++" ) ) ;
489+ assert ! ( cxxflags . into_iter ( ) . all( |flag| flag != "-stdlib=libc++" ) ) ;
480490 let path = PathBuf :: from ( s) ;
481491 println ! ( "cargo:rustc-link-search=native={}" , path. parent( ) . unwrap( ) . display( ) ) ;
482492 if target. contains ( "windows" ) {
483493 println ! ( "cargo:rustc-link-lib=static:-bundle={stdcppname}" ) ;
484494 } else {
485495 println ! ( "cargo:rustc-link-lib=static={stdcppname}" ) ;
486496 }
487- } else if cxxflags_iter . any ( |flag| flag == "-stdlib=libc++" ) {
497+ } else if cxxflags . into_iter ( ) . any ( |flag| flag == "-stdlib=libc++" ) {
488498 println ! ( "cargo:rustc-link-lib=c++" ) ;
489499 } else {
490500 println ! ( "cargo:rustc-link-lib={stdcppname}" ) ;
0 commit comments