@@ -548,20 +548,28 @@ mod c {
548548 sources. extend ( & [ ( "__emutls_get_address" , "emutls.c" ) ] ) ;
549549 }
550550
551+ // Optionally, link against a prebuilt compiler-rt library to supply
552+ // optimized intrinsics instead of compiling a subset of compiler-rt
553+ // from source.
554+ let link_against_prebuilt_rt = env:: var_os ( "LLVM_BUILTIN_RT_LIB" ) . is_some ( ) ;
555+
551556 // When compiling the C code we require the user to tell us where the
552557 // source code is, and this is largely done so when we're compiling as
553558 // part of rust-lang/rust we can use the same llvm-project repository as
554559 // rust-lang/rust.
555560 let root = match env:: var_os ( "RUST_COMPILER_RT_ROOT" ) {
556561 Some ( s) => PathBuf :: from ( s) ,
562+ // If a prebuild libcompiler-rt is provided, set a valid
563+ // path to simplify later logic. Nothing should be compiled.
564+ None if link_against_prebuilt_rt => PathBuf :: new ( ) ,
557565 None => {
558566 panic ! (
559567 "RUST_COMPILER_RT_ROOT is not set. You may need to run \
560568 `ci/download-compiler-rt.sh`."
561569 ) ;
562570 }
563571 } ;
564- if !root. exists ( ) {
572+ if !link_against_prebuilt_rt && ! root. exists ( ) {
565573 panic ! ( "RUST_COMPILER_RT_ROOT={} does not exist" , root. display( ) ) ;
566574 }
567575
@@ -577,7 +585,7 @@ mod c {
577585 let src_dir = root. join ( "lib/builtins" ) ;
578586 if target. arch == "aarch64" && target. env != "msvc" && target. os != "uefi" {
579587 // See below for why we're building these as separate libraries.
580- build_aarch64_out_of_line_atomics_libraries ( & src_dir, cfg) ;
588+ build_aarch64_out_of_line_atomics_libraries ( & src_dir, cfg, link_against_prebuilt_rt ) ;
581589
582590 // Some run-time CPU feature detection is necessary, as well.
583591 let cpu_model_src = if src_dir. join ( "cpu_model.c" ) . exists ( ) {
@@ -591,20 +599,43 @@ mod c {
591599 let mut added_sources = HashSet :: new ( ) ;
592600 for ( sym, src) in sources. map . iter ( ) {
593601 let src = src_dir. join ( src) ;
594- if added_sources. insert ( src. clone ( ) ) {
602+ if !link_against_prebuilt_rt && added_sources. insert ( src. clone ( ) ) {
595603 cfg. file ( & src) ;
596604 println ! ( "cargo:rerun-if-changed={}" , src. display( ) ) ;
597605 }
598606 println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " , sym) ;
599607 }
600608
601- cfg. compile ( "libcompiler-rt.a" ) ;
609+ if link_against_prebuilt_rt {
610+ let rt_builtins_ext = PathBuf :: from ( env:: var_os ( "LLVM_BUILTIN_RT_LIB" ) . unwrap ( ) ) ;
611+ if !rt_builtins_ext. exists ( ) {
612+ panic ! (
613+ "LLVM_BUILTIN_RT_LIB={} does not exist" ,
614+ rt_builtins_ext. display( )
615+ ) ;
616+ }
617+ if let Some ( dir) = rt_builtins_ext. parent ( ) {
618+ println ! ( "cargo::rustc-link-search=native={}" , dir. display( ) ) ;
619+ }
620+ println ! (
621+ "cargo::rustc-link-lib=static:+verbatim={}" ,
622+ rt_builtins_ext. to_str( ) . unwrap( )
623+ ) ;
624+ } else {
625+ cfg. compile ( "libcompiler-rt.a" ) ;
626+ }
602627 }
603628
604- fn build_aarch64_out_of_line_atomics_libraries ( builtins_dir : & Path , cfg : & mut cc:: Build ) {
629+ fn build_aarch64_out_of_line_atomics_libraries (
630+ builtins_dir : & Path ,
631+ cfg : & mut cc:: Build ,
632+ link_against_prebuilt_rt : bool ,
633+ ) {
605634 let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
606635 let outlined_atomics_file = builtins_dir. join ( "aarch64" ) . join ( "lse.S" ) ;
607- println ! ( "cargo:rerun-if-changed={}" , outlined_atomics_file. display( ) ) ;
636+ if !link_against_prebuilt_rt {
637+ println ! ( "cargo:rerun-if-changed={}" , outlined_atomics_file. display( ) ) ;
638+ }
608639
609640 cfg. include ( & builtins_dir) ;
610641
@@ -617,6 +648,13 @@ mod c {
617648 for ( model_number, model_name) in
618649 & [ ( 1 , "relax" ) , ( 2 , "acq" ) , ( 3 , "rel" ) , ( 4 , "acq_rel" ) ]
619650 {
651+ let sym = format ! ( "__aarch64_{}{}_{}" , instruction_type, size, model_name) ;
652+ println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " , sym) ;
653+
654+ if link_against_prebuilt_rt {
655+ continue ;
656+ }
657+
620658 // The original compiler-rt build system compiles the same
621659 // source file multiple times with different compiler
622660 // options. Here we do something slightly different: we
@@ -640,9 +678,6 @@ mod c {
640678 . unwrap ( ) ;
641679 drop ( file) ;
642680 cfg. file ( path) ;
643-
644- let sym = format ! ( "__aarch64_{}{}_{}" , instruction_type, size, model_name) ;
645- println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " , sym) ;
646681 }
647682 }
648683 }
0 commit comments