9
9
//! ensure that they're always in place if needed.
10
10
11
11
use std:: fs;
12
- use std:: path:: PathBuf ;
12
+ use std:: path:: { Path , PathBuf } ;
13
13
use std:: sync:: OnceLock ;
14
14
15
15
use build_helper:: ci:: CiEnv ;
16
16
17
17
use crate :: Kind ;
18
- use crate :: core:: builder:: { Builder , RunConfig , ShouldRun , Step } ;
18
+ use crate :: core:: builder:: { Builder , Cargo , RunConfig , ShouldRun , Step } ;
19
19
use crate :: core:: config:: TargetSelection ;
20
20
use crate :: utils:: build_stamp:: { BuildStamp , generate_smart_stamp_hash} ;
21
21
use crate :: utils:: exec:: command;
@@ -29,7 +29,8 @@ pub struct Meta {
29
29
}
30
30
31
31
pub enum GccBuildStatus {
32
- AlreadyBuilt ,
32
+ /// libgccjit is already built at this path
33
+ AlreadyBuilt ( PathBuf ) ,
33
34
ShouldBuild ( Meta ) ,
34
35
}
35
36
@@ -41,9 +42,6 @@ pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> Gc
41
42
// Initialize the gcc submodule if not initialized already.
42
43
builder. config . update_submodule ( "src/gcc" ) ;
43
44
44
- // FIXME (GuillaumeGomez): To be done once gccjit has been built in the CI.
45
- // builder.config.maybe_download_ci_gcc();
46
-
47
45
let root = builder. src . join ( "src/gcc" ) ;
48
46
let out_dir = builder. gcc_out ( target) . join ( "build" ) ;
49
47
let install_dir = builder. gcc_out ( target) . join ( "install" ) ;
@@ -70,19 +68,37 @@ pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> Gc
70
68
stamp. path( ) . display( )
71
69
) ) ;
72
70
}
73
- return GccBuildStatus :: AlreadyBuilt ;
71
+ let path = libgccjit_built_path ( & install_dir) ;
72
+ if path. is_file ( ) {
73
+ return GccBuildStatus :: AlreadyBuilt ( path) ;
74
+ } else {
75
+ builder. info ( & format ! (
76
+ "GCC stamp is up-to-date, but the libgccjit.so file was not found at `{}`" ,
77
+ path. display( ) ,
78
+ ) ) ;
79
+ }
74
80
}
75
81
76
82
GccBuildStatus :: ShouldBuild ( Meta { stamp, out_dir, install_dir, root } )
77
83
}
78
84
85
+ /// Returns the path to a libgccjit.so file in the install directory of GCC.
86
+ fn libgccjit_built_path ( install_dir : & Path ) -> PathBuf {
87
+ install_dir. join ( "lib/libgccjit.so" )
88
+ }
89
+
79
90
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
80
91
pub struct Gcc {
81
92
pub target : TargetSelection ,
82
93
}
83
94
95
+ #[ derive( Clone ) ]
96
+ pub struct GccOutput {
97
+ pub libgccjit : PathBuf ,
98
+ }
99
+
84
100
impl Step for Gcc {
85
- type Output = bool ;
101
+ type Output = GccOutput ;
86
102
87
103
const ONLY_HOSTS : bool = true ;
88
104
@@ -94,14 +110,14 @@ impl Step for Gcc {
94
110
run. builder . ensure ( Gcc { target : run. target } ) ;
95
111
}
96
112
97
- /// Compile GCC for `target`.
98
- fn run ( self , builder : & Builder < ' _ > ) -> bool {
113
+ /// Compile GCC (specifically `libgccjit`) for `target`.
114
+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
99
115
let target = self . target ;
100
116
101
117
// If GCC has already been built, we avoid building it again.
102
118
let Meta { stamp, out_dir, install_dir, root } = match prebuilt_gcc_config ( builder, target)
103
119
{
104
- GccBuildStatus :: AlreadyBuilt => return true ,
120
+ GccBuildStatus :: AlreadyBuilt ( path ) => return GccOutput { libgccjit : path } ,
105
121
GccBuildStatus :: ShouldBuild ( m) => m,
106
122
} ;
107
123
@@ -110,8 +126,9 @@ impl Step for Gcc {
110
126
let _time = helpers:: timeit ( builder) ;
111
127
t ! ( fs:: create_dir_all( & out_dir) ) ;
112
128
129
+ let libgccjit_path = libgccjit_built_path ( & install_dir) ;
113
130
if builder. config . dry_run ( ) {
114
- return true ;
131
+ return GccOutput { libgccjit : libgccjit_path } ;
115
132
}
116
133
117
134
// GCC creates files (e.g. symlinks to the downloaded dependencies)
@@ -173,11 +190,17 @@ impl Step for Gcc {
173
190
174
191
let lib_alias = install_dir. join ( "lib/libgccjit.so.0" ) ;
175
192
if !lib_alias. exists ( ) {
176
- t ! ( builder. symlink_file( install_dir . join ( "lib/libgccjit.so" ) , lib_alias, ) ) ;
193
+ t ! ( builder. symlink_file( & libgccjit_path , lib_alias) ) ;
177
194
}
178
195
179
196
t ! ( stamp. write( ) ) ;
180
197
181
- true
198
+ GccOutput { libgccjit : libgccjit_path }
182
199
}
183
200
}
201
+
202
+ /// Configures a Cargo invocation so that it can build the GCC codegen backend.
203
+ pub fn add_cg_gcc_cargo_flags ( cargo : & mut Cargo , gcc : & GccOutput ) {
204
+ // Add the path to libgccjit.so to the linker search paths.
205
+ cargo. rustflag ( & format ! ( "-L{}" , gcc. libgccjit. parent( ) . unwrap( ) . display( ) ) ) ;
206
+ }
0 commit comments