4040//! but not gcc's. As a result rustc cannot link with C++ static libraries (#36710)
4141//! when linking in self-contained mode.
4242
43- use crate :: spec:: LinkOutputKind ;
43+ use crate :: spec:: { LinkOutputKind , MaybeLazy } ;
4444use std:: borrow:: Cow ;
4545use std:: collections:: BTreeMap ;
4646
47+ type LazyCrtObjectsArgs = & ' static [ ( LinkOutputKind , & ' static [ & ' static str ] ) ] ;
48+ pub struct LazyCrtObjectsState ( LazyCrtObjectsArgs ) ;
49+
50+ impl FnOnce < ( ) > for LazyCrtObjectsState {
51+ type Output = CrtObjects ;
52+ extern "rust-call" fn call_once ( self , _args : ( ) ) -> Self :: Output {
53+ self . 0 . iter ( ) . map ( |( z, k) | ( * z, k. iter ( ) . map ( |b| ( * b) . into ( ) ) . collect ( ) ) ) . collect ( )
54+ }
55+ }
56+
4757pub type CrtObjects = BTreeMap < LinkOutputKind , Vec < Cow < ' static , str > > > ;
58+ pub type LazyCrtObjects = MaybeLazy < CrtObjects , LazyCrtObjectsState > ;
4859
49- pub ( super ) fn new ( obj_table : & [ ( LinkOutputKind , & [ & ' static str ] ) ] ) -> CrtObjects {
50- obj_table. iter ( ) . map ( |( z, k) | ( * z, k. iter ( ) . map ( |b| ( * b) . into ( ) ) . collect ( ) ) ) . collect ( )
60+ #[ inline]
61+ pub ( super ) fn new ( obj_table : LazyCrtObjectsArgs ) -> LazyCrtObjects {
62+ MaybeLazy :: lazied ( LazyCrtObjectsState ( obj_table) )
5163}
5264
53- pub ( super ) fn all ( obj : & ' static str ) -> CrtObjects {
54- new ( & [
55- ( LinkOutputKind :: DynamicNoPicExe , & [ obj] ) ,
56- ( LinkOutputKind :: DynamicPicExe , & [ obj] ) ,
57- ( LinkOutputKind :: StaticNoPicExe , & [ obj] ) ,
58- ( LinkOutputKind :: StaticPicExe , & [ obj] ) ,
59- ( LinkOutputKind :: DynamicDylib , & [ obj] ) ,
60- ( LinkOutputKind :: StaticDylib , & [ obj] ) ,
61- ] )
65+ macro_rules! all {
66+ ( $obj: literal) => {
67+ new( & [
68+ ( LinkOutputKind :: DynamicNoPicExe , & [ $obj] ) ,
69+ ( LinkOutputKind :: DynamicPicExe , & [ $obj] ) ,
70+ ( LinkOutputKind :: StaticNoPicExe , & [ $obj] ) ,
71+ ( LinkOutputKind :: StaticPicExe , & [ $obj] ) ,
72+ ( LinkOutputKind :: DynamicDylib , & [ $obj] ) ,
73+ ( LinkOutputKind :: StaticDylib , & [ $obj] ) ,
74+ ] )
75+ } ;
6276}
6377
64- pub ( super ) fn pre_musl_self_contained ( ) -> CrtObjects {
78+ pub ( super ) fn pre_musl_self_contained ( ) -> LazyCrtObjects {
6579 new ( & [
6680 ( LinkOutputKind :: DynamicNoPicExe , & [ "crt1.o" , "crti.o" , "crtbegin.o" ] ) ,
6781 ( LinkOutputKind :: DynamicPicExe , & [ "Scrt1.o" , "crti.o" , "crtbeginS.o" ] ) ,
@@ -72,7 +86,7 @@ pub(super) fn pre_musl_self_contained() -> CrtObjects {
7286 ] )
7387}
7488
75- pub ( super ) fn post_musl_self_contained ( ) -> CrtObjects {
89+ pub ( super ) fn post_musl_self_contained ( ) -> LazyCrtObjects {
7690 new ( & [
7791 ( LinkOutputKind :: DynamicNoPicExe , & [ "crtend.o" , "crtn.o" ] ) ,
7892 ( LinkOutputKind :: DynamicPicExe , & [ "crtendS.o" , "crtn.o" ] ) ,
@@ -83,7 +97,7 @@ pub(super) fn post_musl_self_contained() -> CrtObjects {
8397 ] )
8498}
8599
86- pub ( super ) fn pre_mingw_self_contained ( ) -> CrtObjects {
100+ pub ( super ) fn pre_mingw_self_contained ( ) -> LazyCrtObjects {
87101 new ( & [
88102 ( LinkOutputKind :: DynamicNoPicExe , & [ "crt2.o" , "rsbegin.o" ] ) ,
89103 ( LinkOutputKind :: DynamicPicExe , & [ "crt2.o" , "rsbegin.o" ] ) ,
@@ -94,19 +108,19 @@ pub(super) fn pre_mingw_self_contained() -> CrtObjects {
94108 ] )
95109}
96110
97- pub ( super ) fn post_mingw_self_contained ( ) -> CrtObjects {
98- all ( "rsend.o" )
111+ pub ( super ) fn post_mingw_self_contained ( ) -> LazyCrtObjects {
112+ all ! ( "rsend.o" )
99113}
100114
101- pub ( super ) fn pre_mingw ( ) -> CrtObjects {
102- all ( "rsbegin.o" )
115+ pub ( super ) fn pre_mingw ( ) -> LazyCrtObjects {
116+ all ! ( "rsbegin.o" )
103117}
104118
105- pub ( super ) fn post_mingw ( ) -> CrtObjects {
106- all ( "rsend.o" )
119+ pub ( super ) fn post_mingw ( ) -> LazyCrtObjects {
120+ all ! ( "rsend.o" )
107121}
108122
109- pub ( super ) fn pre_wasi_self_contained ( ) -> CrtObjects {
123+ pub ( super ) fn pre_wasi_self_contained ( ) -> LazyCrtObjects {
110124 // Use crt1-command.o instead of crt1.o to enable support for new-style
111125 // commands. See https://reviews.llvm.org/D81689 for more info.
112126 new ( & [
@@ -118,6 +132,6 @@ pub(super) fn pre_wasi_self_contained() -> CrtObjects {
118132 ] )
119133}
120134
121- pub ( super ) fn post_wasi_self_contained ( ) -> CrtObjects {
135+ pub ( super ) fn post_wasi_self_contained ( ) -> LazyCrtObjects {
122136 new ( & [ ] )
123137}
0 commit comments