@@ -12,6 +12,8 @@ use std::fs;
1212use  std:: path:: PathBuf ; 
1313use  std:: sync:: OnceLock ; 
1414
15+ use  build_helper:: ci:: CiEnv ; 
16+ 
1517use  crate :: Kind ; 
1618use  crate :: core:: builder:: { Builder ,  RunConfig ,  ShouldRun ,  Step } ; 
1719use  crate :: core:: config:: TargetSelection ; 
@@ -112,16 +114,60 @@ impl Step for Gcc {
112114            return  true ; 
113115        } 
114116
115-         command ( root. join ( "contrib/download_prerequisites" ) ) . current_dir ( & root) . run ( builder) ; 
116-         command ( root. join ( "configure" ) ) 
117+         // GCC creates files (e.g. symlinks to the downloaded dependencies) 
118+         // in the source directory, which does not work with our CI setup, where we mount 
119+         // source directories as read-only on Linux. 
120+         // Therefore, as a part of the build in CI, we first copy the whole source directory 
121+         // to the build directory, and perform the build from there. 
122+         let  src_dir = if  CiEnv :: is_ci ( )  { 
123+             let  src_dir = builder. gcc_out ( target) . join ( "src" ) ; 
124+             if  src_dir. exists ( )  { 
125+                 builder. remove_dir ( & src_dir) ; 
126+             } 
127+             builder. create_dir ( & src_dir) ; 
128+             builder. cp_link_r ( & root,  & src_dir) ; 
129+             src_dir
130+         }  else  { 
131+             root
132+         } ; 
133+ 
134+         command ( src_dir. join ( "contrib/download_prerequisites" ) ) . current_dir ( & src_dir) . run ( builder) ; 
135+         let  mut  configure_cmd = command ( src_dir. join ( "configure" ) ) ; 
136+         configure_cmd
117137            . current_dir ( & out_dir) 
138+             // On CI, we compile GCC with Clang. 
139+             // The -Wno-everything flag is needed to make GCC compile with Clang 19. 
140+             // `-g -O2` are the default flags that are otherwise used by Make. 
141+             // FIXME(kobzol): change the flags once we have [gcc] configuration in config.toml. 
142+             . env ( "CXXFLAGS" ,  "-Wno-everything -g -O2" ) 
143+             . env ( "CFLAGS" ,  "-Wno-everything -g -O2" ) 
118144            . arg ( "--enable-host-shared" ) 
119145            . arg ( "--enable-languages=jit" ) 
120146            . arg ( "--enable-checking=release" ) 
121147            . arg ( "--disable-bootstrap" ) 
122148            . arg ( "--disable-multilib" ) 
123-             . arg ( format ! ( "--prefix={}" ,  install_dir. display( ) ) ) 
124-             . run ( builder) ; 
149+             . arg ( format ! ( "--prefix={}" ,  install_dir. display( ) ) ) ; 
150+         let  cc = builder. build . cc ( target) . display ( ) . to_string ( ) ; 
151+         let  cc = builder
152+             . build 
153+             . config 
154+             . ccache 
155+             . as_ref ( ) 
156+             . map_or_else ( || cc. clone ( ) ,  |ccache| format ! ( "{ccache} {cc}" ) ) ; 
157+         configure_cmd. env ( "CC" ,  cc) ; 
158+ 
159+         if  let  Ok ( ref  cxx)  = builder. build . cxx ( target)  { 
160+             let  cxx = cxx. display ( ) . to_string ( ) ; 
161+             let  cxx = builder
162+                 . build 
163+                 . config 
164+                 . ccache 
165+                 . as_ref ( ) 
166+                 . map_or_else ( || cxx. clone ( ) ,  |ccache| format ! ( "{ccache} {cxx}" ) ) ; 
167+             configure_cmd. env ( "CXX" ,  cxx) ; 
168+         } 
169+         configure_cmd. run ( builder) ; 
170+ 
125171        command ( "make" ) . current_dir ( & out_dir) . arg ( format ! ( "-j{}" ,  builder. jobs( ) ) ) . run ( builder) ; 
126172        command ( "make" ) . current_dir ( & out_dir) . arg ( "install" ) . run ( builder) ; 
127173
0 commit comments