@@ -15,7 +15,9 @@ use std::sync::OnceLock;
1515use std:: { env, fs} ;
1616
1717use build_helper:: ci:: CiEnv ;
18- use build_helper:: git:: get_closest_merge_commit;
18+ use build_helper:: git:: { PathFreshness , check_path_modifications} ;
19+ #[ cfg( feature = "tracing" ) ]
20+ use tracing:: instrument;
1921
2022use crate :: core:: builder:: { Builder , RunConfig , ShouldRun , Step } ;
2123use crate :: core:: config:: { Config , TargetSelection } ;
@@ -24,7 +26,7 @@ use crate::utils::exec::command;
2426use crate :: utils:: helpers:: {
2527 self , exe, get_clang_cl_resource_dir, t, unhashed_basename, up_to_date,
2628} ;
27- use crate :: { CLang , GitRepo , Kind } ;
29+ use crate :: { CLang , GitRepo , Kind , trace } ;
2830
2931#[ derive( Clone ) ]
3032pub struct LlvmResult {
@@ -172,35 +174,38 @@ pub fn prebuilt_llvm_config(
172174 LlvmBuildStatus :: ShouldBuild ( Meta { stamp, res, out_dir, root : root. into ( ) } )
173175}
174176
175- /// This retrieves the LLVM sha we *want* to use, according to git history.
176- pub ( crate ) fn detect_llvm_sha ( config : & Config , is_git : bool ) -> String {
177- let llvm_sha = if is_git {
178- get_closest_merge_commit (
179- Some ( & config. src ) ,
180- & config. git_config ( ) ,
181- & [
182- config. src . join ( "src/llvm-project" ) ,
183- config. src . join ( "src/bootstrap/download-ci-llvm-stamp" ) ,
184- // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
185- config. src . join ( "src/version" ) ,
186- ] ,
177+ /// Detect whether LLVM sources have been modified locally or not.
178+ pub ( crate ) fn detect_llvm_freshness ( config : & Config , is_git : bool ) -> PathFreshness {
179+ let freshness = if is_git {
180+ Some (
181+ check_path_modifications (
182+ Some ( & config. src ) ,
183+ & config. git_config ( ) ,
184+ & [
185+ "src/llvm-project" ,
186+ "src/bootstrap/download-ci-llvm-stamp" ,
187+ // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
188+ "src/version" ,
189+ ] ,
190+ CiEnv :: current ( ) ,
191+ )
192+ . unwrap ( ) ,
187193 )
188- . unwrap ( )
189194 } else if let Some ( info) = crate :: utils:: channel:: read_commit_info_file ( & config. src ) {
190- info. sha . trim ( ) . to_owned ( )
195+ Some ( PathFreshness :: LastModifiedUpstream { upstream : info. sha . trim ( ) . to_owned ( ) } )
191196 } else {
192- "" . to_owned ( )
197+ None
193198 } ;
194199
195- if llvm_sha . is_empty ( ) {
200+ let Some ( freshness ) = freshness else {
196201 eprintln ! ( "error: could not find commit hash for downloading LLVM" ) ;
197202 eprintln ! ( "HELP: maybe your repository history is too shallow?" ) ;
198203 eprintln ! ( "HELP: consider disabling `download-ci-llvm`" ) ;
199204 eprintln ! ( "HELP: or fetch enough history to include one upstream commit" ) ;
200205 panic ! ( ) ;
201- }
206+ } ;
202207
203- llvm_sha
208+ freshness
204209}
205210
206211/// Returns whether the CI-found LLVM is currently usable.
@@ -280,12 +285,7 @@ pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool {
280285 return false ;
281286 }
282287
283- let llvm_sha = detect_llvm_sha ( config, true ) ;
284- let head_sha = crate :: output (
285- helpers:: git ( Some ( & config. src ) ) . arg ( "rev-parse" ) . arg ( "HEAD" ) . as_command_mut ( ) ,
286- ) ;
287- let head_sha = head_sha. trim ( ) ;
288- llvm_sha == head_sha
288+ matches ! ( detect_llvm_freshness( config, true ) , PathFreshness :: HasLocalModifications { .. } )
289289}
290290
291291#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
@@ -469,6 +469,10 @@ impl Step for Llvm {
469469 cfg. define ( "LLVM_BUILD_32_BITS" , "ON" ) ;
470470 }
471471
472+ if target. starts_with ( "x86_64" ) && target. contains ( "ohos" ) {
473+ cfg. define ( "LLVM_TOOL_LLVM_RTDYLD_BUILD" , "OFF" ) ;
474+ }
475+
472476 let mut enabled_llvm_projects = Vec :: new ( ) ;
473477
474478 if helpers:: forcing_clang_based_tests ( ) {
@@ -516,7 +520,7 @@ impl Step for Llvm {
516520 }
517521
518522 // https://llvm.org/docs/HowToCrossCompileLLVM.html
519- if !builder. is_builder_target ( & target) {
523+ if !builder. is_builder_target ( target) {
520524 let LlvmResult { llvm_config, .. } =
521525 builder. ensure ( Llvm { target : builder. config . build } ) ;
522526 if !builder. config . dry_run ( ) {
@@ -668,7 +672,7 @@ fn configure_cmake(
668672 }
669673 cfg. target ( & target. triple ) . host ( & builder. config . build . triple ) ;
670674
671- if !builder. is_builder_target ( & target) {
675+ if !builder. is_builder_target ( target) {
672676 cfg. define ( "CMAKE_CROSSCOMPILING" , "True" ) ;
673677
674678 if target. contains ( "netbsd" ) {
@@ -733,57 +737,17 @@ fn configure_cmake(
733737 None => ( builder. cc ( target) , builder. cxx ( target) . unwrap ( ) ) ,
734738 } ;
735739
736- // Handle msvc + ninja + ccache specially (this is what the bots use)
737- if target. is_msvc ( ) && builder. ninja ( ) && builder. config . ccache . is_some ( ) {
738- let mut wrap_cc = env:: current_exe ( ) . expect ( "failed to get cwd" ) ;
739- wrap_cc. set_file_name ( "sccache-plus-cl.exe" ) ;
740-
741- cfg. define ( "CMAKE_C_COMPILER" , sanitize_cc ( & wrap_cc) )
742- . define ( "CMAKE_CXX_COMPILER" , sanitize_cc ( & wrap_cc) ) ;
743- cfg. env ( "SCCACHE_PATH" , builder. config . ccache . as_ref ( ) . unwrap ( ) )
744- . env ( "SCCACHE_TARGET" , target. triple )
745- . env ( "SCCACHE_CC" , & cc)
746- . env ( "SCCACHE_CXX" , & cxx) ;
747-
748- // Building LLVM on MSVC can be a little ludicrous at times. We're so far
749- // off the beaten path here that I'm not really sure this is even half
750- // supported any more. Here we're trying to:
751- //
752- // * Build LLVM on MSVC
753- // * Build LLVM with `clang-cl` instead of `cl.exe`
754- // * Build a project with `sccache`
755- // * Build for 32-bit as well
756- // * Build with Ninja
757- //
758- // For `cl.exe` there are different binaries to compile 32/64 bit which
759- // we use but for `clang-cl` there's only one which internally
760- // multiplexes via flags. As a result it appears that CMake's detection
761- // of a compiler's architecture and such on MSVC **doesn't** pass any
762- // custom flags we pass in CMAKE_CXX_FLAGS below. This means that if we
763- // use `clang-cl.exe` it's always diagnosed as a 64-bit compiler which
764- // definitely causes problems since all the env vars are pointing to
765- // 32-bit libraries.
766- //
767- // To hack around this... again... we pass an argument that's
768- // unconditionally passed in the sccache shim. This'll get CMake to
769- // correctly diagnose it's doing a 32-bit compilation and LLVM will
770- // internally configure itself appropriately.
771- if builder. config . llvm_clang_cl . is_some ( ) && target. contains ( "i686" ) {
772- cfg. env ( "SCCACHE_EXTRA_ARGS" , "-m32" ) ;
740+ // If ccache is configured we inform the build a little differently how
741+ // to invoke ccache while also invoking our compilers.
742+ if use_compiler_launcher {
743+ if let Some ( ref ccache) = builder. config . ccache {
744+ cfg. define ( "CMAKE_C_COMPILER_LAUNCHER" , ccache)
745+ . define ( "CMAKE_CXX_COMPILER_LAUNCHER" , ccache) ;
773746 }
774- } else {
775- // If ccache is configured we inform the build a little differently how
776- // to invoke ccache while also invoking our compilers.
777- if use_compiler_launcher {
778- if let Some ( ref ccache) = builder. config . ccache {
779- cfg. define ( "CMAKE_C_COMPILER_LAUNCHER" , ccache)
780- . define ( "CMAKE_CXX_COMPILER_LAUNCHER" , ccache) ;
781- }
782- }
783- cfg. define ( "CMAKE_C_COMPILER" , sanitize_cc ( & cc) )
784- . define ( "CMAKE_CXX_COMPILER" , sanitize_cc ( & cxx) )
785- . define ( "CMAKE_ASM_COMPILER" , sanitize_cc ( & cc) ) ;
786747 }
748+ cfg. define ( "CMAKE_C_COMPILER" , sanitize_cc ( & cc) )
749+ . define ( "CMAKE_CXX_COMPILER" , sanitize_cc ( & cxx) )
750+ . define ( "CMAKE_ASM_COMPILER" , sanitize_cc ( & cc) ) ;
787751
788752 cfg. build_arg ( "-j" ) . build_arg ( builder. jobs ( ) . to_string ( ) ) ;
789753 // FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing
@@ -807,7 +771,9 @@ fn configure_cmake(
807771 cflags. push ( " " ) ;
808772 cflags. push ( s) ;
809773 }
810-
774+ if target. contains ( "ohos" ) {
775+ cflags. push ( " -D_LINUX_SYSINFO_H" ) ;
776+ }
811777 if builder. config . llvm_clang_cl . is_some ( ) {
812778 cflags. push ( format ! ( " --target={target}" ) ) ;
813779 }
@@ -828,6 +794,9 @@ fn configure_cmake(
828794 cxxflags. push ( " " ) ;
829795 cxxflags. push ( s) ;
830796 }
797+ if target. contains ( "ohos" ) {
798+ cxxflags. push ( " -D_LINUX_SYSINFO_H" ) ;
799+ }
831800 if builder. config . llvm_clang_cl . is_some ( ) {
832801 cxxflags. push ( format ! ( " --target={target}" ) ) ;
833802 }
@@ -934,6 +903,15 @@ impl Step for Enzyme {
934903 }
935904
936905 /// Compile Enzyme for `target`.
906+ #[ cfg_attr(
907+ feature = "tracing" ,
908+ instrument(
909+ level = "debug" ,
910+ name = "Enzyme::run" ,
911+ skip_all,
912+ fields( target = ?self . target) ,
913+ ) ,
914+ ) ]
937915 fn run ( self , builder : & Builder < ' _ > ) -> PathBuf {
938916 builder. require_submodule (
939917 "src/tools/enzyme" ,
@@ -959,7 +937,9 @@ impl Step for Enzyme {
959937 let out_dir = builder. enzyme_out ( target) ;
960938 let stamp = BuildStamp :: new ( & out_dir) . with_prefix ( "enzyme" ) . add_stamp ( smart_stamp_hash) ;
961939
940+ trace ! ( "checking build stamp to see if we need to rebuild enzyme artifacts" ) ;
962941 if stamp. is_up_to_date ( ) {
942+ trace ! ( ?out_dir, "enzyme build artifacts are up to date" ) ;
963943 if stamp. stamp ( ) . is_empty ( ) {
964944 builder. info (
965945 "Could not determine the Enzyme submodule commit hash. \
@@ -973,6 +953,7 @@ impl Step for Enzyme {
973953 return out_dir;
974954 }
975955
956+ trace ! ( ?target, "(re)building enzyme artifacts" ) ;
976957 builder. info ( & format ! ( "Building Enzyme for {}" , target) ) ;
977958 t ! ( stamp. remove( ) ) ;
978959 let _time = helpers:: timeit ( builder) ;
@@ -982,25 +963,23 @@ impl Step for Enzyme {
982963 . config
983964 . update_submodule ( Path :: new ( "src" ) . join ( "tools" ) . join ( "enzyme" ) . to_str ( ) . unwrap ( ) ) ;
984965 let mut cfg = cmake:: Config :: new ( builder. src . join ( "src/tools/enzyme/enzyme/" ) ) ;
985- // FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds
986- //cfg.profile("Debug");
987- //cfg.define("CMAKE_BUILD_TYPE", "Debug");
988966 configure_cmake ( builder, target, & mut cfg, true , LdFlags :: default ( ) , & [ ] ) ;
989967
990968 // Re-use the same flags as llvm to control the level of debug information
991- // generated for lld.
969+ // generated by Enzyme.
970+ // FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds.
992971 let profile = match ( builder. config . llvm_optimize , builder. config . llvm_release_debuginfo ) {
993972 ( false , _) => "Debug" ,
994973 ( true , false ) => "Release" ,
995974 ( true , true ) => "RelWithDebInfo" ,
996975 } ;
976+ trace ! ( ?profile) ;
997977
998978 cfg. out_dir ( & out_dir)
999979 . profile ( profile)
1000980 . env ( "LLVM_CONFIG_REAL" , & llvm_config)
1001981 . define ( "LLVM_ENABLE_ASSERTIONS" , "ON" )
1002982 . define ( "ENZYME_EXTERNAL_SHARED_LIB" , "ON" )
1003- . define ( "ENZYME_RUNPASS" , "ON" )
1004983 . define ( "LLVM_DIR" , builder. llvm_out ( target) ) ;
1005984
1006985 cfg. build ( ) ;
@@ -1118,7 +1097,7 @@ impl Step for Lld {
11181097 . define ( "LLVM_CMAKE_DIR" , llvm_cmake_dir)
11191098 . define ( "LLVM_INCLUDE_TESTS" , "OFF" ) ;
11201099
1121- if !builder. is_builder_target ( & target) {
1100+ if !builder. is_builder_target ( target) {
11221101 // Use the host llvm-tblgen binary.
11231102 cfg. define (
11241103 "LLVM_TABLEGEN_EXE" ,
@@ -1204,6 +1183,10 @@ impl Step for Sanitizers {
12041183 cfg. define ( "COMPILER_RT_USE_LIBCXX" , "OFF" ) ;
12051184 cfg. define ( "LLVM_CONFIG_PATH" , & llvm_config) ;
12061185
1186+ if self . target . contains ( "ohos" ) {
1187+ cfg. define ( "COMPILER_RT_USE_BUILTINS_LIBRARY" , "ON" ) ;
1188+ }
1189+
12071190 // On Darwin targets the sanitizer runtimes are build as universal binaries.
12081191 // Unfortunately sccache currently lacks support to build them successfully.
12091192 // Disable compiler launcher on Darwin targets to avoid potential issues.
0 commit comments