@@ -26,7 +26,11 @@ pub struct Gcc {
2626
2727#[ derive( Clone ) ]
2828pub struct GccOutput {
29- pub libgccjit : PathBuf ,
29+ /// Path to a built or downloaded libgccjit.
30+ /// Is None when setting libgccjit-libs-dir.
31+ /// FIXME: it seems wrong to make this an Option.
32+ /// Perhaps it should be a Vec so that we can install all libs from libgccjit-libs-dir?
33+ pub libgccjit : Option < PathBuf > ,
3034}
3135
3236impl GccOutput {
@@ -36,23 +40,25 @@ impl GccOutput {
3640 return ;
3741 }
3842
39- // At build time, cg_gcc has to link to libgccjit.so (the unversioned symbol).
40- // However, at runtime, it will by default look for libgccjit.so.0.
41- // So when we install the built libgccjit.so file to the target `directory`, we add it there
42- // with the `.0` suffix.
43- let mut target_filename = self . libgccjit . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ;
44- target_filename. push_str ( ".0" ) ;
45-
46- // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.
47- // In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink,
48- // which wouldn't work.
49- let actual_libgccjit_path = t ! (
50- self . libgccjit. canonicalize( ) ,
51- format!( "Cannot find libgccjit at {}" , self . libgccjit. display( ) )
52- ) ;
43+ if let Some ( ref path) = self . libgccjit {
44+ // At build time, cg_gcc has to link to libgccjit.so (the unversioned symbol).
45+ // However, at runtime, it will by default look for libgccjit.so.0.
46+ // So when we install the built libgccjit.so file to the target `directory`, we add it there
47+ // with the `.0` suffix.
48+ let mut target_filename = path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ;
49+ target_filename. push_str ( ".0" ) ;
50+
51+ // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.
52+ // In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink,
53+ // which wouldn't work.
54+ let actual_libgccjit_path = t ! (
55+ path. canonicalize( ) ,
56+ format!( "Cannot find libgccjit at {}" , path. display( ) )
57+ ) ;
5358
54- let dst = directory. join ( & target_filename) ;
55- builder. copy_link ( & actual_libgccjit_path, & dst, FileType :: NativeLibrary ) ;
59+ let dst = directory. join ( & target_filename) ;
60+ builder. copy_link ( & actual_libgccjit_path, & dst, FileType :: NativeLibrary ) ;
61+ }
5662
5763 if let Some ( ref path) = builder. config . libgccjit_libs_dir {
5864 let host_target = builder. config . host_target . triple ;
@@ -64,13 +70,14 @@ impl GccOutput {
6470 . map ( |target| target. triple )
6571 . chain ( std:: iter:: once ( host_target) ) ;
6672
73+ let target_filename = "libgccjit.so.0" ;
6774 for target in targets {
68- let source = source. join ( target) . join ( & target_filename) ;
75+ let source = source. join ( target) . join ( target_filename) ;
6976 // To support symlinks in libgccjit-libs-dir, we have to resolve it first,
7077 // otherwise we'd create a symlink to a symlink, which wouldn't work.
7178 let actual_libgccjit_path = t ! (
7279 source. canonicalize( ) ,
73- format!( "Cannot find libgccjit at {}" , self . libgccjit . display( ) )
80+ format!( "Cannot find libgccjit at {}" , source . display( ) )
7481 ) ;
7582 let target_dir = dst. join ( target) ;
7683 t ! (
@@ -104,7 +111,8 @@ impl Step for Gcc {
104111
105112 // If GCC has already been built, we avoid building it again.
106113 let metadata = match get_gcc_build_status ( builder, target) {
107- GccBuildStatus :: AlreadyBuilt ( path) => return GccOutput { libgccjit : path } ,
114+ GccBuildStatus :: AlreadyBuilt ( path) => return GccOutput { libgccjit : Some ( path) } ,
115+ GccBuildStatus :: InLibsDir => return GccOutput { libgccjit : None } ,
108116 GccBuildStatus :: ShouldBuild ( m) => m,
109117 } ;
110118
@@ -114,14 +122,14 @@ impl Step for Gcc {
114122
115123 let libgccjit_path = libgccjit_built_path ( & metadata. install_dir ) ;
116124 if builder. config . dry_run ( ) {
117- return GccOutput { libgccjit : libgccjit_path } ;
125+ return GccOutput { libgccjit : Some ( libgccjit_path) } ;
118126 }
119127
120128 build_gcc ( & metadata, builder, target) ;
121129
122130 t ! ( metadata. stamp. write( ) ) ;
123131
124- GccOutput { libgccjit : libgccjit_path }
132+ GccOutput { libgccjit : Some ( libgccjit_path) }
125133 }
126134}
127135
@@ -135,6 +143,7 @@ pub struct Meta {
135143pub enum GccBuildStatus {
136144 /// libgccjit is already built at this path
137145 AlreadyBuilt ( PathBuf ) ,
146+ InLibsDir ,
138147 ShouldBuild ( Meta ) ,
139148}
140149
@@ -199,6 +208,11 @@ fn try_download_gcc(_builder: &Builder<'_>, _target: TargetSelection) -> Option<
199208/// It's used to avoid busting caches during x.py check -- if we've already built
200209/// GCC, it's fine for us to not try to avoid doing so.
201210pub fn get_gcc_build_status ( builder : & Builder < ' _ > , target : TargetSelection ) -> GccBuildStatus {
211+ if matches ! ( builder. config. gcc_ci_mode, crate :: core:: config:: GccCiMode :: CopyFromLibsDir ) {
212+ // TODO: check if this is OK.
213+ return GccBuildStatus :: InLibsDir ;
214+ }
215+
202216 if let Some ( path) = try_download_gcc ( builder, target) {
203217 return GccBuildStatus :: AlreadyBuilt ( path) ;
204218 }
@@ -322,7 +336,9 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
322336/// Configures a Cargo invocation so that it can build the GCC codegen backend.
323337pub fn add_cg_gcc_cargo_flags ( cargo : & mut Cargo , gcc : & GccOutput ) {
324338 // Add the path to libgccjit.so to the linker search paths.
325- cargo. rustflag ( & format ! ( "-L{}" , gcc. libgccjit. parent( ) . unwrap( ) . to_str( ) . unwrap( ) ) ) ;
339+ if let Some ( ref path) = gcc. libgccjit {
340+ cargo. rustflag ( & format ! ( "-L{}" , path. parent( ) . unwrap( ) . to_str( ) . unwrap( ) ) ) ;
341+ }
326342}
327343
328344/// The absolute path to the downloaded GCC artifacts.
0 commit comments