@@ -14,14 +14,72 @@ use std::sync::OnceLock;
14
14
15
15
use build_helper:: ci:: CiEnv ;
16
16
17
- use crate :: Kind ;
18
- use crate :: core:: builder:: { Builder , RunConfig , ShouldRun , Step } ;
19
17
use crate :: core:: builder:: { Builder , Cargo , Kind , RunConfig , ShouldRun , Step } ;
20
18
use crate :: core:: config:: TargetSelection ;
21
19
use crate :: utils:: build_stamp:: { BuildStamp , generate_smart_stamp_hash} ;
22
20
use crate :: utils:: exec:: command;
23
21
use crate :: utils:: helpers:: { self , t} ;
24
22
23
+ #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
24
+ pub struct Gcc {
25
+ pub target : TargetSelection ,
26
+ }
27
+
28
+ #[ derive( Clone ) ]
29
+ pub struct GccOutput {
30
+ pub libgccjit : PathBuf ,
31
+ }
32
+
33
+ impl Step for Gcc {
34
+ type Output = GccOutput ;
35
+
36
+ const ONLY_HOSTS : bool = true ;
37
+
38
+ fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
39
+ run. path ( "src/gcc" ) . alias ( "gcc" )
40
+ }
41
+
42
+ fn make_run ( run : RunConfig < ' _ > ) {
43
+ run. builder . ensure ( Gcc { target : run. target } ) ;
44
+ }
45
+
46
+ /// Compile GCC (specifically `libgccjit`) for `target`.
47
+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
48
+ let target = self . target ;
49
+
50
+ // If GCC has already been built, we avoid building it again.
51
+ let metadata = match get_gcc_build_status ( builder, target) {
52
+ GccBuildStatus :: AlreadyBuilt ( path) => return GccOutput { libgccjit : path } ,
53
+ GccBuildStatus :: ShouldBuild ( m) => m,
54
+ } ;
55
+
56
+ let _guard = builder. msg_unstaged ( Kind :: Build , "GCC" , target) ;
57
+ t ! ( metadata. stamp. remove( ) ) ;
58
+ let _time = helpers:: timeit ( builder) ;
59
+
60
+ let libgccjit_path = libgccjit_built_path ( & metadata. install_dir ) ;
61
+ if builder. config . dry_run ( ) {
62
+ return GccOutput { libgccjit : libgccjit_path } ;
63
+ }
64
+
65
+ build_gcc ( & metadata, builder, target) ;
66
+ create_lib_alias ( builder, & libgccjit_path) ;
67
+
68
+ t ! ( metadata. stamp. write( ) ) ;
69
+
70
+ GccOutput { libgccjit : libgccjit_path }
71
+ }
72
+ }
73
+
74
+ /// Creates a libgccjit.so.0 alias next to libgccjit.so if it does not
75
+ /// already exist
76
+ fn create_lib_alias ( builder : & Builder < ' _ > , libgccjit : & PathBuf ) {
77
+ let lib_alias = libgccjit. parent ( ) . unwrap ( ) . join ( "libgccjit.so.0" ) ;
78
+ if !lib_alias. exists ( ) {
79
+ t ! ( builder. symlink_file( libgccjit, lib_alias) ) ;
80
+ }
81
+ }
82
+
25
83
pub struct Meta {
26
84
stamp : BuildStamp ,
27
85
out_dir : PathBuf ,
@@ -39,6 +97,8 @@ pub enum GccBuildStatus {
39
97
/// Returns a path to the libgccjit.so file.
40
98
#[ cfg( not( test) ) ]
41
99
fn try_download_gcc ( builder : & Builder < ' _ > , target : TargetSelection ) -> Option < PathBuf > {
100
+ use build_helper:: git:: PathFreshness ;
101
+
42
102
// Try to download GCC from CI if configured and available
43
103
if !matches ! ( builder. config. gcc_ci_mode, crate :: core:: config:: GccCiMode :: DownloadFromCi ) {
44
104
return None ;
0 commit comments