From caddbbc315e834241c6ae7e22434b574c589e5fc Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 16 Oct 2022 12:46:39 -0700 Subject: [PATCH] build: avoid compiling self-hosted twice build.zig: add a 'compile' step to compile the self-hosted compiler without installing it. Compilation: set cache mode to whole when using the LLVM backend and --enable-cache is passed. This makes `zig build` act the same as it does with stage1. Upside is that a second invocation of `zig build` on an unmodified source tree will avoid redoing the compilation again. Downside is that it will proliferate more garbage in the project-local cache (same as stage1). This can eventually be fixed when Zig's incremental compilation is more robust; we can go back to having LLVM use CacheMode.incremental and rely on it detecting no changes and avoiding doing the flush() step. --- CMakeLists.txt | 4 ++-- build.zig | 4 ++++ cmake/install.cmake | 7 +++++-- src/Compilation.zig | 13 ++++++++----- src/link/Elf.zig | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16e6776010f8..dcc7e03d6b0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1045,7 +1045,7 @@ elseif(MINGW) target_link_libraries(zig2 ntdll) endif() -set(ZIG_BUILD_ARGS "build" +set(ZIG_BUILD_ARGS --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" "-Dconfig_h=${ZIG_CONFIG_H_OUT}" "-Denable-llvm" @@ -1060,7 +1060,7 @@ set(ZIG_BUILD_ARGS "build" ) add_custom_target(stage3 ALL - COMMAND zig2 ${ZIG_BUILD_ARGS} + COMMAND zig2 build compile ${ZIG_BUILD_ARGS} DEPENDS zig2 COMMENT STATUS "Building stage3" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" diff --git a/build.zig b/build.zig index aec623f642fb..2dd047a1e3e1 100644 --- a/build.zig +++ b/build.zig @@ -142,6 +142,10 @@ pub fn build(b: *Builder) !void { }; const exe = b.addExecutable("zig", main_file); + + const compile_step = b.step("compile", "Build the self-hosted compiler"); + compile_step.dependOn(&exe.step); + exe.stack_size = stack_size; exe.strip = strip; exe.sanitize_thread = sanitize_thread; diff --git a/cmake/install.cmake b/cmake/install.cmake index f7b14c471efe..4a8356313e6f 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -1,5 +1,8 @@ -set(ZIG_INSTALL_ARGS ${ZIG_BUILD_ARGS} --prefix "${CMAKE_INSTALL_PREFIX}") -execute_process(COMMAND "${ZIG_EXECUTABLE}" ${ZIG_INSTALL_ARGS} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE _result) +set(ZIG_INSTALL_ARGS build ${ZIG_BUILD_ARGS} --prefix "${CMAKE_INSTALL_PREFIX}") +execute_process( + COMMAND "${ZIG_EXECUTABLE}" ${ZIG_INSTALL_ARGS} + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE _result) if(_result) message("::") diff --git a/src/Compilation.zig b/src/Compilation.zig index 0ff94818756d..659cfda9bdbe 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1109,11 +1109,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const use_stage1 = options.use_stage1 orelse false; - const cache_mode = if (use_stage1 and !options.disable_lld_caching) - CacheMode.whole - else - options.cache_mode; - // Make a decision on whether to use LLVM or our own backend. const use_llvm = build_options.have_llvm and blk: { if (options.use_llvm) |explicit| @@ -1154,6 +1149,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { } } + // TODO: once we support incremental compilation for the LLVM backend via + // saving the LLVM module into a bitcode file and restoring it, along with + // compiler state, the second clause here can be removed so that incremental + // cache mode is used for LLVM backend too. We need some fuzz testing before + // that can be enabled. + const cache_mode = if ((use_stage1 and !options.disable_lld_caching) or + (use_llvm and !options.disable_lld_caching)) CacheMode.whole else options.cache_mode; + const tsan = options.want_tsan orelse false; // TSAN is implemented in C++ so it requires linking libc++. const link_libcpp = options.link_libcpp or tsan; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 4e67c095c007..1a722c1dde47 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1282,7 +1282,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v // linked are in the hash that namespaces the directory we are outputting to. Therefore, // we must hash those now, and the resulting digest will form the "id" of the linking // job we are about to perform. - // After a successful link, we store the id in the metadata of a symlink named "id.txt" in + // After a successful link, we store the id in the metadata of a symlink named "lld.id" in // the artifact directory. So, now, we check if this symlink exists, and if it matches // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD. const id_symlink_basename = "lld.id";