11use anyhow:: { bail, Context , Result } ;
22use clap:: { ArgAction , CommandFactory , FromArgMatches } ;
3+ use clap_lex:: OsStrExt ;
34use lexopt:: Arg ;
45use std:: env;
56use std:: ffi:: OsString ;
@@ -31,6 +32,16 @@ struct LldFlag {
3132 long : Option < & ' static str > ,
3233 short : Option < char > ,
3334 value : FlagValue ,
35+ nonstandard : bool ,
36+ }
37+
38+ impl LldFlag {
39+ const fn nonstandard ( self ) -> Self {
40+ LldFlag {
41+ nonstandard : true ,
42+ ..self
43+ }
44+ }
3445}
3546
3647enum FlagValue {
@@ -71,6 +82,7 @@ macro_rules! flag {
7182 long: Some ( flag!( @name [ ] $( $flag) * ) ) ,
7283 short: flag!( @short $( $short) ?) ,
7384 value: flag!( @value $( $flag) * ) ,
85+ nonstandard: false ,
7486 }
7587 } ;
7688
@@ -81,6 +93,7 @@ macro_rules! flag {
8193 long: None ,
8294 short: Some ( flag!( @char $flag) ) ,
8395 value: flag!( @value $flag $( $val) * ) ,
96+ nonstandard: false ,
8497 }
8598 } ;
8699
@@ -126,111 +139,108 @@ macro_rules! flag {
126139}
127140
128141const LLD_FLAGS : & [ LldFlag ] = & [
129- flag ! { --allow-multiple-definition } ,
130- flag ! { --allow-undefined-file=PATH } ,
131- flag ! { --allow-undefined } ,
132- flag ! { --Bdynamic } ,
133- flag ! { --Bstatic } ,
134- flag ! { --Bsymbolic } ,
135- flag ! { --build-id[ =VAL ] } ,
136- flag ! { --call_shared } ,
142+ flag ! { --allow-multiple-definition } . nonstandard ( ) ,
143+ flag ! { --allow-undefined-file=PATH } . nonstandard ( ) ,
144+ flag ! { --allow-undefined } . nonstandard ( ) ,
145+ flag ! { --Bdynamic } . nonstandard ( ) ,
146+ flag ! { --Bstatic } . nonstandard ( ) ,
147+ flag ! { --Bsymbolic } . nonstandard ( ) ,
148+ flag ! { --build-id[ =VAL ] } . nonstandard ( ) ,
149+ flag ! { --call_shared } . nonstandard ( ) ,
137150 flag ! { --check-features } ,
138- flag ! { --color-diagnostics[ =VALUE ] } ,
139- flag ! { --compress-relocations } ,
140- flag ! { --demangle } ,
141- flag ! { --dn } ,
142- flag ! { --dy } ,
143- flag ! { --emit-relocs } ,
144- flag ! { --end-lib } ,
145- flag ! { --entry SYM } ,
151+ flag ! { --color-diagnostics[ =VALUE ] } . nonstandard ( ) ,
152+ flag ! { --compress-relocations } . nonstandard ( ) ,
153+ flag ! { --demangle } . nonstandard ( ) ,
154+ flag ! { --dn } . nonstandard ( ) ,
155+ flag ! { --dy } . nonstandard ( ) ,
156+ flag ! { --emit-relocs } . nonstandard ( ) ,
157+ flag ! { --end-lib } . nonstandard ( ) ,
158+ flag ! { --entry SYM } . nonstandard ( ) ,
146159 flag ! { --error-limit=N } ,
147- flag ! { --error-unresolved-symbols } ,
160+ flag ! { --error-unresolved-symbols } . nonstandard ( ) ,
148161 flag ! { --experimental-pic } ,
149162 flag ! { --export-all } ,
150- flag ! { -E / --export-dynamic } ,
151- flag ! { --export-if -defined=SYM } ,
163+ flag ! { -E / --export-dynamic } . nonstandard ( ) ,
164+ flag ! { --export-if -defined=SYM } . nonstandard ( ) ,
152165 flag ! { --export-memory[ =NAME ] } ,
153166 flag ! { --export-table } ,
154- flag ! { --export=SYM } ,
155- flag ! { --extra-features=LIST } ,
156- flag ! { --fatal-warnings } ,
157- flag ! { --features=LIST } ,
158- flag ! { --gc-sections } ,
167+ flag ! { --export=SYM } . nonstandard ( ) ,
168+ flag ! { --extra-features=LIST } . nonstandard ( ) ,
169+ flag ! { --fatal-warnings } . nonstandard ( ) ,
170+ flag ! { --features=LIST } . nonstandard ( ) ,
171+ flag ! { --gc-sections } . nonstandard ( ) ,
159172 flag ! { --global-base=VALUE } ,
160173 flag ! { --growable-table } ,
161174 flag ! { --import-memory[ =NAME ] } ,
162175 flag ! { --import-table } ,
163- flag ! { --import-undefined } ,
176+ flag ! { --import-undefined } . nonstandard ( ) ,
164177 flag ! { --initial-heap=SIZE } ,
165178 flag ! { --initial-memory=SIZE } ,
166- flag ! { --keep-section=NAME } ,
179+ flag ! { --keep-section=NAME } . nonstandard ( ) ,
167180 flag ! { --lto-CGO =LEVEL } ,
168181 flag ! { --lto-debug-pass-manager } ,
169182 flag ! { --lto-O =LEVEL } ,
170183 flag ! { --lto-partitions=NUM } ,
171184 flag ! { -L PATH } ,
172185 flag ! { -l LIB } ,
173- flag ! { --Map =FILE } ,
186+ flag ! { --Map =FILE } . nonstandard ( ) ,
174187 flag ! { --max-memory=SIZE } ,
175188 flag ! { --merge-data-segments } ,
176- flag ! { --mllvm=FLAG } ,
189+ flag ! { --mllvm=FLAG } . nonstandard ( ) ,
177190 flag ! { -m ARCH } ,
178- flag ! { --no-allow-multiple-definition } ,
191+ flag ! { --no-allow-multiple-definition } . nonstandard ( ) ,
179192 flag ! { --no-check-features } ,
180- flag ! { --no-color-diagnostics } ,
181- flag ! { --no-demangle } ,
182- flag ! { --no-entry } ,
183- flag ! { --no-export-dynamic } ,
184- flag ! { --no-fatal-warnings } ,
185- flag ! { --no-gc-sections } ,
193+ flag ! { --no-color-diagnostics } . nonstandard ( ) ,
194+ flag ! { --no-demangle } . nonstandard ( ) ,
195+ flag ! { --no-entry } . nonstandard ( ) ,
196+ flag ! { --no-export-dynamic } . nonstandard ( ) ,
197+ flag ! { --no-fatal-warnings } . nonstandard ( ) ,
198+ flag ! { --no-gc-sections } . nonstandard ( ) ,
186199 flag ! { --no-growable-memory } ,
187200 flag ! { --no-merge-data-segments } ,
188- flag ! { --no-pie } ,
189- flag ! { --no-print-gc-sections } ,
201+ flag ! { --no-pie } . nonstandard ( ) ,
202+ flag ! { --no-print-gc-sections } . nonstandard ( ) ,
190203 flag ! { --no-shlib-sigcheck } ,
191- flag ! { --no-whole-archive } ,
192- flag ! { --noinhibit-exec } ,
193- flag ! { --non_shared } ,
204+ flag ! { --no-whole-archive } . nonstandard ( ) ,
205+ flag ! { --noinhibit-exec } . nonstandard ( ) ,
206+ flag ! { --non_shared } . nonstandard ( ) ,
194207 flag ! { -O LEVEL } ,
195208 flag ! { --page-size=VALUE } ,
196- flag ! { --pie } ,
197- flag ! { --print-gc-sections } ,
198- flag ! { -M / --print-map } ,
199- flag ! { --relocatable } ,
209+ flag ! { --pie } . nonstandard ( ) ,
210+ flag ! { --print-gc-sections } . nonstandard ( ) ,
211+ flag ! { -M / --print-map } . nonstandard ( ) ,
212+ flag ! { --relocatable } . nonstandard ( ) ,
200213 flag ! { --reproduce=VALUE } ,
201- flag ! { --rpath=VALUE } ,
202- flag ! { --save-temps } ,
214+ flag ! { --rpath=VALUE } . nonstandard ( ) ,
215+ flag ! { --save-temps } . nonstandard ( ) ,
203216 flag ! { --shared-memory } ,
204- flag ! { --shared } ,
205- flag ! { --soname=VALUE } ,
206- flag ! { --stack-first } ,
207- flag ! { --start-lib } ,
208- flag ! { --static } ,
209- flag ! { -s / --strip-all } ,
210- flag ! { -S / --strip-debug } ,
217+ flag ! { --shared } . nonstandard ( ) ,
218+ flag ! { --soname=VALUE } . nonstandard ( ) ,
219+ flag ! { --stack-first } . nonstandard ( ) ,
220+ flag ! { --start-lib } . nonstandard ( ) ,
221+ flag ! { --static } . nonstandard ( ) ,
222+ flag ! { -s / --strip-all } . nonstandard ( ) ,
223+ flag ! { -S / --strip-debug } . nonstandard ( ) ,
211224 flag ! { --table-base=VALUE } ,
212225 flag ! { --thinlto-cache-dir=PATH } ,
213226 flag ! { --thinlto-cache-policy=VALUE } ,
214227 flag ! { --thinlto-jobs=N } ,
215- flag ! { --threads=N } ,
216- flag ! { -y / --trace-symbol=SYM } ,
217- flag ! { -t / --trace } ,
218- flag ! { --undefined=SYM } ,
219- flag ! { --unresolved-symbols=VALUE } ,
220- flag ! { --warn-unresolved-symbols } ,
221- flag ! { --whole-archive } ,
228+ flag ! { --threads=N } . nonstandard ( ) ,
229+ flag ! { -y / --trace-symbol=SYM } . nonstandard ( ) ,
230+ flag ! { -t / --trace } . nonstandard ( ) ,
231+ flag ! { --undefined=SYM } . nonstandard ( ) ,
232+ flag ! { --unresolved-symbols=VALUE } . nonstandard ( ) ,
233+ flag ! { --warn-unresolved-symbols } . nonstandard ( ) ,
234+ flag ! { --whole-archive } . nonstandard ( ) ,
222235 flag ! { --why-extract=MEMBER } ,
223- flag ! { --wrap=VALUE } ,
236+ flag ! { --wrap=VALUE } . nonstandard ( ) ,
224237 flag ! { -z OPT } ,
225238] ;
226239
227- const LLD_LONG_FLAGS_NONSTANDARD : & [ & str ] = & [ "-shared" ] ;
228-
229240#[ derive( Default ) ]
230241struct App {
231242 component : ComponentLdArgs ,
232243 lld_args : Vec < OsString > ,
233- shared : bool ,
234244}
235245
236246/// A linker to create a Component from input object files and libraries.
@@ -442,7 +452,6 @@ impl App {
442452 let mut command = ComponentLdArgs :: command ( ) ;
443453 let mut lld_args = Vec :: new ( ) ;
444454 let mut component_ld_args = vec ! [ std:: env:: args_os( ) . nth( 0 ) . unwrap( ) ] ;
445- let mut shared = false ;
446455 let mut parser = lexopt:: Parser :: from_iter ( args) ;
447456
448457 fn handle_lld_arg (
@@ -497,14 +506,31 @@ impl App {
497506 loop {
498507 if let Some ( mut args) = parser. try_raw_args ( ) {
499508 if let Some ( arg) = args. peek ( ) {
500- let for_lld = LLD_LONG_FLAGS_NONSTANDARD . iter ( ) . any ( |s| arg == * s) ;
501- if for_lld {
502- lld_args. push ( arg. to_owned ( ) ) ;
503- if arg == "-shared" {
504- shared = true ;
509+ // If this is a `-...` flag then check to see if this is a
510+ // "nonstandard" flag like `-shared`. That's done by
511+ // looking at all `nonstandard` flags and testing if the
512+ // option is `-name...`. If so, then assume it's a nonstandard
513+ // flag and give it to LLD then move on.
514+ //
515+ // Note that if any flag has a value it'll get passed to
516+ // LLD below in `Arg::Value`, and otherwise if the option
517+ // has an embedded `=` in it that'll be handled here via
518+ // the `starts_with` check.
519+ //
520+ // Also note that `--foo` flags are all auto-skipped here
521+ // since the `starts_with` check won't pass for any of them
522+ // as `f.long` never starts with `-`.
523+ if let Some ( flag) = arg. strip_prefix ( "-" ) {
524+ let for_lld = LLD_FLAGS
525+ . iter ( )
526+ . filter ( |f| f. nonstandard )
527+ . filter_map ( |f| f. long )
528+ . any ( |f| flag. starts_with ( f) ) ;
529+ if for_lld {
530+ lld_args. push ( arg. to_owned ( ) ) ;
531+ args. next ( ) ;
532+ continue ;
505533 }
506- args. next ( ) ;
507- continue ;
508534 }
509535 }
510536 }
@@ -555,7 +581,6 @@ impl App {
555581 Ok ( matches) => Ok ( App {
556582 component : ComponentLdArgs :: from_arg_matches ( & matches) ?,
557583 lld_args,
558- shared,
559584 } ) ,
560585 Err ( _) => {
561586 add_wasm_ld_options ( ComponentLdArgs :: command ( ) ) . get_matches_from ( component_ld_args) ;
@@ -716,7 +741,7 @@ impl App {
716741 self . component . skip_wit_component
717742 // Skip componentization with `--shared` since that's creating a
718743 // shared library that's not a component yet.
719- || self . shared
744+ || self . lld_args . iter ( ) . any ( |s| s == "- shared" || s == "--shared" )
720745 }
721746
722747 fn lld ( & self ) -> Lld {
0 commit comments