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.
This commit is contained in:
Andrew Kelley 2022-10-16 12:46:39 -07:00
parent 1013212697
commit caddbbc315
5 changed files with 20 additions and 10 deletions

View file

@ -1045,7 +1045,7 @@ elseif(MINGW)
target_link_libraries(zig2 ntdll) target_link_libraries(zig2 ntdll)
endif() endif()
set(ZIG_BUILD_ARGS "build" set(ZIG_BUILD_ARGS
--zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib"
"-Dconfig_h=${ZIG_CONFIG_H_OUT}" "-Dconfig_h=${ZIG_CONFIG_H_OUT}"
"-Denable-llvm" "-Denable-llvm"
@ -1060,7 +1060,7 @@ set(ZIG_BUILD_ARGS "build"
) )
add_custom_target(stage3 ALL add_custom_target(stage3 ALL
COMMAND zig2 ${ZIG_BUILD_ARGS} COMMAND zig2 build compile ${ZIG_BUILD_ARGS}
DEPENDS zig2 DEPENDS zig2
COMMENT STATUS "Building stage3" COMMENT STATUS "Building stage3"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"

View file

@ -142,6 +142,10 @@ pub fn build(b: *Builder) !void {
}; };
const exe = b.addExecutable("zig", main_file); 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.stack_size = stack_size;
exe.strip = strip; exe.strip = strip;
exe.sanitize_thread = sanitize_thread; exe.sanitize_thread = sanitize_thread;

View file

@ -1,5 +1,8 @@
set(ZIG_INSTALL_ARGS ${ZIG_BUILD_ARGS} --prefix "${CMAKE_INSTALL_PREFIX}") 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) execute_process(
COMMAND "${ZIG_EXECUTABLE}" ${ZIG_INSTALL_ARGS}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE _result)
if(_result) if(_result)
message("::") message("::")

View file

@ -1109,11 +1109,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const use_stage1 = options.use_stage1 orelse false; 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. // Make a decision on whether to use LLVM or our own backend.
const use_llvm = build_options.have_llvm and blk: { const use_llvm = build_options.have_llvm and blk: {
if (options.use_llvm) |explicit| 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; const tsan = options.want_tsan orelse false;
// TSAN is implemented in C++ so it requires linking libc++. // TSAN is implemented in C++ so it requires linking libc++.
const link_libcpp = options.link_libcpp or tsan; const link_libcpp = options.link_libcpp or tsan;

View file

@ -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, // 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 // we must hash those now, and the resulting digest will form the "id" of the linking
// job we are about to perform. // 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 // 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. // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD.
const id_symlink_basename = "lld.id"; const id_symlink_basename = "lld.id";