@@ -547,20 +547,28 @@ mod c {
547547            sources. extend ( & [ ( "__emutls_get_address" ,  "emutls.c" ) ] ) ; 
548548        } 
549549
550+         // Optionally, link against a prebuilt compiler-rt library to supply 
551+         // optimized intrinsics instead of compiling a subset of compiler-rt 
552+         // from source. 
553+         let  link_against_prebuilt_rt = env:: var_os ( "LLVM_COMPILER_RT_LIB" ) . is_some ( ) ; 
554+ 
550555        // When compiling the C code we require the user to tell us where the 
551556        // source code is, and this is largely done so when we're compiling as 
552557        // part of rust-lang/rust we can use the same llvm-project repository as 
553558        // rust-lang/rust. 
554559        let  root = match  env:: var_os ( "RUST_COMPILER_RT_ROOT" )  { 
555560            Some ( s)  => PathBuf :: from ( s) , 
561+             // If a prebuild libcompiler-rt is provided, set a valid 
562+             // path to simplify later logic. Nothing should be compiled. 
563+             None  if  link_against_prebuilt_rt => PathBuf :: new ( ) , 
556564            None  => { 
557565                panic ! ( 
558566                    "RUST_COMPILER_RT_ROOT is not set. You may need to run \  
559567                     `ci/download-compiler-rt.sh`."
560568                ) ; 
561569            } 
562570        } ; 
563-         if  !root. exists ( )  { 
571+         if  !link_against_prebuilt_rt && ! root. exists ( )  { 
564572            panic ! ( "RUST_COMPILER_RT_ROOT={} does not exist" ,  root. display( ) ) ; 
565573        } 
566574
@@ -576,7 +584,7 @@ mod c {
576584        let  src_dir = root. join ( "lib/builtins" ) ; 
577585        if  target. arch  == "aarch64"  && target. env  != "msvc"  && target. os  != "uefi"  { 
578586            // See below for why we're building these as separate libraries. 
579-             build_aarch64_out_of_line_atomics_libraries ( & src_dir,  cfg) ; 
587+             build_aarch64_out_of_line_atomics_libraries ( & src_dir,  cfg,  link_against_prebuilt_rt ) ; 
580588
581589            // Some run-time CPU feature detection is necessary, as well. 
582590            let  cpu_model_src = if  src_dir. join ( "cpu_model.c" ) . exists ( )  { 
@@ -590,20 +598,45 @@ mod c {
590598        let  mut  added_sources = HashSet :: new ( ) ; 
591599        for  ( sym,  src)  in  sources. map . iter ( )  { 
592600            let  src = src_dir. join ( src) ; 
593-             if  added_sources. insert ( src. clone ( ) )  { 
601+             if  !link_against_prebuilt_rt &&  added_sources. insert ( src. clone ( ) )  { 
594602                cfg. file ( & src) ; 
595603                println ! ( "cargo:rerun-if-changed={}" ,  src. display( ) ) ; 
596604            } 
597605            println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
598606        } 
599607
600-         cfg. compile ( "libcompiler-rt.a" ) ; 
608+         if  link_against_prebuilt_rt { 
609+             let  rt_builtins_ext = PathBuf :: from ( env:: var_os ( "LLVM_COMPILER_RT_LIB" ) . unwrap ( ) ) ; 
610+             if  !rt_builtins_ext. exists ( )  { 
611+                 panic ! ( 
612+                     "LLVM_COMPILER_RT_LIB={} does not exist" , 
613+                     rt_builtins_ext. display( ) 
614+                 ) ; 
615+             } 
616+             if  let  Some ( dir)  = rt_builtins_ext. parent ( )  { 
617+                 println ! ( "cargo::rustc-link-search=native={}" ,  dir. display( ) ) ; 
618+             } 
619+             if  let  Some ( lib)  = rt_builtins_ext. file_name ( )  { 
620+                 println ! ( 
621+                     "cargo::rustc-link-lib=static:+verbatim={}" , 
622+                     lib. to_str( ) . unwrap( ) 
623+                 ) ; 
624+             } 
625+         }  else  { 
626+             cfg. compile ( "libcompiler-rt.a" ) ; 
627+         } 
601628    } 
602629
603-     fn  build_aarch64_out_of_line_atomics_libraries ( builtins_dir :  & Path ,  cfg :  & mut  cc:: Build )  { 
630+     fn  build_aarch64_out_of_line_atomics_libraries ( 
631+         builtins_dir :  & Path , 
632+         cfg :  & mut  cc:: Build , 
633+         link_against_prebuilt_rt :  bool , 
634+     )  { 
604635        let  out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ; 
605636        let  outlined_atomics_file = builtins_dir. join ( "aarch64" ) . join ( "lse.S" ) ; 
606-         println ! ( "cargo:rerun-if-changed={}" ,  outlined_atomics_file. display( ) ) ; 
637+         if  !link_against_prebuilt_rt { 
638+             println ! ( "cargo:rerun-if-changed={}" ,  outlined_atomics_file. display( ) ) ; 
639+         } 
607640
608641        cfg. include ( & builtins_dir) ; 
609642
@@ -616,6 +649,13 @@ mod c {
616649                for  ( model_number,  model_name)  in 
617650                    & [ ( 1 ,  "relax" ) ,  ( 2 ,  "acq" ) ,  ( 3 ,  "rel" ) ,  ( 4 ,  "acq_rel" ) ] 
618651                { 
652+                     let  sym = format ! ( "__aarch64_{}{}_{}" ,  instruction_type,  size,  model_name) ; 
653+                     println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
654+ 
655+                     if  link_against_prebuilt_rt { 
656+                         continue ; 
657+                     } 
658+ 
619659                    // The original compiler-rt build system compiles the same 
620660                    // source file multiple times with different compiler 
621661                    // options. Here we do something slightly different: we 
@@ -639,9 +679,6 @@ mod c {
639679                    . unwrap ( ) ; 
640680                    drop ( file) ; 
641681                    cfg. file ( path) ; 
642- 
643-                     let  sym = format ! ( "__aarch64_{}{}_{}" ,  instruction_type,  size,  model_name) ; 
644-                     println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
645682                } 
646683            } 
647684        } 
0 commit comments