@@ -540,20 +540,28 @@ mod c {
540540            sources. extend ( & [ ( "__emutls_get_address" ,  "emutls.c" ) ] ) ; 
541541        } 
542542
543+         // Optionally, link against a prebuilt llvm compiler-rt containing the builtins 
544+         // library. Only the builtins library is required. On many platforms, this is 
545+         // available as a library named libclang_rt.builtins.a. 
546+         let  link_against_prebuilt_rt = env:: var_os ( "LLVM_COMPILER_RT_LIB" ) . is_some ( ) ; 
547+ 
543548        // When compiling the C code we require the user to tell us where the 
544549        // source code is, and this is largely done so when we're compiling as 
545550        // part of rust-lang/rust we can use the same llvm-project repository as 
546551        // rust-lang/rust. 
547552        let  root = match  env:: var_os ( "RUST_COMPILER_RT_ROOT" )  { 
548553            Some ( s)  => PathBuf :: from ( s) , 
554+             // If a prebuild libcompiler-rt is provided, set a valid 
555+             // path to simplify later logic. Nothing should be compiled. 
556+             None  if  link_against_prebuilt_rt => PathBuf :: new ( ) , 
549557            None  => { 
550558                panic ! ( 
551559                    "RUST_COMPILER_RT_ROOT is not set. You may need to run \  
552560
553561                ) ; 
554562            } 
555563        } ; 
556-         if  !root. exists ( )  { 
564+         if  !link_against_prebuilt_rt && ! root. exists ( )  { 
557565            panic ! ( "RUST_COMPILER_RT_ROOT={} does not exist" ,  root. display( ) ) ; 
558566        } 
559567
@@ -569,7 +577,7 @@ mod c {
569577        let  src_dir = root. join ( "lib/builtins" ) ; 
570578        if  target. arch  == "aarch64"  && target. env  != "msvc"  && target. os  != "uefi"  { 
571579            // See below for why we're building these as separate libraries. 
572-             build_aarch64_out_of_line_atomics_libraries ( & src_dir,  cfg) ; 
580+             build_aarch64_out_of_line_atomics_libraries ( & src_dir,  cfg,  link_against_prebuilt_rt ) ; 
573581
574582            // Some run-time CPU feature detection is necessary, as well. 
575583            let  cpu_model_src = if  src_dir. join ( "cpu_model.c" ) . exists ( )  { 
@@ -583,20 +591,45 @@ mod c {
583591        let  mut  added_sources = HashSet :: new ( ) ; 
584592        for  ( sym,  src)  in  sources. map . iter ( )  { 
585593            let  src = src_dir. join ( src) ; 
586-             if  added_sources. insert ( src. clone ( ) )  { 
594+             if  !link_against_prebuilt_rt &&  added_sources. insert ( src. clone ( ) )  { 
587595                cfg. file ( & src) ; 
588596                println ! ( "cargo:rerun-if-changed={}" ,  src. display( ) ) ; 
589597            } 
590598            println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
591599        } 
592600
593-         cfg. compile ( "libcompiler-rt.a" ) ; 
601+         if  link_against_prebuilt_rt { 
602+             let  rt_builtins_ext = PathBuf :: from ( env:: var_os ( "LLVM_COMPILER_RT_LIB" ) . unwrap ( ) ) ; 
603+             if  !rt_builtins_ext. exists ( )  { 
604+                 panic ! ( 
605+                     "LLVM_COMPILER_RT_LIB={} does not exist" , 
606+                     rt_builtins_ext. display( ) 
607+                 ) ; 
608+             } 
609+             if  let  Some ( dir)  = rt_builtins_ext. parent ( )  { 
610+                 println ! ( "cargo::rustc-link-search=native={}" ,  dir. display( ) ) ; 
611+             } 
612+             if  let  Some ( lib)  = rt_builtins_ext. file_name ( )  { 
613+                 println ! ( 
614+                     "cargo::rustc-link-lib=static:+verbatim={}" , 
615+                     lib. to_str( ) . unwrap( ) 
616+                 ) ; 
617+             } 
618+         }  else  { 
619+             cfg. compile ( "libcompiler-rt.a" ) ; 
620+         } 
594621    } 
595622
596-     fn  build_aarch64_out_of_line_atomics_libraries ( builtins_dir :  & Path ,  cfg :  & mut  cc:: Build )  { 
623+     fn  build_aarch64_out_of_line_atomics_libraries ( 
624+         builtins_dir :  & Path , 
625+         cfg :  & mut  cc:: Build , 
626+         link_against_prebuilt_rt :  bool , 
627+     )  { 
597628        let  out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ; 
598629        let  outlined_atomics_file = builtins_dir. join ( "aarch64" ) . join ( "lse.S" ) ; 
599-         println ! ( "cargo:rerun-if-changed={}" ,  outlined_atomics_file. display( ) ) ; 
630+         if  !link_against_prebuilt_rt { 
631+             println ! ( "cargo:rerun-if-changed={}" ,  outlined_atomics_file. display( ) ) ; 
632+         } 
600633
601634        cfg. include ( & builtins_dir) ; 
602635
@@ -609,6 +642,13 @@ mod c {
609642                for  ( model_number,  model_name)  in 
610643                    & [ ( 1 ,  "relax" ) ,  ( 2 ,  "acq" ) ,  ( 3 ,  "rel" ) ,  ( 4 ,  "acq_rel" ) ] 
611644                { 
645+                     let  sym = format ! ( "__aarch64_{}{}_{}" ,  instruction_type,  size,  model_name) ; 
646+                     println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
647+ 
648+                     if  link_against_prebuilt_rt { 
649+                         continue ; 
650+                     } 
651+ 
612652                    // The original compiler-rt build system compiles the same 
613653                    // source file multiple times with different compiler 
614654                    // options. Here we do something slightly different: we 
@@ -632,9 +672,6 @@ mod c {
632672                    . unwrap ( ) ; 
633673                    drop ( file) ; 
634674                    cfg. file ( path) ; 
635- 
636-                     let  sym = format ! ( "__aarch64_{}{}_{}" ,  instruction_type,  size,  model_name) ; 
637-                     println ! ( "cargo:rustc-cfg={}=\" optimized-c\" " ,  sym) ; 
638675                } 
639676            } 
640677        } 
0 commit comments