| author | |
| committer | |
| log | 24a9a42966dc9c0654314ad99866699208776025 |
| tree | 338bbf5f3aa39700e08eda107194b3ce93958059 |
| parent | 7c236f6dd8194500f459b48621e2eb1997563caf |
closes #28811 files changed, 151 insertions(+), 89 deletions(-)
src/all_types.hpp+7-1| ... | ... | @@ -1297,6 +1297,12 @@ struct TimeEvent { |
| 1297 | 1297 | const char *name; |
| 1298 | 1298 | }; |
| 1299 | 1299 | |
| 1300 | enum BuildMode { | |
| 1301 | BuildModeDebug, | |
| 1302 | BuildModeFastRelease, | |
| 1303 | BuildModeSafeRelease, | |
| 1304 | }; | |
| 1305 | ||
| 1300 | 1306 | struct CodeGen { |
| 1301 | 1307 | LLVMModuleRef module; |
| 1302 | 1308 | ZigList<ErrorMsg*> errors; |
| ... | ... | @@ -1392,7 +1398,7 @@ struct CodeGen { |
| 1392 | 1398 | Buf *dynamic_linker; |
| 1393 | 1399 | Buf *ar_path; |
| 1394 | 1400 | Buf triple_str; |
| 1395 | bool is_release_build; | |
| 1401 | BuildMode build_mode; | |
| 1396 | 1402 | bool is_test_build; |
| 1397 | 1403 | uint32_t target_os_index; |
| 1398 | 1404 | uint32_t target_arch_index; |
src/codegen.cpp+29-17| ... | ... | @@ -55,11 +55,12 @@ static PackageTableEntry *new_package(const char *root_src_dir, const char *root |
| 55 | 55 | return entry; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type) { | |
| 58 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode) { | |
| 59 | 59 | CodeGen *g = allocate<CodeGen>(1); |
| 60 | 60 | |
| 61 | 61 | codegen_add_time_event(g, "Initialize"); |
| 62 | 62 | |
| 63 | g->build_mode = build_mode; | |
| 63 | 64 | g->out_type = out_type; |
| 64 | 65 | g->import_table.init(32); |
| 65 | 66 | g->builtin_fn_table.init(32); |
| ... | ... | @@ -72,7 +73,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 72 | 73 | g->memoized_fn_eval_table.init(16); |
| 73 | 74 | g->exported_symbol_names.init(8); |
| 74 | 75 | g->external_prototypes.init(8); |
| 75 | g->is_release_build = false; | |
| 76 | 76 | g->is_test_build = false; |
| 77 | 77 | g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); |
| 78 | 78 | |
| ... | ... | @@ -154,10 +154,6 @@ void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { |
| 154 | 154 | g->clang_argv_len = len; |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | void codegen_set_is_release(CodeGen *g, bool is_release_build) { | |
| 158 | g->is_release_build = is_release_build; | |
| 159 | } | |
| 160 | ||
| 161 | 157 | void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt) { |
| 162 | 158 | g->omit_zigrt = omit_zigrt; |
| 163 | 159 | } |
| ... | ... | @@ -393,7 +389,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 393 | 389 | } |
| 394 | 390 | |
| 395 | 391 | if (fn_table_entry->body_node != nullptr) { |
| 396 | bool want_fn_safety = !g->is_release_build && !fn_table_entry->def_scope->safety_off; | |
| 392 | bool want_fn_safety = g->build_mode != BuildModeFastRelease && !fn_table_entry->def_scope->safety_off; | |
| 397 | 393 | if (want_fn_safety) { |
| 398 | 394 | if (g->link_libc) { |
| 399 | 395 | addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong"); |
| ... | ... | @@ -407,7 +403,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 407 | 403 | ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value); |
| 408 | 404 | } |
| 409 | 405 | addLLVMFnAttr(fn_table_entry->llvm_value, "nounwind"); |
| 410 | if (!g->is_release_build && fn_table_entry->fn_inline != FnInlineAlways) { | |
| 406 | if (g->build_mode == BuildModeDebug && fn_table_entry->fn_inline != FnInlineAlways) { | |
| 411 | 407 | ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true"); |
| 412 | 408 | ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim-non-leaf", nullptr); |
| 413 | 409 | } |
| ... | ... | @@ -440,7 +436,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { |
| 440 | 436 | unsigned scope_line = line_number; |
| 441 | 437 | bool is_definition = fn_table_entry->body_node != nullptr; |
| 442 | 438 | unsigned flags = 0; |
| 443 | bool is_optimized = g->is_release_build; | |
| 439 | bool is_optimized = g->build_mode != BuildModeDebug; | |
| 444 | 440 | bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal); |
| 445 | 441 | ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, |
| 446 | 442 | get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "", |
| ... | ... | @@ -555,7 +551,7 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntr |
| 555 | 551 | } |
| 556 | 552 | |
| 557 | 553 | static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) { |
| 558 | if (g->is_release_build) | |
| 554 | if (g->build_mode == BuildModeFastRelease) | |
| 559 | 555 | return false; |
| 560 | 556 | |
| 561 | 557 | // TODO memoize |
| ... | ... | @@ -725,7 +721,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 725 | 721 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 726 | 722 | LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv); |
| 727 | 723 | addLLVMFnAttr(fn_val, "nounwind"); |
| 728 | if (!g->is_release_build) { | |
| 724 | if (g->build_mode == BuildModeDebug) { | |
| 729 | 725 | ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); |
| 730 | 726 | ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); |
| 731 | 727 | } |
| ... | ... | @@ -1697,7 +1693,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1697 | 1693 | if (!type_has_bits(var->value->type)) |
| 1698 | 1694 | return nullptr; |
| 1699 | 1695 | |
| 1700 | if (var->ref_count == 0 && g->is_release_build) | |
| 1696 | if (var->ref_count == 0 && g->build_mode != BuildModeDebug) | |
| 1701 | 1697 | return nullptr; |
| 1702 | 1698 | |
| 1703 | 1699 | IrInstruction *init_value = decl_var_instruction->init_value; |
| ... | ... | @@ -3926,7 +3922,7 @@ static void do_code_gen(CodeGen *g) { |
| 3926 | 3922 | os_path_join(g->cache_dir, o_basename, output_path); |
| 3927 | 3923 | ensure_cache_dir(g); |
| 3928 | 3924 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), |
| 3929 | LLVMObjectFile, &err_msg, !g->is_release_build)) | |
| 3925 | LLVMObjectFile, &err_msg, g->build_mode == BuildModeDebug)) | |
| 3930 | 3926 | { |
| 3931 | 3927 | zig_panic("unable to write object file: %s", err_msg); |
| 3932 | 3928 | } |
| ... | ... | @@ -4320,6 +4316,15 @@ static const char *bool_to_str(bool b) { |
| 4320 | 4316 | return b ? "true" : "false"; |
| 4321 | 4317 | } |
| 4322 | 4318 | |
| 4319 | static const char *build_mode_to_str(BuildMode build_mode) { | |
| 4320 | switch (build_mode) { | |
| 4321 | case BuildModeDebug: return "Mode.Debug"; | |
| 4322 | case BuildModeSafeRelease: return "Mode.ReleaseSafe"; | |
| 4323 | case BuildModeFastRelease: return "Mode.ReleaseFast"; | |
| 4324 | } | |
| 4325 | zig_unreachable(); | |
| 4326 | } | |
| 4327 | ||
| 4323 | 4328 | static void define_builtin_compile_vars(CodeGen *g) { |
| 4324 | 4329 | if (g->std_package == nullptr) |
| 4325 | 4330 | return; |
| ... | ... | @@ -4428,13 +4433,21 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 4428 | 4433 | " SeqCst,\n" |
| 4429 | 4434 | "};\n\n"); |
| 4430 | 4435 | } |
| 4436 | { | |
| 4437 | buf_appendf(contents, | |
| 4438 | "pub const Mode = enum {\n" | |
| 4439 | " Debug,\n" | |
| 4440 | " ReleaseSafe,\n" | |
| 4441 | " ReleaseFast,\n" | |
| 4442 | "};\n\n"); | |
| 4443 | } | |
| 4431 | 4444 | buf_appendf(contents, "pub const is_big_endian = %s;\n", bool_to_str(g->is_big_endian)); |
| 4432 | buf_appendf(contents, "pub const is_release = %s;\n", bool_to_str(g->is_release_build)); | |
| 4433 | 4445 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); |
| 4434 | 4446 | buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); |
| 4435 | 4447 | buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); |
| 4436 | 4448 | buf_appendf(contents, "pub const environ = Environ.%s;\n", cur_environ); |
| 4437 | 4449 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); |
| 4450 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); | |
| 4438 | 4451 | |
| 4439 | 4452 | { |
| 4440 | 4453 | buf_appendf(contents, "pub const link_libs = [][]const u8 {\n"); |
| ... | ... | @@ -4484,8 +4497,8 @@ static void init(CodeGen *g) { |
| 4484 | 4497 | zig_panic("unable to create target based on: %s", buf_ptr(&g->triple_str)); |
| 4485 | 4498 | } |
| 4486 | 4499 | |
| 4487 | ||
| 4488 | LLVMCodeGenOptLevel opt_level = g->is_release_build ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; | |
| 4500 | bool is_optimized = g->build_mode != BuildModeDebug; | |
| 4501 | LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; | |
| 4489 | 4502 | |
| 4490 | 4503 | LLVMRelocMode reloc_mode = g->is_static ? LLVMRelocStatic : LLVMRelocPIC; |
| 4491 | 4504 | |
| ... | ... | @@ -4518,7 +4531,6 @@ static void init(CodeGen *g) { |
| 4518 | 4531 | |
| 4519 | 4532 | |
| 4520 | 4533 | Buf *producer = buf_sprintf("zig %s", ZIG_VERSION_STRING); |
| 4521 | bool is_optimized = g->is_release_build; | |
| 4522 | 4534 | const char *flags = ""; |
| 4523 | 4535 | unsigned runtime_version = 0; |
| 4524 | 4536 | ZigLLVMDIFile *compile_unit_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(g->root_out_name), |
src/codegen.hpp+1-2| ... | ... | @@ -14,10 +14,9 @@ |
| 14 | 14 | |
| 15 | 15 | #include <stdio.h> |
| 16 | 16 | |
| 17 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type); | |
| 17 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode); | |
| 18 | 18 | |
| 19 | 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); | |
| 21 | 20 | void codegen_set_is_test(CodeGen *codegen, bool is_test); |
| 22 | 21 | void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); |
| 23 | 22 |
src/ir.cpp-1| ... | ... | @@ -4649,7 +4649,6 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 4649 | 4649 | if (init_value == irb->codegen->invalid_instruction) |
| 4650 | 4650 | return init_value; |
| 4651 | 4651 | |
| 4652 | ||
| 4653 | 4652 | IrInstruction *result = ir_build_var_decl(irb, scope, node, var, type_instruction, init_value); |
| 4654 | 4653 | var->decl_instruction = result; |
| 4655 | 4654 | return result; |
src/link.cpp+1-3| ... | ... | @@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 37 | 37 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); |
| 38 | 38 | |
| 39 | 39 | ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target; |
| 40 | CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj); | |
| 40 | CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj, parent_gen->build_mode); | |
| 41 | 41 | child_gen->link_libc = parent_gen->link_libc; |
| 42 | 42 | |
| 43 | 43 | child_gen->link_libs.resize(parent_gen->link_libs.length); |
| ... | ... | @@ -50,8 +50,6 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 50 | 50 | |
| 51 | 51 | codegen_set_cache_dir(child_gen, parent_gen->cache_dir); |
| 52 | 52 | |
| 53 | codegen_set_is_release(child_gen, parent_gen->is_release_build); | |
| 54 | ||
| 55 | 53 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 56 | 54 | codegen_set_is_static(child_gen, parent_gen->is_static); |
| 57 | 55 |
src/main.cpp+9-7| ... | ... | @@ -38,7 +38,8 @@ static int usage(const char *arg0) { |
| 38 | 38 | " --output-h [file] override generated header file path\n" |
| 39 | 39 | " --pkg-begin [name] [path] make package available to import and push current pkg\n" |
| 40 | 40 | " --pkg-end pop current pkg\n" |
| 41 | " --release build with optimizations on and debug protection off\n" | |
| 41 | " --release-fast build with optimizations on and safety off\n" | |
| 42 | " --release-safe build with optimizations on and safety on\n" | |
| 42 | 43 | " --static output will be statically linked\n" |
| 43 | 44 | " --strip exclude debug symbols\n" |
| 44 | 45 | " --target-arch [name] specify target architecture\n" |
| ... | ... | @@ -161,7 +162,6 @@ int main(int argc, char **argv) { |
| 161 | 162 | const char *in_file = nullptr; |
| 162 | 163 | const char *out_file = nullptr; |
| 163 | 164 | const char *out_file_h = nullptr; |
| 164 | bool is_release_build = false; | |
| 165 | 165 | bool strip = false; |
| 166 | 166 | bool is_static = false; |
| 167 | 167 | OutType out_type = OutTypeUnknown; |
| ... | ... | @@ -201,6 +201,7 @@ int main(int argc, char **argv) { |
| 201 | 201 | bool timing_info = false; |
| 202 | 202 | const char *cache_dir = nullptr; |
| 203 | 203 | CliPkg *cur_pkg = allocate<CliPkg>(1); |
| 204 | BuildMode build_mode = BuildModeDebug; | |
| 204 | 205 | |
| 205 | 206 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 206 | 207 | const char *zig_exe_path = arg0; |
| ... | ... | @@ -237,7 +238,7 @@ int main(int argc, char **argv) { |
| 237 | 238 | } |
| 238 | 239 | } |
| 239 | 240 | |
| 240 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe); | |
| 241 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug); | |
| 241 | 242 | codegen_set_out_name(g, buf_create_from_str("build")); |
| 242 | 243 | codegen_set_verbose(g, verbose); |
| 243 | 244 | |
| ... | ... | @@ -319,8 +320,10 @@ int main(int argc, char **argv) { |
| 319 | 320 | char *arg = argv[i]; |
| 320 | 321 | |
| 321 | 322 | if (arg[0] == '-') { |
| 322 | if (strcmp(arg, "--release") == 0) { | |
| 323 | is_release_build = true; | |
| 323 | if (strcmp(arg, "--release-fast") == 0) { | |
| 324 | build_mode = BuildModeFastRelease; | |
| 325 | } else if (strcmp(arg, "--release-safe") == 0) { | |
| 326 | build_mode = BuildModeSafeRelease; | |
| 324 | 327 | } else if (strcmp(arg, "--strip") == 0) { |
| 325 | 328 | strip = true; |
| 326 | 329 | } else if (strcmp(arg, "--static") == 0) { |
| ... | ... | @@ -569,10 +572,9 @@ int main(int argc, char **argv) { |
| 569 | 572 | buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir), |
| 570 | 573 | full_cache_dir); |
| 571 | 574 | |
| 572 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type); | |
| 575 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode); | |
| 573 | 576 | codegen_set_out_name(g, buf_out_name); |
| 574 | 577 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 575 | codegen_set_is_release(g, is_release_build); | |
| 576 | 578 | codegen_set_is_test(g, cmd == CmdTest); |
| 577 | 579 | codegen_set_linker_script(g, linker_script); |
| 578 | 580 | codegen_set_cache_dir(g, full_cache_dir); |
std/build.zig+69-35| ... | ... | @@ -405,6 +405,23 @@ pub const Builder = struct { |
| 405 | 405 | return &step_info.step; |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | pub fn standardReleaseOptions(self: &Builder) -> builtin.Mode { | |
| 409 | const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false; | |
| 410 | const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false; | |
| 411 | ||
| 412 | if (release_safe and !release_fast) { | |
| 413 | return builtin.Mode.ReleaseSafe; | |
| 414 | } else if (release_fast and !release_safe) { | |
| 415 | return builtin.Mode.ReleaseFast; | |
| 416 | } else if (!release_fast and !release_safe) { | |
| 417 | return builtin.Mode.Debug; | |
| 418 | } else { | |
| 419 | %%io.stderr.printf("Both -Drelease-safe and -Drelease-fast specified"); | |
| 420 | self.markInvalidUserInput(); | |
| 421 | return builtin.Mode.Debug; | |
| 422 | } | |
| 423 | } | |
| 424 | ||
| 408 | 425 | pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool { |
| 409 | 426 | test (%%self.user_input_options.put(name, UserInputOption { |
| 410 | 427 | .name = name, |
| ... | ... | @@ -667,7 +684,7 @@ pub const LibExeObjStep = struct { |
| 667 | 684 | linker_script: ?[]const u8, |
| 668 | 685 | link_libs: BufSet, |
| 669 | 686 | verbose: bool, |
| 670 | release: bool, | |
| 687 | build_mode: builtin.Mode, | |
| 671 | 688 | static: bool, |
| 672 | 689 | output_path: ?[]const u8, |
| 673 | 690 | output_h_path: ?[]const u8, |
| ... | ... | @@ -724,7 +741,7 @@ pub const LibExeObjStep = struct { |
| 724 | 741 | var self = LibExeObjStep { |
| 725 | 742 | .builder = builder, |
| 726 | 743 | .verbose = false, |
| 727 | .release = false, | |
| 744 | .build_mode = builtin.Mode.Debug, | |
| 728 | 745 | .static = static, |
| 729 | 746 | .kind = kind, |
| 730 | 747 | .root_src = root_src, |
| ... | ... | @@ -794,8 +811,8 @@ pub const LibExeObjStep = struct { |
| 794 | 811 | self.verbose = value; |
| 795 | 812 | } |
| 796 | 813 | |
| 797 | pub fn setRelease(self: &LibExeObjStep, value: bool) { | |
| 798 | self.release = value; | |
| 814 | pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) { | |
| 815 | self.build_mode = mode; | |
| 799 | 816 | } |
| 800 | 817 | |
| 801 | 818 | pub fn setOutputPath(self: &LibExeObjStep, value: []const u8) { |
| ... | ... | @@ -886,8 +903,10 @@ pub const LibExeObjStep = struct { |
| 886 | 903 | %%zig_args.append("--verbose"); |
| 887 | 904 | } |
| 888 | 905 | |
| 889 | if (self.release) { | |
| 890 | %%zig_args.append("--release"); | |
| 906 | switch (self.build_mode) { | |
| 907 | builtin.Mode.Debug => {}, | |
| 908 | builtin.Mode.ReleaseSafe => %%zig_args.append("--release-safe"), | |
| 909 | builtin.Mode.ReleaseFast => %%zig_args.append("--release-fast"), | |
| 891 | 910 | } |
| 892 | 911 | |
| 893 | 912 | %%zig_args.append("--cache-dir"); |
| ... | ... | @@ -980,7 +999,7 @@ pub const TestStep = struct { |
| 980 | 999 | step: Step, |
| 981 | 1000 | builder: &Builder, |
| 982 | 1001 | root_src: []const u8, |
| 983 | release: bool, | |
| 1002 | build_mode: builtin.Mode, | |
| 984 | 1003 | verbose: bool, |
| 985 | 1004 | link_libs: BufSet, |
| 986 | 1005 | name_prefix: []const u8, |
| ... | ... | @@ -992,7 +1011,7 @@ pub const TestStep = struct { |
| 992 | 1011 | .step = Step.init(step_name, builder.allocator, make), |
| 993 | 1012 | .builder = builder, |
| 994 | 1013 | .root_src = root_src, |
| 995 | .release = false, | |
| 1014 | .build_mode = builtin.Mode.Debug, | |
| 996 | 1015 | .verbose = false, |
| 997 | 1016 | .name_prefix = "", |
| 998 | 1017 | .filter = null, |
| ... | ... | @@ -1004,8 +1023,8 @@ pub const TestStep = struct { |
| 1004 | 1023 | self.verbose = value; |
| 1005 | 1024 | } |
| 1006 | 1025 | |
| 1007 | pub fn setRelease(self: &TestStep, value: bool) { | |
| 1008 | self.release = value; | |
| 1026 | pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) { | |
| 1027 | self.build_mode = mode; | |
| 1009 | 1028 | } |
| 1010 | 1029 | |
| 1011 | 1030 | pub fn linkSystemLibrary(self: &TestStep, name: []const u8) { |
| ... | ... | @@ -1034,8 +1053,10 @@ pub const TestStep = struct { |
| 1034 | 1053 | %%zig_args.append("--verbose"); |
| 1035 | 1054 | } |
| 1036 | 1055 | |
| 1037 | if (self.release) { | |
| 1038 | %%zig_args.append("--release"); | |
| 1056 | switch (self.build_mode) { | |
| 1057 | builtin.Mode.Debug => {}, | |
| 1058 | builtin.Mode.ReleaseSafe => %%zig_args.append("--release-safe"), | |
| 1059 | builtin.Mode.ReleaseFast => %%zig_args.append("--release-fast"), | |
| 1039 | 1060 | } |
| 1040 | 1061 | |
| 1041 | 1062 | test (self.filter) |filter| { |
| ... | ... | @@ -1095,6 +1116,8 @@ pub const CLibExeObjStep = struct { |
| 1095 | 1116 | name_only_filename: []const u8, |
| 1096 | 1117 | object_src: []const u8, |
| 1097 | 1118 | kind: Kind, |
| 1119 | build_mode: builtin.Mode, | |
| 1120 | strip: bool, | |
| 1098 | 1121 | |
| 1099 | 1122 | const Kind = enum { |
| 1100 | 1123 | Exe, |
| ... | ... | @@ -1147,6 +1170,8 @@ pub const CLibExeObjStep = struct { |
| 1147 | 1170 | .major_only_filename = undefined, |
| 1148 | 1171 | .name_only_filename = undefined, |
| 1149 | 1172 | .object_src = undefined, |
| 1173 | .build_mode = builtin.Mode.Debug, | |
| 1174 | .strip = false, | |
| 1150 | 1175 | }; |
| 1151 | 1176 | clib.computeOutFileNames(); |
| 1152 | 1177 | return clib; |
| ... | ... | @@ -1233,13 +1258,8 @@ pub const CLibExeObjStep = struct { |
| 1233 | 1258 | %%self.include_dirs.append(path); |
| 1234 | 1259 | } |
| 1235 | 1260 | |
| 1236 | pub fn addCompileFlagsForRelease(self: &CLibExeObjStep, release: bool) { | |
| 1237 | if (release) { | |
| 1238 | %%self.cflags.append("-g"); | |
| 1239 | %%self.cflags.append("-O2"); | |
| 1240 | } else { | |
| 1241 | %%self.cflags.append("-g"); | |
| 1242 | } | |
| 1261 | pub fn setBuildMode(self: &CLibExeObjStep, build_mode: builtin.Mode) { | |
| 1262 | self.build_mode = build_mode; | |
| 1243 | 1263 | } |
| 1244 | 1264 | |
| 1245 | 1265 | pub fn addCompileFlags(self: &CLibExeObjStep, flags: []const []const u8) { |
| ... | ... | @@ -1248,6 +1268,34 @@ pub const CLibExeObjStep = struct { |
| 1248 | 1268 | } |
| 1249 | 1269 | } |
| 1250 | 1270 | |
| 1271 | fn appendCompileFlags(self: &CLibExeObjStep, args: &List([]const u8)) { | |
| 1272 | if (!self.strip) { | |
| 1273 | %%args.append("-g"); | |
| 1274 | } | |
| 1275 | switch (self.build_mode) { | |
| 1276 | builtin.Mode.Debug => {}, | |
| 1277 | builtin.Mode.ReleaseSafe => { | |
| 1278 | %%args.append("-O2"); | |
| 1279 | %%args.append("-D_FORTIFY_SOURCE=2"); | |
| 1280 | %%args.append("-fstack-protector-strong"); | |
| 1281 | %%args.append("--param"); | |
| 1282 | %%args.append("ssp-buffer-size=4"); | |
| 1283 | }, | |
| 1284 | builtin.Mode.ReleaseFast => { | |
| 1285 | %%args.append("-O2"); | |
| 1286 | }, | |
| 1287 | } | |
| 1288 | ||
| 1289 | for (self.include_dirs.toSliceConst()) |dir| { | |
| 1290 | %%args.append("-I"); | |
| 1291 | %%args.append(self.builder.pathFromRoot(dir)); | |
| 1292 | } | |
| 1293 | ||
| 1294 | for (self.cflags.toSliceConst()) |cflag| { | |
| 1295 | %%args.append(cflag); | |
| 1296 | } | |
| 1297 | } | |
| 1298 | ||
| 1251 | 1299 | fn make(step: &Step) -> %void { |
| 1252 | 1300 | const self = @fieldParentPtr(CLibExeObjStep, "step", step); |
| 1253 | 1301 | const cc = os.getEnv("CC") ?? "cc"; |
| ... | ... | @@ -1265,14 +1313,7 @@ pub const CLibExeObjStep = struct { |
| 1265 | 1313 | %%cc_args.append("-o"); |
| 1266 | 1314 | %%cc_args.append(output_path); |
| 1267 | 1315 | |
| 1268 | for (self.cflags.toSliceConst()) |cflag| { | |
| 1269 | %%cc_args.append(cflag); | |
| 1270 | } | |
| 1271 | ||
| 1272 | for (self.include_dirs.toSliceConst()) |dir| { | |
| 1273 | %%cc_args.append("-I"); | |
| 1274 | %%cc_args.append(builder.pathFromRoot(dir)); | |
| 1275 | } | |
| 1316 | self.appendCompileFlags(&cc_args); | |
| 1276 | 1317 | |
| 1277 | 1318 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| 1278 | 1319 | }, |
| ... | ... | @@ -1295,14 +1336,7 @@ pub const CLibExeObjStep = struct { |
| 1295 | 1336 | %%cc_args.append("-o"); |
| 1296 | 1337 | %%cc_args.append(cache_o_file); |
| 1297 | 1338 | |
| 1298 | for (self.cflags.toSliceConst()) |cflag| { | |
| 1299 | %%cc_args.append(cflag); | |
| 1300 | } | |
| 1301 | ||
| 1302 | for (self.include_dirs.toSliceConst()) |dir| { | |
| 1303 | %%cc_args.append("-I"); | |
| 1304 | %%cc_args.append(builder.pathFromRoot(dir)); | |
| 1305 | } | |
| 1339 | self.appendCompileFlags(&cc_args); | |
| 1306 | 1340 | |
| 1307 | 1341 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| 1308 | 1342 |
std/hash_map.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ const mem = @import("mem.zig"); |
| 5 | 5 | const Allocator = mem.Allocator; |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | |
| 8 | const want_modification_safety = !builtin.is_release; | |
| 8 | const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast; | |
| 9 | 9 | const debug_u32 = if (want_modification_safety) u32 else void; |
| 10 | 10 | |
| 11 | 11 | pub fn HashMap(comptime K: type, comptime V: type, |
std/special/build_file_template.zig+12-2| ... | ... | @@ -1,10 +1,20 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | const Mode = @import("builtin").Mode; | |
| 2 | 3 | |
| 3 | 4 | pub fn build(b: &Builder) { |
| 4 | const release = b.option(bool, "release", "optimizations on and safety off") ?? false; | |
| 5 | const release_safe = b.option(bool, "--release-safe", "optimizations on and safety on") ?? false; | |
| 6 | const release_fast = b.option(bool, "--release-fast", "optimizations on and safety off") ?? false; | |
| 7 | ||
| 8 | const build_mode = if (release_safe) { | |
| 9 | Mode.ReleaseSafe | |
| 10 | } else if (release_fast) { | |
| 11 | Mode.ReleaseFast | |
| 12 | } else { | |
| 13 | Mode.Debug | |
| 14 | }; | |
| 5 | 15 | |
| 6 | 16 | const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig"); |
| 7 | exe.setRelease(release); | |
| 17 | exe.setBuildMode(build_mode); | |
| 8 | 18 | |
| 9 | 19 | b.default_step.dependOn(&exe.step); |
| 10 | 20 | } |
std/special/builtin.zig+1-1| ... | ... | @@ -32,7 +32,7 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | export fn __stack_chk_fail() { |
| 35 | if (builtin.is_release) { | |
| 35 | if (builtin.mode == builtin.Mode.ReleaseFast) { | |
| 36 | 36 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); |
| 37 | 37 | unreachable; |
| 38 | 38 | } |
test/tests.zig+21-19| ... | ... | @@ -9,6 +9,7 @@ const io = std.io; |
| 9 | 9 | const mem = std.mem; |
| 10 | 10 | const fmt = std.fmt; |
| 11 | 11 | const List = std.list.List; |
| 12 | const Mode = @import("builtin").Mode; | |
| 12 | 13 | |
| 13 | 14 | const compare_output = @import("compare_output.zig"); |
| 14 | 15 | const build_examples = @import("build_examples.zig"); |
| ... | ... | @@ -107,14 +108,13 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons |
| 107 | 108 | name:[] const u8, desc: []const u8) -> &build.Step |
| 108 | 109 | { |
| 109 | 110 | const step = b.step(b.fmt("test-{}", name), desc); |
| 110 | for ([]bool{false, true}) |release| { | |
| 111 | for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| { | |
| 111 | 112 | for ([]bool{false, true}) |link_libc| { |
| 112 | 113 | const these_tests = b.addTest(root_src); |
| 113 | these_tests.setNamePrefix(b.fmt("{}-{}-{} ", name, | |
| 114 | if (release) "release" else "debug", | |
| 114 | these_tests.setNamePrefix(b.fmt("{}-{}-{} ", name, @enumTagName(mode), | |
| 115 | 115 | if (link_libc) "c" else "bare")); |
| 116 | 116 | these_tests.setFilter(test_filter); |
| 117 | these_tests.setRelease(release); | |
| 117 | these_tests.setBuildMode(mode); | |
| 118 | 118 | if (link_libc) { |
| 119 | 119 | these_tests.linkSystemLibrary("c"); |
| 120 | 120 | } |
| ... | ... | @@ -372,9 +372,9 @@ pub const CompareOutputContext = struct { |
| 372 | 372 | self.step.dependOn(&run_and_cmp_output.step); |
| 373 | 373 | }, |
| 374 | 374 | Special.None => { |
| 375 | for ([]bool{false, true}) |release| { | |
| 375 | for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| { | |
| 376 | 376 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})", |
| 377 | "compare-output", case.name, if (release) "release" else "debug"); | |
| 377 | "compare-output", case.name, @enumTagName(mode)); | |
| 378 | 378 | test (self.test_filter) |filter| { |
| 379 | 379 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 380 | 380 | continue; |
| ... | ... | @@ -382,7 +382,7 @@ pub const CompareOutputContext = struct { |
| 382 | 382 | |
| 383 | 383 | const exe = b.addExecutable("test", root_src); |
| 384 | 384 | exe.setOutputPath(exe_path); |
| 385 | exe.setRelease(release); | |
| 385 | exe.setBuildMode(mode); | |
| 386 | 386 | if (case.link_libc) { |
| 387 | 387 | exe.linkSystemLibrary("c"); |
| 388 | 388 | } |
| ... | ... | @@ -465,10 +465,10 @@ pub const CompileErrorContext = struct { |
| 465 | 465 | name: []const u8, |
| 466 | 466 | test_index: usize, |
| 467 | 467 | case: &const TestCase, |
| 468 | release: bool, | |
| 468 | build_mode: Mode, | |
| 469 | 469 | |
| 470 | 470 | pub fn create(context: &CompileErrorContext, name: []const u8, |
| 471 | case: &const TestCase, release: bool) -> &CompileCmpOutputStep | |
| 471 | case: &const TestCase, build_mode: Mode) -> &CompileCmpOutputStep | |
| 472 | 472 | { |
| 473 | 473 | const allocator = context.b.allocator; |
| 474 | 474 | const ptr = %%allocator.create(CompileCmpOutputStep); |
| ... | ... | @@ -478,7 +478,7 @@ pub const CompileErrorContext = struct { |
| 478 | 478 | .name = name, |
| 479 | 479 | .test_index = context.test_index, |
| 480 | 480 | .case = case, |
| 481 | .release = release, | |
| 481 | .build_mode = build_mode, | |
| 482 | 482 | }; |
| 483 | 483 | context.test_index += 1; |
| 484 | 484 | return ptr; |
| ... | ... | @@ -501,8 +501,10 @@ pub const CompileErrorContext = struct { |
| 501 | 501 | %%zig_args.append("--output"); |
| 502 | 502 | %%zig_args.append(b.pathFromRoot(obj_path)); |
| 503 | 503 | |
| 504 | if (self.release) { | |
| 505 | %%zig_args.append("--release"); | |
| 504 | switch (self.build_mode) { | |
| 505 | Mode.Debug => {}, | |
| 506 | Mode.ReleaseSafe => %%zig_args.append("--release-safe"), | |
| 507 | Mode.ReleaseFast => %%zig_args.append("--release-fast"), | |
| 506 | 508 | } |
| 507 | 509 | |
| 508 | 510 | %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); |
| ... | ... | @@ -620,15 +622,15 @@ pub const CompileErrorContext = struct { |
| 620 | 622 | pub fn addCase(self: &CompileErrorContext, case: &const TestCase) { |
| 621 | 623 | const b = self.b; |
| 622 | 624 | |
| 623 | for ([]bool{false, true}) |release| { | |
| 625 | for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| { | |
| 624 | 626 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})", |
| 625 | case.name, if (release) "release" else "debug"); | |
| 627 | case.name, @enumTagName(mode)); | |
| 626 | 628 | test (self.test_filter) |filter| { |
| 627 | 629 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 628 | 630 | continue; |
| 629 | 631 | } |
| 630 | 632 | |
| 631 | const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, release); | |
| 633 | const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode); | |
| 632 | 634 | self.step.dependOn(&compile_and_cmp_errors.step); |
| 633 | 635 | |
| 634 | 636 | for (case.sources.toSliceConst()) |src_file| { |
| ... | ... | @@ -657,7 +659,7 @@ pub const BuildExamplesContext = struct { |
| 657 | 659 | pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) { |
| 658 | 660 | const b = self.b; |
| 659 | 661 | |
| 660 | const annotated_case_name = b.fmt("build {} (debug)", build_file); | |
| 662 | const annotated_case_name = b.fmt("build {} (Debug)", build_file); | |
| 661 | 663 | test (self.test_filter) |filter| { |
| 662 | 664 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 663 | 665 | return; |
| ... | ... | @@ -686,16 +688,16 @@ pub const BuildExamplesContext = struct { |
| 686 | 688 | pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) { |
| 687 | 689 | const b = self.b; |
| 688 | 690 | |
| 689 | for ([]bool{false, true}) |release| { | |
| 691 | for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| { | |
| 690 | 692 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})", |
| 691 | root_src, if (release) "release" else "debug"); | |
| 693 | root_src, @enumTagName(mode)); | |
| 692 | 694 | test (self.test_filter) |filter| { |
| 693 | 695 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| 694 | 696 | continue; |
| 695 | 697 | } |
| 696 | 698 | |
| 697 | 699 | const exe = b.addExecutable("test", root_src); |
| 698 | exe.setRelease(release); | |
| 700 | exe.setBuildMode(mode); | |
| 699 | 701 | if (link_libc) { |
| 700 | 702 | exe.linkSystemLibrary("c"); |
| 701 | 703 | } |