authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-16 12:46:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-18 16:52:43-07:00
logcaddbbc315e834241c6ae7e22434b574c589e5fc
treefe412c607e0e4a21a8f43da130335ace3c4fe304
parent10132126972604c4636b148df27ab7fe9e50136b

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.

5 files changed, 20 insertions(+), 10 deletions(-)

CMakeLists.txt+2-2
......@@ -1045,7 +1045,7 @@ elseif(MINGW)
10451045 target_link_libraries(zig2 ntdll)
10461046endif()
10471047
1048set(ZIG_BUILD_ARGS "build"
1048set(ZIG_BUILD_ARGS
10491049 --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib"
10501050 "-Dconfig_h=${ZIG_CONFIG_H_OUT}"
10511051 "-Denable-llvm"
......@@ -1060,7 +1060,7 @@ set(ZIG_BUILD_ARGS "build"
10601060)
10611061
10621062add_custom_target(stage3 ALL
1063 COMMAND zig2 ${ZIG_BUILD_ARGS}
1063 COMMAND zig2 build compile ${ZIG_BUILD_ARGS}
10641064 DEPENDS zig2
10651065 COMMENT STATUS "Building stage3"
10661066 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
build.zig+4
......@@ -142,6 +142,10 @@ pub fn build(b: *Builder) !void {
142142 };
143143
144144 const exe = b.addExecutable("zig", main_file);
145
146 const compile_step = b.step("compile", "Build the self-hosted compiler");
147 compile_step.dependOn(&exe.step);
148
145149 exe.stack_size = stack_size;
146150 exe.strip = strip;
147151 exe.sanitize_thread = sanitize_thread;
cmake/install.cmake+5-2
......@@ -1,5 +1,8 @@
1set(ZIG_INSTALL_ARGS ${ZIG_BUILD_ARGS} --prefix "${CMAKE_INSTALL_PREFIX}")
2execute_process(COMMAND "${ZIG_EXECUTABLE}" ${ZIG_INSTALL_ARGS} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE _result)
1set(ZIG_INSTALL_ARGS build ${ZIG_BUILD_ARGS} --prefix "${CMAKE_INSTALL_PREFIX}")
2execute_process(
3 COMMAND "${ZIG_EXECUTABLE}" ${ZIG_INSTALL_ARGS}
4 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
5 RESULT_VARIABLE _result)
36
47if(_result)
58 message("::")
src/Compilation.zig+8-5
......@@ -1109,11 +1109,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
11091109
11101110 const use_stage1 = options.use_stage1 orelse false;
11111111
1112 const cache_mode = if (use_stage1 and !options.disable_lld_caching)
1113 CacheMode.whole
1114 else
1115 options.cache_mode;
1116
11171112 // Make a decision on whether to use LLVM or our own backend.
11181113 const use_llvm = build_options.have_llvm and blk: {
11191114 if (options.use_llvm) |explicit|
......@@ -1154,6 +1149,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
11541149 }
11551150 }
11561151
1152 // TODO: once we support incremental compilation for the LLVM backend via
1153 // saving the LLVM module into a bitcode file and restoring it, along with
1154 // compiler state, the second clause here can be removed so that incremental
1155 // cache mode is used for LLVM backend too. We need some fuzz testing before
1156 // that can be enabled.
1157 const cache_mode = if ((use_stage1 and !options.disable_lld_caching) or
1158 (use_llvm and !options.disable_lld_caching)) CacheMode.whole else options.cache_mode;
1159
11571160 const tsan = options.want_tsan orelse false;
11581161 // TSAN is implemented in C++ so it requires linking libc++.
11591162 const link_libcpp = options.link_libcpp or tsan;
src/link/Elf.zig+1-1
......@@ -1282,7 +1282,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
12821282 // linked are in the hash that namespaces the directory we are outputting to. Therefore,
12831283 // we must hash those now, and the resulting digest will form the "id" of the linking
12841284 // job we are about to perform.
1285 // After a successful link, we store the id in the metadata of a symlink named "id.txt" in
1285 // After a successful link, we store the id in the metadata of a symlink named "lld.id" in
12861286 // the artifact directory. So, now, we check if this symlink exists, and if it matches
12871287 // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD.
12881288 const id_symlink_basename = "lld.id";