diff --git a/CMakeLists.txt b/CMakeLists.txt index 963938ca78..3263725019 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -296,14 +296,12 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig" "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig" "${CMAKE_SOURCE_DIR}/lib/std/os.zig" - "${CMAKE_SOURCE_DIR}/lib/std/os/darwin.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux/errno/generic.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig" - "${CMAKE_SOURCE_DIR}/lib/std/os/posix_spawn.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig" @@ -507,7 +505,9 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/Thread.zig" "${CMAKE_SOURCE_DIR}/lib/std/Thread/Futex.zig" "${CMAKE_SOURCE_DIR}/lib/std/Thread/Mutex.zig" + "${CMAKE_SOURCE_DIR}/lib/std/Thread/Pool.zig" "${CMAKE_SOURCE_DIR}/lib/std/Thread/ResetEvent.zig" + "${CMAKE_SOURCE_DIR}/lib/std/Thread/WaitGroup.zig" "${CMAKE_SOURCE_DIR}/lib/std/time.zig" "${CMAKE_SOURCE_DIR}/lib/std/treap.zig" "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig" @@ -517,6 +517,7 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig" + "${CMAKE_SOURCE_DIR}/lib/std/zig/Server.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/system.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativePaths.zig" @@ -531,9 +532,7 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/src/Package.zig" "${CMAKE_SOURCE_DIR}/src/RangeSet.zig" "${CMAKE_SOURCE_DIR}/src/Sema.zig" - "${CMAKE_SOURCE_DIR}/src/ThreadPool.zig" "${CMAKE_SOURCE_DIR}/src/TypedValue.zig" - "${CMAKE_SOURCE_DIR}/src/WaitGroup.zig" "${CMAKE_SOURCE_DIR}/src/Zir.zig" "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig" "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig" @@ -560,9 +559,12 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/src/arch/wasm/Mir.zig" "${CMAKE_SOURCE_DIR}/src/arch/x86_64/CodeGen.zig" "${CMAKE_SOURCE_DIR}/src/arch/x86_64/Emit.zig" + "${CMAKE_SOURCE_DIR}/src/arch/x86_64/Encoding.zig" "${CMAKE_SOURCE_DIR}/src/arch/x86_64/Mir.zig" - "${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig" "${CMAKE_SOURCE_DIR}/src/arch/x86_64/abi.zig" + "${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig" + "${CMAKE_SOURCE_DIR}/src/arch/x86_64/encoder.zig" + "${CMAKE_SOURCE_DIR}/src/arch/x86_64/encodings.zig" "${CMAKE_SOURCE_DIR}/src/clang.zig" "${CMAKE_SOURCE_DIR}/src/clang_options.zig" "${CMAKE_SOURCE_DIR}/src/clang_options_data.zig" @@ -827,6 +829,12 @@ else() set(ZIG_STATIC_ARG "") endif() +if(CMAKE_POSITION_INDEPENDENT_CODE) + set(ZIG_PIE_ARG="-Dpie") +else() + set(ZIG_PIE_ARG="") +endif() + set(ZIG_BUILD_ARGS --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" "-Dconfig_h=${ZIG_CONFIG_H_OUT}" @@ -835,6 +843,7 @@ set(ZIG_BUILD_ARGS ${ZIG_STATIC_ARG} ${ZIG_NO_LIB_ARG} ${ZIG_SINGLE_THREADED_ARG} + ${ZIG_PIE_ARG} "-Dtarget=${ZIG_TARGET_TRIPLE}" "-Dcpu=${ZIG_TARGET_MCPU}" "-Dversion-string=${RESOLVED_ZIG_VERSION}" diff --git a/build.zig b/build.zig index 87b1b797ca..72db9ba749 100644 --- a/build.zig +++ b/build.zig @@ -31,6 +31,11 @@ pub fn build(b: *std.Build) !void { const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false; const test_step = b.step("test", "Run all the tests"); + const deprecated_skip_install_lib_files = b.option(bool, "skip-install-lib-files", "deprecated. see no-lib") orelse false; + if (deprecated_skip_install_lib_files) { + std.log.warn("-Dskip-install-lib-files is deprecated in favor of -Dno-lib", .{}); + } + const skip_install_lib_files = b.option(bool, "no-lib", "skip copying of lib/ files and langref to installation prefix. Useful for development") orelse deprecated_skip_install_lib_files; const docgen_exe = b.addExecutable(.{ .name = "docgen", @@ -40,28 +45,35 @@ pub fn build(b: *std.Build) !void { }); docgen_exe.single_threaded = single_threaded; - const langref_out_path = try b.cache_root.join(b.allocator, &.{"langref.html"}); - const docgen_cmd = docgen_exe.run(); - docgen_cmd.addArgs(&[_][]const u8{ - "--zig", - b.zig_exe, - "doc" ++ fs.path.sep_str ++ "langref.html.in", - langref_out_path, - }); - docgen_cmd.step.dependOn(&docgen_exe.step); + const docgen_cmd = b.addRunArtifact(docgen_exe); + docgen_cmd.addArgs(&.{ "--zig", b.zig_exe }); + if (b.zig_lib_dir) |p| { + docgen_cmd.addArgs(&.{ "--zig-lib-dir", p }); + } + docgen_cmd.addFileSourceArg(.{ .path = "doc/langref.html.in" }); + const langref_file = docgen_cmd.addOutputFileArg("langref.html"); + const install_langref = b.addInstallFileWithDir(langref_file, .prefix, "doc/langref.html"); + if (!skip_install_lib_files) { + b.getInstallStep().dependOn(&install_langref.step); + } const docs_step = b.step("docs", "Build documentation"); docs_step.dependOn(&docgen_cmd.step); - const test_cases = b.addTest(.{ - .root_source_file = .{ .path = "src/test.zig" }, + // This is for legacy reasons, to be removed after our CI scripts are upgraded to use + // the file from the install prefix instead. + const legacy_write_to_cache = b.addWriteFiles(); + legacy_write_to_cache.addCopyFileToSource(langref_file, "zig-cache/langref.html"); + docs_step.dependOn(&legacy_write_to_cache.step); + + const check_case_exe = b.addExecutable(.{ + .name = "check-case", + .root_source_file = .{ .path = "test/src/Cases.zig" }, .optimize = optimize, }); - test_cases.main_pkg_path = "."; - test_cases.stack_size = stack_size; - test_cases.single_threaded = single_threaded; - - const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"}); + check_case_exe.main_pkg_path = "."; + check_case_exe.stack_size = stack_size; + check_case_exe.single_threaded = single_threaded; const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false; const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false; @@ -74,11 +86,6 @@ pub fn build(b: *std.Build) !void { const skip_stage1 = b.option(bool, "skip-stage1", "Main test suite skips stage1 compile error tests") orelse false; const skip_run_translated_c = b.option(bool, "skip-run-translated-c", "Main test suite skips run-translated-c tests") orelse false; const skip_stage2_tests = b.option(bool, "skip-stage2-tests", "Main test suite skips self-hosted compiler tests") orelse false; - const deprecated_skip_install_lib_files = b.option(bool, "skip-install-lib-files", "deprecated. see no-lib") orelse false; - if (deprecated_skip_install_lib_files) { - std.log.warn("-Dskip-install-lib-files is deprecated in favor of -Dno-lib", .{}); - } - const skip_install_lib_files = b.option(bool, "no-lib", "skip copying of lib/ files to installation prefix. Useful for development") orelse deprecated_skip_install_lib_files; const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false; @@ -157,6 +164,7 @@ pub fn build(b: *std.Build) !void { const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse (enable_llvm or only_c); const sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") orelse false; const strip = b.option(bool, "strip", "Omit debug information"); + const pie = b.option(bool, "pie", "Produce a Position Independent Executable"); const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false; const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: { @@ -167,6 +175,7 @@ pub fn build(b: *std.Build) !void { const exe = addCompilerStep(b, optimize, target); exe.strip = strip; + exe.pie = pie; exe.sanitize_thread = sanitize_thread; exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false; exe.install(); @@ -178,13 +187,12 @@ pub fn build(b: *std.Build) !void { test_step.dependOn(&exe.step); } - b.default_step.dependOn(&exe.step); exe.single_threaded = single_threaded; if (target.isWindows() and target.getAbi() == .gnu) { // LTO is currently broken on mingw, this can be removed when it's fixed. exe.want_lto = false; - test_cases.want_lto = false; + check_case_exe.want_lto = false; } const exe_options = b.addOptions(); @@ -199,11 +207,11 @@ pub fn build(b: *std.Build) !void { exe_options.addOption(bool, "llvm_has_xtensa", llvm_has_xtensa); exe_options.addOption(bool, "force_gpa", force_gpa); exe_options.addOption(bool, "only_c", only_c); - exe_options.addOption(bool, "omit_pkg_fetching_code", false); + exe_options.addOption(bool, "omit_pkg_fetching_code", only_c); if (link_libc) { exe.linkLibC(); - test_cases.linkLibC(); + check_case_exe.linkLibC(); } const is_debug = optimize == .Debug; @@ -289,14 +297,14 @@ pub fn build(b: *std.Build) !void { } try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx); - try addCmakeCfgOptionsToExe(b, cfg, test_cases, use_zig_libcxx); + try addCmakeCfgOptionsToExe(b, cfg, check_case_exe, use_zig_libcxx); } else { // Here we are -Denable-llvm but no cmake integration. try addStaticLlvmOptionsToExe(exe); - try addStaticLlvmOptionsToExe(test_cases); + try addStaticLlvmOptionsToExe(check_case_exe); } if (target.isWindows()) { - inline for (.{ exe, test_cases }) |artifact| { + inline for (.{ exe, check_case_exe }) |artifact| { artifact.linkSystemLibrary("version"); artifact.linkSystemLibrary("uuid"); artifact.linkSystemLibrary("ole32"); @@ -341,8 +349,9 @@ pub fn build(b: *std.Build) !void { const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); const test_cases_options = b.addOptions(); - test_cases.addOptions("build_options", test_cases_options); + check_case_exe.addOptions("build_options", test_cases_options); + test_cases_options.addOption(bool, "enable_tracy", false); test_cases_options.addOption(bool, "enable_logging", enable_logging); test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots); test_cases_options.addOption(bool, "skip_non_native", skip_non_native); @@ -366,12 +375,6 @@ pub fn build(b: *std.Build) !void { test_cases_options.addOption(std.SemanticVersion, "semver", semver); test_cases_options.addOption(?[]const u8, "test_filter", test_filter); - const test_cases_step = b.step("test-cases", "Run the main compiler test cases"); - test_cases_step.dependOn(&test_cases.step); - if (!skip_stage2_tests) { - test_step.dependOn(test_cases_step); - } - var chosen_opt_modes_buf: [4]builtin.Mode = undefined; var chosen_mode_index: usize = 0; if (!skip_debug) { @@ -392,96 +395,101 @@ pub fn build(b: *std.Build) !void { } const optimization_modes = chosen_opt_modes_buf[0..chosen_mode_index]; - // run stage1 `zig fmt` on this build.zig file just to make sure it works - test_step.dependOn(&fmt_build_zig.step); - const fmt_step = b.step("test-fmt", "Run zig fmt against build.zig to make sure it works"); - fmt_step.dependOn(&fmt_build_zig.step); + const fmt_include_paths = &.{ "doc", "lib", "src", "test", "tools", "build.zig" }; + const fmt_exclude_paths = &.{"test/cases"}; + const do_fmt = b.addFmt(.{ + .paths = fmt_include_paths, + .exclude_paths = fmt_exclude_paths, + }); - test_step.dependOn(tests.addPkgTests( - b, - test_filter, - "test/behavior.zig", - "behavior", - "Run the behavior tests", - optimization_modes, - skip_single_threaded, - skip_non_native, - skip_libc, - skip_stage1, - skip_stage2_tests, - )); + b.step("test-fmt", "Check source files having conforming formatting").dependOn(&b.addFmt(.{ + .paths = fmt_include_paths, + .exclude_paths = fmt_exclude_paths, + .check = true, + }).step); - test_step.dependOn(tests.addPkgTests( - b, - test_filter, - "lib/compiler_rt.zig", - "compiler-rt", - "Run the compiler_rt tests", - optimization_modes, - true, // skip_single_threaded - skip_non_native, - true, // skip_libc - skip_stage1, - skip_stage2_tests or true, // TODO get these all passing - )); + const test_cases_step = b.step("test-cases", "Run the main compiler test cases"); + try tests.addCases(b, test_cases_step, test_filter, check_case_exe); + if (!skip_stage2_tests) test_step.dependOn(test_cases_step); - test_step.dependOn(tests.addPkgTests( - b, - test_filter, - "lib/c.zig", - "universal-libc", - "Run the universal libc tests", - optimization_modes, - true, // skip_single_threaded - skip_non_native, - true, // skip_libc - skip_stage1, - skip_stage2_tests or true, // TODO get these all passing - )); + test_step.dependOn(tests.addModuleTests(b, .{ + .test_filter = test_filter, + .root_src = "test/behavior.zig", + .name = "behavior", + .desc = "Run the behavior tests", + .optimize_modes = optimization_modes, + .skip_single_threaded = skip_single_threaded, + .skip_non_native = skip_non_native, + .skip_libc = skip_libc, + .skip_stage1 = skip_stage1, + .skip_stage2 = skip_stage2_tests, + .max_rss = 1 * 1024 * 1024 * 1024, + })); + + test_step.dependOn(tests.addModuleTests(b, .{ + .test_filter = test_filter, + .root_src = "lib/compiler_rt.zig", + .name = "compiler-rt", + .desc = "Run the compiler_rt tests", + .optimize_modes = optimization_modes, + .skip_single_threaded = true, + .skip_non_native = skip_non_native, + .skip_libc = true, + .skip_stage1 = skip_stage1, + .skip_stage2 = true, // TODO get all these passing + })); + + test_step.dependOn(tests.addModuleTests(b, .{ + .test_filter = test_filter, + .root_src = "lib/c.zig", + .name = "universal-libc", + .desc = "Run the universal libc tests", + .optimize_modes = optimization_modes, + .skip_single_threaded = true, + .skip_non_native = skip_non_native, + .skip_libc = true, + .skip_stage1 = skip_stage1, + .skip_stage2 = true, // TODO get all these passing + })); test_step.dependOn(tests.addCompareOutputTests(b, test_filter, optimization_modes)); test_step.dependOn(tests.addStandaloneTests( b, - test_filter, optimization_modes, - skip_non_native, enable_macos_sdk, - target, skip_stage2_tests, - b.enable_darling, - b.enable_qemu, - b.enable_rosetta, - b.enable_wasmtime, - b.enable_wine, enable_symlinks_windows, )); test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release)); - test_step.dependOn(tests.addLinkTests(b, test_filter, optimization_modes, enable_macos_sdk, skip_stage2_tests, enable_symlinks_windows)); + test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, skip_stage2_tests, enable_symlinks_windows)); test_step.dependOn(tests.addStackTraceTests(b, test_filter, optimization_modes)); - test_step.dependOn(tests.addCliTests(b, test_filter, optimization_modes)); + test_step.dependOn(tests.addCliTests(b)); test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, optimization_modes)); test_step.dependOn(tests.addTranslateCTests(b, test_filter)); if (!skip_run_translated_c) { test_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target)); } - // tests for this feature are disabled until we have the self-hosted compiler available - // test_step.dependOn(tests.addGenHTests(b, test_filter)); - test_step.dependOn(tests.addPkgTests( - b, - test_filter, - "lib/std/std.zig", - "std", - "Run the standard library tests", - optimization_modes, - skip_single_threaded, - skip_non_native, - skip_libc, - skip_stage1, - true, // TODO get these all passing - )); + test_step.dependOn(tests.addModuleTests(b, .{ + .test_filter = test_filter, + .root_src = "lib/std/std.zig", + .name = "std", + .desc = "Run the standard library tests", + .optimize_modes = optimization_modes, + .skip_single_threaded = skip_single_threaded, + .skip_non_native = skip_non_native, + .skip_libc = skip_libc, + .skip_stage1 = skip_stage1, + .skip_stage2 = true, // TODO get all these passing + // I observed a value of 3398275072 on my M1, and multiplied by 1.1 to + // get this amount: + .max_rss = 3738102579, + })); try addWasiUpdateStep(b, version); + + b.step("fmt", "Modify source files in place to have conforming formatting") + .dependOn(&do_fmt.step); } fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { @@ -510,6 +518,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { exe_options.addOption(bool, "enable_tracy_callstack", false); exe_options.addOption(bool, "enable_tracy_allocation", false); exe_options.addOption(bool, "value_tracing", false); + exe_options.addOption(bool, "omit_pkg_fetching_code", true); const run_opt = b.addSystemCommand(&.{ "wasm-opt", "-Oz", "--enable-bulk-memory" }); run_opt.addArtifactArg(exe); @@ -681,10 +690,7 @@ fn addCxxKnownPath( ) !void { if (!std.process.can_spawn) return error.RequiredLibraryNotFound; - const path_padded = try b.exec(&[_][]const u8{ - ctx.cxx_compiler, - b.fmt("-print-file-name={s}", .{objname}), - }); + const path_padded = b.exec(&.{ ctx.cxx_compiler, b.fmt("-print-file-name={s}", .{objname}) }); var tokenizer = mem.tokenize(u8, path_padded, "\r\n"); const path_unpadded = tokenizer.next().?; if (mem.eql(u8, path_unpadded, objname)) { diff --git a/ci/aarch64-linux-debug.sh b/ci/aarch64-linux-debug.sh index 2c0639763c..2fd831860e 100644 --- a/ci/aarch64-linux-debug.sh +++ b/ci/aarch64-linux-debug.sh @@ -67,7 +67,7 @@ stage3-debug/bin/zig build test docs \ --zig-lib-dir "$(pwd)/../lib" # Look for HTML errors. -tidy --drop-empty-elements no -qe "$ZIG_LOCAL_CACHE_DIR/langref.html" +tidy --drop-empty-elements no -qe "stage3-debug/doc/langref.html" # Produce the experimental std lib documentation. stage3-debug/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib @@ -98,3 +98,9 @@ unset CXX ninja install stage3/bin/zig test ../test/behavior.zig -I../test +stage3/bin/zig build -p stage4 \ + -Dstatic-llvm \ + -Dtarget=native-native-musl \ + --search-prefix "$PREFIX" \ + --zig-lib-dir "$(pwd)/../lib" +stage4/bin/zig test ../test/behavior.zig -I../test diff --git a/ci/aarch64-linux-release.sh b/ci/aarch64-linux-release.sh index 3992f62770..8eb9ed2523 100644 --- a/ci/aarch64-linux-release.sh +++ b/ci/aarch64-linux-release.sh @@ -67,7 +67,7 @@ stage3-release/bin/zig build test docs \ --zig-lib-dir "$(pwd)/../lib" # Look for HTML errors. -tidy --drop-empty-elements no -qe "$ZIG_LOCAL_CACHE_DIR/langref.html" +tidy --drop-empty-elements no -qe "stage3-release/doc/langref.html" # Produce the experimental std lib documentation. stage3-release/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib @@ -98,3 +98,9 @@ unset CXX ninja install stage3/bin/zig test ../test/behavior.zig -I../test +stage3/bin/zig build -p stage4 \ + -Dstatic-llvm \ + -Dtarget=native-native-musl \ + --search-prefix "$PREFIX" \ + --zig-lib-dir "$(pwd)/../lib" +stage4/bin/zig test ../test/behavior.zig -I../test diff --git a/ci/x86_64-linux-debug.sh b/ci/x86_64-linux-debug.sh index ddcc76af7d..3ae72f7ef5 100755 --- a/ci/x86_64-linux-debug.sh +++ b/ci/x86_64-linux-debug.sh @@ -66,7 +66,7 @@ stage3-debug/bin/zig build test docs \ --zig-lib-dir "$(pwd)/../lib" # Look for HTML errors. -tidy --drop-empty-elements no -qe "$ZIG_LOCAL_CACHE_DIR/langref.html" +tidy --drop-empty-elements no -qe "stage3-debug/doc/langref.html" # Produce the experimental std lib documentation. stage3-debug/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib @@ -97,3 +97,9 @@ unset CXX ninja install stage3/bin/zig test ../test/behavior.zig -I../test +stage3/bin/zig build -p stage4 \ + -Dstatic-llvm \ + -Dtarget=native-native-musl \ + --search-prefix "$PREFIX" \ + --zig-lib-dir "$(pwd)/../lib" +stage4/bin/zig test ../test/behavior.zig -I../test diff --git a/ci/x86_64-linux-release.sh b/ci/x86_64-linux-release.sh index d3da4991e2..f8b94addcc 100755 --- a/ci/x86_64-linux-release.sh +++ b/ci/x86_64-linux-release.sh @@ -67,7 +67,7 @@ stage3-release/bin/zig build test docs \ --zig-lib-dir "$(pwd)/../lib" # Look for HTML errors. -tidy --drop-empty-elements no -qe "$ZIG_LOCAL_CACHE_DIR/langref.html" +tidy --drop-empty-elements no -qe "stage3-release/doc/langref.html" # Produce the experimental std lib documentation. stage3-release/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib @@ -114,3 +114,9 @@ unset CXX ninja install stage3/bin/zig test ../test/behavior.zig -I../test +stage3/bin/zig build -p stage4 \ + -Dstatic-llvm \ + -Dtarget=native-native-musl \ + --search-prefix "$PREFIX" \ + --zig-lib-dir "$(pwd)/../lib" +stage4/bin/zig test ../test/behavior.zig -I../test diff --git a/doc/docgen.zig b/doc/docgen.zig index fae513f8c3..277316dd37 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -28,10 +28,10 @@ const usage = \\ ; -fn errorf(comptime format: []const u8, args: anytype) noreturn { +fn fatal(comptime format: []const u8, args: anytype) noreturn { const stderr = io.getStdErr().writer(); - stderr.print("error: " ++ format, args) catch {}; + stderr.print("error: " ++ format ++ "\n", args) catch {}; process.exit(1); } @@ -45,6 +45,7 @@ pub fn main() !void { if (!args_it.skip()) @panic("expected self arg"); var zig_exe: []const u8 = "zig"; + var opt_zig_lib_dir: ?[]const u8 = null; var do_code_tests = true; var files = [_][]const u8{ "", "" }; @@ -59,24 +60,29 @@ pub fn main() !void { if (args_it.next()) |param| { zig_exe = param; } else { - errorf("expected parameter after --zig\n", .{}); + fatal("expected parameter after --zig", .{}); + } + } else if (mem.eql(u8, arg, "--zig-lib-dir")) { + if (args_it.next()) |param| { + opt_zig_lib_dir = param; + } else { + fatal("expected parameter after --zig-lib-dir", .{}); } } else if (mem.eql(u8, arg, "--skip-code-tests")) { do_code_tests = false; } else { - errorf("unrecognized option: '{s}'\n", .{arg}); + fatal("unrecognized option: '{s}'", .{arg}); } } else { if (i > 1) { - errorf("too many arguments\n", .{}); + fatal("too many arguments", .{}); } files[i] = arg; i += 1; } } if (i < 2) { - errorf("not enough arguments\n", .{}); - process.exit(1); + fatal("not enough arguments", .{}); } var in_file = try fs.cwd().openFile(files[0], .{ .mode = .read_only }); @@ -95,7 +101,7 @@ pub fn main() !void { try fs.cwd().makePath(tmp_dir_name); defer fs.cwd().deleteTree(tmp_dir_name) catch {}; - try genHtml(allocator, &tokenizer, &toc, buffered_writer.writer(), zig_exe, do_code_tests); + try genHtml(allocator, &tokenizer, &toc, buffered_writer.writer(), zig_exe, opt_zig_lib_dir, do_code_tests); try buffered_writer.flush(); } @@ -1268,9 +1274,10 @@ fn genHtml( toc: *Toc, out: anytype, zig_exe: []const u8, + opt_zig_lib_dir: ?[]const u8, do_code_tests: bool, ) !void { - var progress = Progress{}; + var progress = Progress{ .dont_print_on_dumb = true }; const root_node = progress.start("Generating docgen examples", toc.nodes.len); defer root_node.end(); @@ -1278,7 +1285,7 @@ fn genHtml( try env_map.put("ZIG_DEBUG_COLOR", "1"); const host = try std.zig.system.NativeTargetInfo.detect(.{}); - const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe); + const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe, opt_zig_lib_dir); for (toc.nodes) |node| { defer root_node.completeOne(); @@ -1370,6 +1377,9 @@ fn genHtml( "--color", "on", "--enable-cache", tmp_source_file_name, }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try build_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } try shell_out.print("$ zig build-exe {s} ", .{name_plus_ext}); @@ -1512,8 +1522,12 @@ fn genHtml( defer test_args.deinit(); try test_args.appendSlice(&[_][]const u8{ - zig_exe, "test", tmp_source_file_name, + zig_exe, "test", + tmp_source_file_name, }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try test_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } try shell_out.print("$ zig test {s}.zig ", .{code.name}); switch (code.mode) { @@ -1564,12 +1578,13 @@ fn genHtml( defer test_args.deinit(); try test_args.appendSlice(&[_][]const u8{ - zig_exe, - "test", - "--color", - "on", + zig_exe, "test", + "--color", "on", tmp_source_file_name, }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try test_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } try shell_out.print("$ zig test {s}.zig ", .{code.name}); switch (code.mode) { @@ -1624,8 +1639,12 @@ fn genHtml( defer test_args.deinit(); try test_args.appendSlice(&[_][]const u8{ - zig_exe, "test", tmp_source_file_name, + zig_exe, "test", + tmp_source_file_name, }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try test_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } var mode_arg: []const u8 = ""; switch (code.mode) { .Debug => {}, @@ -1684,17 +1703,17 @@ fn genHtml( defer build_args.deinit(); try build_args.appendSlice(&[_][]const u8{ - zig_exe, - "build-obj", + zig_exe, "build-obj", + "--color", "on", + "--name", code.name, tmp_source_file_name, - "--color", - "on", - "--name", - code.name, try std.fmt.allocPrint(allocator, "-femit-bin={s}{c}{s}", .{ tmp_dir_name, fs.path.sep, name_plus_obj_ext, }), }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try build_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } try shell_out.print("$ zig build-obj {s}.zig ", .{code.name}); @@ -1758,13 +1777,15 @@ fn genHtml( defer test_args.deinit(); try test_args.appendSlice(&[_][]const u8{ - zig_exe, - "build-lib", + zig_exe, "build-lib", tmp_source_file_name, try std.fmt.allocPrint(allocator, "-femit-bin={s}{s}{s}", .{ tmp_dir_name, fs.path.sep_str, bin_basename, }), }); + if (opt_zig_lib_dir) |zig_lib_dir| { + try test_args.appendSlice(&.{ "--zig-lib-dir", zig_lib_dir }); + } try shell_out.print("$ zig build-lib {s}.zig ", .{code.name}); switch (code.mode) { @@ -1829,9 +1850,23 @@ fn exec(allocator: Allocator, env_map: *process.EnvMap, args: []const []const u8 return result; } -fn getBuiltinCode(allocator: Allocator, env_map: *process.EnvMap, zig_exe: []const u8) ![]const u8 { - const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" }); - return result.stdout; +fn getBuiltinCode( + allocator: Allocator, + env_map: *process.EnvMap, + zig_exe: []const u8, + opt_zig_lib_dir: ?[]const u8, +) ![]const u8 { + if (opt_zig_lib_dir) |zig_lib_dir| { + const result = try exec(allocator, env_map, &.{ + zig_exe, "build-obj", "--show-builtin", "--zig-lib-dir", zig_lib_dir, + }); + return result.stdout; + } else { + const result = try exec(allocator, env_map, &.{ + zig_exe, "build-obj", "--show-builtin", + }); + return result.stdout; + } } fn dumpArgs(args: []const []const u8) void { diff --git a/doc/langref.html.in b/doc/langref.html.in index e016ef13f8..991fd0c3e6 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7457,20 +7457,20 @@ pub const STDOUT_FILENO = 1; pub fn syscall1(number: usize, arg1: usize) usize { return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) + : [ret] "={rax}" (-> usize), : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1) + [arg1] "{rdi}" (arg1), : "rcx", "r11" ); } pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) + : [ret] "={rax}" (-> usize), : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3) + [arg3] "{rdx}" (arg3), : "rcx", "r11" ); } @@ -7519,14 +7519,14 @@ pub fn syscall1(number: usize, arg1: usize) usize { // type is the result type of the inline assembly expression. // If it is a value binding, then `%[ret]` syntax would be used // to refer to the register bound to the value. - (-> usize) + (-> usize), // Next is the list of inputs. // The constraint for these inputs means, "when the assembly code is // executed, $rax shall have the value of `number` and $rdi shall have // the value of `arg1`". Any number of input parameters is allowed, // including none. : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1) + [arg1] "{rdi}" (arg1), // Next is the list of clobbers. These declare a set of registers whose // values will not be preserved by the execution of this assembly code. // These do not include output or input registers. The special clobber @@ -7818,12 +7818,14 @@ comptime {

This function inserts a platform-specific debug trap instruction which causes debuggers to break there. + Unlike for {#syntax#}@trap(){#endsyntax#}, execution may continue after this point if the program is resumed.

This function is only valid within function scope.

- + {#see_also|@trap#} {#header_close#} + {#header_open|@mulAdd#}
{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}

@@ -9393,6 +9395,19 @@ fn List(comptime T: type) type {

{#header_close#} + {#header_open|@trap#} +
{#syntax#}@trap() noreturn{#endsyntax#}
+

+ This function inserts a platform-specific trap/jam instruction which can be used to exit the program abnormally. + This may be implemented by explicitly emitting an invalid instruction which may cause an illegal instruction exception of some sort. + Unlike for {#syntax#}@breakpoint(){#endsyntax#}, execution does not continue after this point. +

+

+ Outside function scope, this builtin causes a compile error. +

+ {#see_also|@breakpoint#} + {#header_close#} + {#header_open|@truncate#}
{#syntax#}@truncate(comptime T: type, integer: anytype) T{#endsyntax#}

@@ -9565,9 +9580,10 @@ pub fn build(b: *std.Build) void { This causes these options to be available:

-
-Drelease-safe=[bool]
Optimizations on and safety on
-
-Drelease-fast=[bool]
Optimizations on and safety off
-
-Drelease-small=[bool]
Size optimizations on and safety off
+
-Doptimize=Debug
Optimizations off and safety on (default)
+
-Doptimize=ReleaseSafe
Optimizations on and safety on
+
-Doptimize=ReleaseFast
Optimizations on and safety off
+
-Doptimize=ReleaseSmall
Size optimizations on and safety off
{#header_open|Debug#} {#shell_samp#}$ zig build-exe example.zig{#end_shell_samp#} @@ -9788,8 +9804,8 @@ pub fn main() !void { {#header_close#} {#header_open|Builtin Overflow Functions#}

- These builtins return a {#syntax#}bool{#endsyntax#} of whether or not overflow - occurred, as well as returning the overflowed bits: + These builtins return a tuple containing whether there was an overflow + (as a {#syntax#}u1{#endsyntax#}) and the possibly overflowed bits of the operation: