diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a4a6d3199..950aa70ce1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -604,28 +604,29 @@ else() set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a") endif() if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - set(LIBUSERLAND_RELEASE_MODE "false") + set(LIBUSERLAND_RELEASE_ARG "") else() - set(LIBUSERLAND_RELEASE_MODE "true") + set(LIBUSERLAND_RELEASE_ARG "--release-fast --strip") +endif() +if(WIN32) + set(LIBUSERLAND_WINDOWS_ARGS "-lntdll") +else() + set(LIBUSERLAND_WINDOWS_ARGS "") endif() -set(BUILD_LIBUSERLAND_ARGS "build" +set(BUILD_LIBUSERLAND_ARGS "build-lib" --override-lib-dir "${CMAKE_SOURCE_DIR}/lib" - "-Doutput-dir=${CMAKE_BINARY_DIR}" - "-Drelease=${LIBUSERLAND_RELEASE_MODE}" - "-Dlib-files-only" - --prefix "${CMAKE_INSTALL_PREFIX}" - libuserland + --cache on + --output-dir "${CMAKE_BINARY_DIR}" + ${LIBUSERLAND_RELEASE_ARG} + "src-self-hosted/stage1.zig" + --disable-gen-h + --bundle-compiler-rt + -fPIC + -lc + ${LIBUSERLAND_WINDOWS_ARGS} ) -# When using Visual Studio build system generator we default to libuserland install. -if(MSVC) - set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL "Disable copying lib/ files to install prefix") - if(NOT ZIG_SKIP_INSTALL_LIB_FILES) - set(BUILD_LIBUSERLAND_ARGS ${BUILD_LIBUSERLAND_ARGS} install) - endif() -endif() - add_custom_target(zig_build_libuserland ALL COMMAND zig0 ${BUILD_LIBUSERLAND_ARGS} DEPENDS zig0 @@ -648,12 +649,30 @@ add_dependencies(zig zig_build_libuserland) install(TARGETS zig DESTINATION bin) -# CODE has no effect with Visual Studio build system generator. -if(NOT MSVC) - get_target_property(zig0_BINARY_DIR zig0 BINARY_DIR) - install(CODE "set(zig0_EXE \"${zig0_BINARY_DIR}/zig0\")") - install(CODE "set(INSTALL_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\" install)") - install(CODE "set(BUILD_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\")") +set(ZIG_INSTALL_ARGS "build" + --override-lib-dir "${CMAKE_SOURCE_DIR}/lib" + "-Dlib-files-only" + --prefix "${CMAKE_INSTALL_PREFIX}" + install +) + +# CODE has no effect with Visual Studio build system generator, therefore +# when using Visual Studio build system generator we resort to running +# `zig build install` during the build phase. +if(MSVC) + set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL + "Windows-only: Disable copying lib/ files to install prefix during the build phase") + if(NOT ZIG_SKIP_INSTALL_LIB_FILES) + add_custom_target(zig_install_lib_files ALL + COMMAND zig ${ZIG_INSTALL_ARGS} + DEPENDS zig + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + ) + endif() +else() + get_target_property(zig_BINARY_DIR zig BINARY_DIR) + install(CODE "set(zig_EXE \"${zig_BINARY_DIR}/zig\")") + install(CODE "set(ZIG_INSTALL_ARGS \"${ZIG_INSTALL_ARGS}\")") install(CODE "set(CMAKE_SOURCE_DIR \"${CMAKE_SOURCE_DIR}\")") install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install.cmake) endif() diff --git a/build.zig b/build.zig index 4567b63029..e1ae5cf3cd 100644 --- a/build.zig +++ b/build.zig @@ -64,8 +64,6 @@ pub fn build(b: *Builder) !void { try configureStage2(b, test_stage2, ctx); try configureStage2(b, exe, ctx); - addLibUserlandStep(b, mode); - const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false; const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release; const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release; @@ -366,28 +364,3 @@ const Context = struct { dia_guids_lib: []const u8, llvm: LibraryDep, }; - -fn addLibUserlandStep(b: *Builder, mode: builtin.Mode) void { - const artifact = b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); - artifact.disable_gen_h = true; - artifact.bundle_compiler_rt = true; - artifact.setTarget(builtin.arch, builtin.os, builtin.abi); - artifact.setBuildMode(mode); - artifact.force_pic = true; - if (mode != .Debug) { - artifact.strip = true; - } - artifact.linkSystemLibrary("c"); - if (builtin.os == .windows) { - artifact.linkSystemLibrary("ntdll"); - } - const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); - libuserland_step.dependOn(&artifact.step); - - const output_dir = b.option( - []const u8, - "output-dir", - "For libuserland step, where to put the output", - ) orelse return; - artifact.setOutputDir(output_dir); -} diff --git a/cmake/install.cmake b/cmake/install.cmake index 415a088d6a..e485652a05 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -1,16 +1,16 @@ message("-- Installing: ${CMAKE_INSTALL_PREFIX}/lib") -if(NOT EXISTS ${zig0_EXE}) +if(NOT EXISTS ${zig_EXE}) message("::") message(":: ERROR: Executable not found") message(":: (execute_process)") message("::") - message(":: executable: ${zig0_EXE}") + message(":: executable: ${zig_EXE}") message("::") message(FATAL_ERROR) endif() -execute_process(COMMAND ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS} +execute_process(COMMAND ${zig_EXE} ${ZIG_INSTALL_ARGS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} RESULT_VARIABLE _result ) @@ -19,11 +19,11 @@ if(_result) message(":: ERROR: ${_result}") message(":: (execute_process)") - string(REPLACE ";" " " s_INSTALL_LIBUSERLAND_ARGS "${INSTALL_LIBUSERLAND_ARGS}") + string(REPLACE ";" " " s_INSTALL_LIBUSERLAND_ARGS "${ZIG_INSTALL_ARGS}") message("::") - message(":: argv: ${zig0_EXE} ${s_INSTALL_LIBUSERLAND_ARGS} install") + message(":: argv: ${zig_EXE} ${s_INSTALL_LIBUSERLAND_ARGS}") - set(_args ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS}) + set(_args ${zig_EXE} ${ZIG_INSTALL_ARGS}) list(LENGTH _args _len) math(EXPR _len "${_len} - 1") message("::") diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig index 8f62e91e38..d66f00c14e 100644 --- a/src-self-hosted/libc_installation.zig +++ b/src-self-hosted/libc_installation.zig @@ -204,14 +204,17 @@ pub const LibCInstallation = struct { } } } else { - var batch = Batch(FindError!void, 2, .auto_async).init(); - batch.add(&async self.findNativeIncludeDirPosix(allocator)); - if (is_freebsd or is_netbsd) { - self.crt_dir = try std.mem.dupeZ(allocator, u8, "/usr/lib"); - } else if (is_linux or is_dragonfly) { - batch.add(&async self.findNativeCrtDirPosix(allocator)); - } - try batch.wait(); + try blk: { + var batch = Batch(FindError!void, 2, .auto_async).init(); + errdefer batch.wait() catch {}; + batch.add(&async self.findNativeIncludeDirPosix(allocator)); + if (is_freebsd or is_netbsd) { + self.crt_dir = try std.mem.dupeZ(allocator, u8, "/usr/lib"); + } else if (is_linux or is_dragonfly) { + batch.add(&async self.findNativeCrtDirPosix(allocator)); + } + break :blk batch.wait(); + }; } return self; } diff --git a/src/main.cpp b/src/main.cpp index d5883d2bb3..4f5367be7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1003,9 +1003,22 @@ static int main0(int argc, char **argv) { return main_exit(root_progress_node, EXIT_FAILURE); } + // If both output_dir and enable_cache are provided, and doing build-lib, we + // will just do a file copy at the end. This helps when bootstrapping zig from zig0 + // because we want to pass something like this: + // zig0 build-lib --cache on --output-dir ${CMAKE_BINARY_DIR} + // And we don't have access to `zig0 build` because that would require detecting native libc + // on systems where we are not able to build a libc from source for them. + // But that's the only reason this works, so otherwise we give an error here. + Buf *final_output_dir_step = nullptr; if (output_dir != nullptr && enable_cache == CacheOptOn) { - fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n"); - return print_error_usage(arg0); + if (cmd == CmdBuild && out_type == OutTypeLib) { + final_output_dir_step = output_dir; + output_dir = nullptr; + } else { + fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n"); + return print_error_usage(arg0); + } } if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) { @@ -1290,8 +1303,21 @@ static int main0(int argc, char **argv) { #if defined(ZIG_OS_WINDOWS) buf_replace(&g->output_file_path, '/', '\\'); #endif - if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) - return main_exit(root_progress_node, EXIT_FAILURE); + if (final_output_dir_step != nullptr) { + Buf *dest_basename = buf_alloc(); + os_path_split(&g->output_file_path, nullptr, dest_basename); + Buf *dest_path = buf_alloc(); + os_path_join(final_output_dir_step, dest_basename, dest_path); + + if ((err = os_copy_file(&g->output_file_path, dest_path))) { + fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path), + buf_ptr(dest_path), err_str(err)); + return main_exit(root_progress_node, EXIT_FAILURE); + } + } else { + if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) + return main_exit(root_progress_node, EXIT_FAILURE); + } } return main_exit(root_progress_node, EXIT_SUCCESS); } else { diff --git a/src/userland.cpp b/src/userland.cpp index 2be97f22d6..539735f436 100644 --- a/src/userland.cpp +++ b/src/userland.cpp @@ -146,19 +146,8 @@ int stage2_cmd_targets(const char *zig_triple) { } enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) { - libc->include_dir = "/dummy/include"; - libc->include_dir_len = strlen(libc->include_dir); - libc->sys_include_dir = "/dummy/sys/include"; - libc->sys_include_dir_len = strlen(libc->sys_include_dir); - libc->crt_dir = ""; - libc->crt_dir_len = strlen(libc->crt_dir); - libc->static_crt_dir = ""; - libc->static_crt_dir_len = strlen(libc->static_crt_dir); - libc->msvc_lib_dir = ""; - libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir); - libc->kernel32_lib_dir = ""; - libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir); - return ErrorNone; + const char *msg = "stage0 called stage2_libc_parse"; + stage2_panic(msg, strlen(msg)); } enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) {