@@ -24,9 +24,18 @@ use crate::util::get_clang_cl_resource_dir;
24
24
use crate :: util:: { self , exe, output, t, up_to_date} ;
25
25
use crate :: { CLang , GitRepo } ;
26
26
27
+ #[ derive( Clone ) ]
28
+ pub struct LlvmResult {
29
+ /// Path to llvm-config binary.
30
+ /// NB: This is always the host llvm-config!
31
+ pub llvm_config : PathBuf ,
32
+ /// Path to LLVM cmake directory for the target.
33
+ pub llvm_cmake_dir : PathBuf ,
34
+ }
35
+
27
36
pub struct Meta {
28
37
stamp : HashStamp ,
29
- build_llvm_config : PathBuf ,
38
+ res : LlvmResult ,
30
39
out_dir : PathBuf ,
31
40
root : String ,
32
41
}
@@ -64,15 +73,22 @@ impl LdFlags {
64
73
pub fn prebuilt_llvm_config (
65
74
builder : & Builder < ' _ > ,
66
75
target : TargetSelection ,
67
- ) -> Result < PathBuf , Meta > {
76
+ ) -> Result < LlvmResult , Meta > {
68
77
builder. config . maybe_download_ci_llvm ( ) ;
69
78
70
79
// If we're using a custom LLVM bail out here, but we can only use a
71
80
// custom LLVM for the build triple.
72
81
if let Some ( config) = builder. config . target_config . get ( & target) {
73
82
if let Some ( ref s) = config. llvm_config {
74
83
check_llvm_version ( builder, s) ;
75
- return Ok ( s. to_path_buf ( ) ) ;
84
+ let llvm_config = s. to_path_buf ( ) ;
85
+ let mut llvm_cmake_dir = llvm_config. clone ( ) ;
86
+ llvm_cmake_dir. pop ( ) ;
87
+ llvm_cmake_dir. pop ( ) ;
88
+ llvm_cmake_dir. push ( "lib" ) ;
89
+ llvm_cmake_dir. push ( "cmake" ) ;
90
+ llvm_cmake_dir. push ( "llvm" ) ;
91
+ return Ok ( LlvmResult { llvm_config, llvm_cmake_dir } ) ;
76
92
}
77
93
}
78
94
@@ -84,8 +100,9 @@ pub fn prebuilt_llvm_config(
84
100
llvm_config_ret_dir. push ( "build" ) ;
85
101
}
86
102
llvm_config_ret_dir. push ( "bin" ) ;
87
-
88
103
let build_llvm_config = llvm_config_ret_dir. join ( exe ( "llvm-config" , builder. config . build ) ) ;
104
+ let llvm_cmake_dir = out_dir. join ( "lib/cmake/llvm" ) ;
105
+ let res = LlvmResult { llvm_config : build_llvm_config, llvm_cmake_dir } ;
89
106
90
107
let stamp = out_dir. join ( "llvm-finished-building" ) ;
91
108
let stamp = HashStamp :: new ( stamp, builder. in_tree_llvm_info . sha ( ) ) ;
@@ -96,7 +113,7 @@ pub fn prebuilt_llvm_config(
96
113
Using a potentially stale build of LLVM; \
97
114
This may not behave well.",
98
115
) ;
99
- return Ok ( build_llvm_config ) ;
116
+ return Ok ( res ) ;
100
117
}
101
118
102
119
if stamp. is_done ( ) {
@@ -110,10 +127,10 @@ pub fn prebuilt_llvm_config(
110
127
stamp. path. display( )
111
128
) ) ;
112
129
}
113
- return Ok ( build_llvm_config ) ;
130
+ return Ok ( res ) ;
114
131
}
115
132
116
- Err ( Meta { stamp, build_llvm_config , out_dir, root : root. into ( ) } )
133
+ Err ( Meta { stamp, res , out_dir, root : root. into ( ) } )
117
134
}
118
135
119
136
/// This retrieves the LLVM sha we *want* to use, according to git history.
@@ -223,7 +240,7 @@ pub struct Llvm {
223
240
}
224
241
225
242
impl Step for Llvm {
226
- type Output = PathBuf ; // path to llvm-config
243
+ type Output = LlvmResult ;
227
244
228
245
const ONLY_HOSTS : bool = true ;
229
246
@@ -236,7 +253,7 @@ impl Step for Llvm {
236
253
}
237
254
238
255
/// Compile LLVM for `target`.
239
- fn run ( self , builder : & Builder < ' _ > ) -> PathBuf {
256
+ fn run ( self , builder : & Builder < ' _ > ) -> LlvmResult {
240
257
let target = self . target ;
241
258
let target_native = if self . target . starts_with ( "riscv" ) {
242
259
// RISC-V target triples in Rust is not named the same as C compiler target triples.
@@ -252,11 +269,10 @@ impl Step for Llvm {
252
269
target. to_string ( )
253
270
} ;
254
271
255
- let Meta { stamp, build_llvm_config, out_dir, root } =
256
- match prebuilt_llvm_config ( builder, target) {
257
- Ok ( p) => return p,
258
- Err ( m) => m,
259
- } ;
272
+ let Meta { stamp, res, out_dir, root } = match prebuilt_llvm_config ( builder, target) {
273
+ Ok ( p) => return p,
274
+ Err ( m) => m,
275
+ } ;
260
276
261
277
builder. update_submodule ( & Path :: new ( "src" ) . join ( "llvm-project" ) ) ;
262
278
if builder. llvm_link_shared ( ) && target. contains ( "windows" ) {
@@ -430,7 +446,8 @@ impl Step for Llvm {
430
446
431
447
// https://llvm.org/docs/HowToCrossCompileLLVM.html
432
448
if target != builder. config . build {
433
- let llvm_config = builder. ensure ( Llvm { target : builder. config . build } ) ;
449
+ let LlvmResult { llvm_config, .. } =
450
+ builder. ensure ( Llvm { target : builder. config . build } ) ;
434
451
if !builder. config . dry_run ( ) {
435
452
let llvm_bindir = output ( Command :: new ( & llvm_config) . arg ( "--bindir" ) ) ;
436
453
let host_bin = Path :: new ( llvm_bindir. trim ( ) ) ;
@@ -480,7 +497,7 @@ impl Step for Llvm {
480
497
// tools and libs on all platforms.
481
498
482
499
if builder. config . dry_run ( ) {
483
- return build_llvm_config ;
500
+ return res ;
484
501
}
485
502
486
503
cfg. build ( ) ;
@@ -490,7 +507,7 @@ impl Step for Llvm {
490
507
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
491
508
// link to make llvm-config happy.
492
509
if builder. llvm_link_shared ( ) && target. contains ( "apple-darwin" ) {
493
- let mut cmd = Command :: new ( & build_llvm_config ) ;
510
+ let mut cmd = Command :: new ( & res . llvm_config ) ;
494
511
let version = output ( cmd. arg ( "--version" ) ) ;
495
512
let major = version. split ( '.' ) . next ( ) . unwrap ( ) ;
496
513
let lib_name = match llvm_version_suffix {
@@ -509,18 +526,18 @@ impl Step for Llvm {
509
526
// LLVM after a configuration change, so to rebuild it the build files have to be removed,
510
527
// which will also remove these modified files.
511
528
if builder. config . llvm_bolt_profile_generate {
512
- instrument_with_bolt_inplace ( & get_built_llvm_lib_path ( & build_llvm_config ) ) ;
529
+ instrument_with_bolt_inplace ( & get_built_llvm_lib_path ( & res . llvm_config ) ) ;
513
530
}
514
531
if let Some ( path) = & builder. config . llvm_bolt_profile_use {
515
532
optimize_library_with_bolt_inplace (
516
- & get_built_llvm_lib_path ( & build_llvm_config ) ,
533
+ & get_built_llvm_lib_path ( & res . llvm_config ) ,
517
534
& Path :: new ( path) ,
518
535
) ;
519
536
}
520
537
521
538
t ! ( stamp. write( ) ) ;
522
539
523
- build_llvm_config
540
+ res
524
541
}
525
542
}
526
543
@@ -806,7 +823,8 @@ impl Step for Lld {
806
823
}
807
824
let target = self . target ;
808
825
809
- let llvm_config = builder. ensure ( Llvm { target : self . target } ) ;
826
+ let LlvmResult { llvm_config, llvm_cmake_dir } =
827
+ builder. ensure ( Llvm { target : self . target } ) ;
810
828
811
829
let out_dir = builder. lld_out ( target) ;
812
830
let done_stamp = out_dir. join ( "lld-finished-building" ) ;
@@ -837,22 +855,6 @@ impl Step for Lld {
837
855
configure_cmake ( builder, target, & mut cfg, true , ldflags) ;
838
856
configure_llvm ( builder, target, & mut cfg) ;
839
857
840
- // This is an awful, awful hack. Discovered when we migrated to using
841
- // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
842
- // tree, will execute `llvm-config --cmakedir` and then tell CMake about
843
- // that directory for later processing. Unfortunately if this path has
844
- // forward slashes in it (which it basically always does on Windows)
845
- // then CMake will hit a syntax error later on as... something isn't
846
- // escaped it seems?
847
- //
848
- // Instead of attempting to fix this problem in upstream CMake and/or
849
- // LLVM/LLD we just hack around it here. This thin wrapper will take the
850
- // output from llvm-config and replace all instances of `\` with `/` to
851
- // ensure we don't hit the same bugs with escaping. It means that you
852
- // can't build on a system where your paths require `\` on Windows, but
853
- // there's probably a lot of reasons you can't do that other than this.
854
- let llvm_config_shim = env:: current_exe ( ) . unwrap ( ) . with_file_name ( "llvm-config-wrapper" ) ;
855
-
856
858
// Re-use the same flags as llvm to control the level of debug information
857
859
// generated for lld.
858
860
let profile = match ( builder. config . llvm_optimize , builder. config . llvm_release_debuginfo ) {
@@ -863,36 +865,17 @@ impl Step for Lld {
863
865
864
866
cfg. out_dir ( & out_dir)
865
867
. profile ( profile)
866
- . env ( "LLVM_CONFIG_REAL" , & llvm_config)
867
- . define ( "LLVM_CONFIG_PATH" , llvm_config_shim)
868
+ . define ( "LLVM_CMAKE_DIR" , llvm_cmake_dir)
868
869
. define ( "LLVM_INCLUDE_TESTS" , "OFF" ) ;
869
870
870
- // While we're using this horrible workaround to shim the execution of
871
- // llvm-config, let's just pile on more. I can't seem to figure out how
872
- // to build LLD as a standalone project and also cross-compile it at the
873
- // same time. It wants a natively executable `llvm-config` to learn
874
- // about LLVM, but then it learns about all the host configuration of
875
- // LLVM and tries to link to host LLVM libraries.
876
- //
877
- // To work around that we tell our shim to replace anything with the
878
- // build target with the actual target instead. This'll break parts of
879
- // LLD though which try to execute host tools, such as llvm-tblgen, so
880
- // we specifically tell it where to find those. This is likely super
881
- // brittle and will break over time. If anyone knows better how to
882
- // cross-compile LLD it would be much appreciated to fix this!
883
871
if target != builder. config . build {
884
- cfg. env ( "LLVM_CONFIG_SHIM_REPLACE" , & builder. config . build . triple )
885
- . env ( "LLVM_CONFIG_SHIM_REPLACE_WITH" , & target. triple )
886
- . define (
887
- "LLVM_TABLEGEN_EXE" ,
888
- llvm_config. with_file_name ( "llvm-tblgen" ) . with_extension ( EXE_EXTENSION ) ,
889
- ) ;
872
+ // Use the host llvm-tblgen binary.
873
+ cfg. define (
874
+ "LLVM_TABLEGEN_EXE" ,
875
+ llvm_config. with_file_name ( "llvm-tblgen" ) . with_extension ( EXE_EXTENSION ) ,
876
+ ) ;
890
877
}
891
878
892
- // Explicitly set C++ standard, because upstream doesn't do so
893
- // for standalone builds.
894
- cfg. define ( "CMAKE_CXX_STANDARD" , "14" ) ;
895
-
896
879
cfg. build ( ) ;
897
880
898
881
t ! ( File :: create( & done_stamp) ) ;
@@ -994,7 +977,7 @@ impl Step for Sanitizers {
994
977
return runtimes;
995
978
}
996
979
997
- let llvm_config = builder. ensure ( Llvm { target : builder. config . build } ) ;
980
+ let LlvmResult { llvm_config, .. } = builder. ensure ( Llvm { target : builder. config . build } ) ;
998
981
if builder. config . dry_run ( ) {
999
982
return runtimes;
1000
983
}
0 commit comments