authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-02 17:34:21-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-02 17:34:21-04:00
log24a9a42966dc9c0654314ad99866699208776025
tree338bbf5f3aa39700e08eda107194b3ce93958059
parent7c236f6dd8194500f459b48621e2eb1997563caf

add safe release build mode

closes #288

11 files changed, 151 insertions(+), 89 deletions(-)

src/all_types.hpp+7-1
......@@ -1297,6 +1297,12 @@ struct TimeEvent {
12971297 const char *name;
12981298};
12991299
1300enum BuildMode {
1301 BuildModeDebug,
1302 BuildModeFastRelease,
1303 BuildModeSafeRelease,
1304};
1305
13001306struct CodeGen {
13011307 LLVMModuleRef module;
13021308 ZigList<ErrorMsg*> errors;
......@@ -1392,7 +1398,7 @@ struct CodeGen {
13921398 Buf *dynamic_linker;
13931399 Buf *ar_path;
13941400 Buf triple_str;
1395 bool is_release_build;
1401 BuildMode build_mode;
13961402 bool is_test_build;
13971403 uint32_t target_os_index;
13981404 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
5555 return entry;
5656}
5757
58CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type) {
58CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode) {
5959 CodeGen *g = allocate<CodeGen>(1);
6060
6161 codegen_add_time_event(g, "Initialize");
6262
63 g->build_mode = build_mode;
6364 g->out_type = out_type;
6465 g->import_table.init(32);
6566 g->builtin_fn_table.init(32);
......@@ -72,7 +73,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
7273 g->memoized_fn_eval_table.init(16);
7374 g->exported_symbol_names.init(8);
7475 g->external_prototypes.init(8);
75 g->is_release_build = false;
7676 g->is_test_build = false;
7777 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
7878
......@@ -154,10 +154,6 @@ void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {
154154 g->clang_argv_len = len;
155155}
156156
157void codegen_set_is_release(CodeGen *g, bool is_release_build) {
158 g->is_release_build = is_release_build;
159}
160
161157void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt) {
162158 g->omit_zigrt = omit_zigrt;
163159}
......@@ -393,7 +389,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
393389 }
394390
395391 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;
397393 if (want_fn_safety) {
398394 if (g->link_libc) {
399395 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
......@@ -407,7 +403,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
407403 ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
408404 }
409405 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) {
411407 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true");
412408 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim-non-leaf", nullptr);
413409 }
......@@ -440,7 +436,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
440436 unsigned scope_line = line_number;
441437 bool is_definition = fn_table_entry->body_node != nullptr;
442438 unsigned flags = 0;
443 bool is_optimized = g->is_release_build;
439 bool is_optimized = g->build_mode != BuildModeDebug;
444440 bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal);
445441 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
446442 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
555551}
556552
557553static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
558 if (g->is_release_build)
554 if (g->build_mode == BuildModeFastRelease)
559555 return false;
560556
561557 // TODO memoize
......@@ -725,7 +721,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
725721 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
726722 LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv);
727723 addLLVMFnAttr(fn_val, "nounwind");
728 if (!g->is_release_build) {
724 if (g->build_mode == BuildModeDebug) {
729725 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
730726 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
731727 }
......@@ -1697,7 +1693,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
16971693 if (!type_has_bits(var->value->type))
16981694 return nullptr;
16991695
1700 if (var->ref_count == 0 && g->is_release_build)
1696 if (var->ref_count == 0 && g->build_mode != BuildModeDebug)
17011697 return nullptr;
17021698
17031699 IrInstruction *init_value = decl_var_instruction->init_value;
......@@ -3926,7 +3922,7 @@ static void do_code_gen(CodeGen *g) {
39263922 os_path_join(g->cache_dir, o_basename, output_path);
39273923 ensure_cache_dir(g);
39283924 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))
39303926 {
39313927 zig_panic("unable to write object file: %s", err_msg);
39323928 }
......@@ -4320,6 +4316,15 @@ static const char *bool_to_str(bool b) {
43204316 return b ? "true" : "false";
43214317}
43224318
4319static 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
43234328static void define_builtin_compile_vars(CodeGen *g) {
43244329 if (g->std_package == nullptr)
43254330 return;
......@@ -4428,13 +4433,21 @@ static void define_builtin_compile_vars(CodeGen *g) {
44284433 " SeqCst,\n"
44294434 "};\n\n");
44304435 }
4436 {
4437 buf_appendf(contents,
4438 "pub const Mode = enum {\n"
4439 " Debug,\n"
4440 " ReleaseSafe,\n"
4441 " ReleaseFast,\n"
4442 "};\n\n");
4443 }
44314444 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));
44334445 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
44344446 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
44354447 buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
44364448 buf_appendf(contents, "pub const environ = Environ.%s;\n", cur_environ);
44374449 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));
44384451
44394452 {
44404453 buf_appendf(contents, "pub const link_libs = [][]const u8 {\n");
......@@ -4484,8 +4497,8 @@ static void init(CodeGen *g) {
44844497 zig_panic("unable to create target based on: %s", buf_ptr(&g->triple_str));
44854498 }
44864499
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;
44894502
44904503 LLVMRelocMode reloc_mode = g->is_static ? LLVMRelocStatic : LLVMRelocPIC;
44914504
......@@ -4518,7 +4531,6 @@ static void init(CodeGen *g) {
45184531
45194532
45204533 Buf *producer = buf_sprintf("zig %s", ZIG_VERSION_STRING);
4521 bool is_optimized = g->is_release_build;
45224534 const char *flags = "";
45234535 unsigned runtime_version = 0;
45244536 ZigLLVMDIFile *compile_unit_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(g->root_out_name),
src/codegen.hpp+1-2
......@@ -14,10 +14,9 @@
1414
1515#include <stdio.h>
1616
17CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type);
17CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode);
1818
1919void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
20void codegen_set_is_release(CodeGen *codegen, bool is_release);
2120void codegen_set_is_test(CodeGen *codegen, bool is_test);
2221void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2322
src/ir.cpp-1
......@@ -4649,7 +4649,6 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
46494649 if (init_value == irb->codegen->invalid_instruction)
46504650 return init_value;
46514651
4652
46534652 IrInstruction *result = ir_build_var_decl(irb, scope, node, var, type_instruction, init_value);
46544653 var->decl_instruction = result;
46554654 return result;
src/link.cpp+1-3
......@@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
3737 os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
3838
3939 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);
4141 child_gen->link_libc = parent_gen->link_libc;
4242
4343 child_gen->link_libs.resize(parent_gen->link_libs.length);
......@@ -50,8 +50,6 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
5050
5151 codegen_set_cache_dir(child_gen, parent_gen->cache_dir);
5252
53 codegen_set_is_release(child_gen, parent_gen->is_release_build);
54
5553 codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
5654 codegen_set_is_static(child_gen, parent_gen->is_static);
5755
src/main.cpp+9-7
......@@ -38,7 +38,8 @@ static int usage(const char *arg0) {
3838 " --output-h [file] override generated header file path\n"
3939 " --pkg-begin [name] [path] make package available to import and push current pkg\n"
4040 " --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"
4243 " --static output will be statically linked\n"
4344 " --strip exclude debug symbols\n"
4445 " --target-arch [name] specify target architecture\n"
......@@ -161,7 +162,6 @@ int main(int argc, char **argv) {
161162 const char *in_file = nullptr;
162163 const char *out_file = nullptr;
163164 const char *out_file_h = nullptr;
164 bool is_release_build = false;
165165 bool strip = false;
166166 bool is_static = false;
167167 OutType out_type = OutTypeUnknown;
......@@ -201,6 +201,7 @@ int main(int argc, char **argv) {
201201 bool timing_info = false;
202202 const char *cache_dir = nullptr;
203203 CliPkg *cur_pkg = allocate<CliPkg>(1);
204 BuildMode build_mode = BuildModeDebug;
204205
205206 if (argc >= 2 && strcmp(argv[1], "build") == 0) {
206207 const char *zig_exe_path = arg0;
......@@ -237,7 +238,7 @@ int main(int argc, char **argv) {
237238 }
238239 }
239240
240 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe);
241 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug);
241242 codegen_set_out_name(g, buf_create_from_str("build"));
242243 codegen_set_verbose(g, verbose);
243244
......@@ -319,8 +320,10 @@ int main(int argc, char **argv) {
319320 char *arg = argv[i];
320321
321322 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;
324327 } else if (strcmp(arg, "--strip") == 0) {
325328 strip = true;
326329 } else if (strcmp(arg, "--static") == 0) {
......@@ -569,10 +572,9 @@ int main(int argc, char **argv) {
569572 buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir),
570573 full_cache_dir);
571574
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);
573576 codegen_set_out_name(g, buf_out_name);
574577 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
575 codegen_set_is_release(g, is_release_build);
576578 codegen_set_is_test(g, cmd == CmdTest);
577579 codegen_set_linker_script(g, linker_script);
578580 codegen_set_cache_dir(g, full_cache_dir);
std/build.zig+69-35
......@@ -405,6 +405,23 @@ pub const Builder = struct {
405405 return &step_info.step;
406406 }
407407
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
408425 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool {
409426 test (%%self.user_input_options.put(name, UserInputOption {
410427 .name = name,
......@@ -667,7 +684,7 @@ pub const LibExeObjStep = struct {
667684 linker_script: ?[]const u8,
668685 link_libs: BufSet,
669686 verbose: bool,
670 release: bool,
687 build_mode: builtin.Mode,
671688 static: bool,
672689 output_path: ?[]const u8,
673690 output_h_path: ?[]const u8,
......@@ -724,7 +741,7 @@ pub const LibExeObjStep = struct {
724741 var self = LibExeObjStep {
725742 .builder = builder,
726743 .verbose = false,
727 .release = false,
744 .build_mode = builtin.Mode.Debug,
728745 .static = static,
729746 .kind = kind,
730747 .root_src = root_src,
......@@ -794,8 +811,8 @@ pub const LibExeObjStep = struct {
794811 self.verbose = value;
795812 }
796813
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;
799816 }
800817
801818 pub fn setOutputPath(self: &LibExeObjStep, value: []const u8) {
......@@ -886,8 +903,10 @@ pub const LibExeObjStep = struct {
886903 %%zig_args.append("--verbose");
887904 }
888905
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"),
891910 }
892911
893912 %%zig_args.append("--cache-dir");
......@@ -980,7 +999,7 @@ pub const TestStep = struct {
980999 step: Step,
9811000 builder: &Builder,
9821001 root_src: []const u8,
983 release: bool,
1002 build_mode: builtin.Mode,
9841003 verbose: bool,
9851004 link_libs: BufSet,
9861005 name_prefix: []const u8,
......@@ -992,7 +1011,7 @@ pub const TestStep = struct {
9921011 .step = Step.init(step_name, builder.allocator, make),
9931012 .builder = builder,
9941013 .root_src = root_src,
995 .release = false,
1014 .build_mode = builtin.Mode.Debug,
9961015 .verbose = false,
9971016 .name_prefix = "",
9981017 .filter = null,
......@@ -1004,8 +1023,8 @@ pub const TestStep = struct {
10041023 self.verbose = value;
10051024 }
10061025
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;
10091028 }
10101029
10111030 pub fn linkSystemLibrary(self: &TestStep, name: []const u8) {
......@@ -1034,8 +1053,10 @@ pub const TestStep = struct {
10341053 %%zig_args.append("--verbose");
10351054 }
10361055
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"),
10391060 }
10401061
10411062 test (self.filter) |filter| {
......@@ -1095,6 +1116,8 @@ pub const CLibExeObjStep = struct {
10951116 name_only_filename: []const u8,
10961117 object_src: []const u8,
10971118 kind: Kind,
1119 build_mode: builtin.Mode,
1120 strip: bool,
10981121
10991122 const Kind = enum {
11001123 Exe,
......@@ -1147,6 +1170,8 @@ pub const CLibExeObjStep = struct {
11471170 .major_only_filename = undefined,
11481171 .name_only_filename = undefined,
11491172 .object_src = undefined,
1173 .build_mode = builtin.Mode.Debug,
1174 .strip = false,
11501175 };
11511176 clib.computeOutFileNames();
11521177 return clib;
......@@ -1233,13 +1258,8 @@ pub const CLibExeObjStep = struct {
12331258 %%self.include_dirs.append(path);
12341259 }
12351260
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;
12431263 }
12441264
12451265 pub fn addCompileFlags(self: &CLibExeObjStep, flags: []const []const u8) {
......@@ -1248,6 +1268,34 @@ pub const CLibExeObjStep = struct {
12481268 }
12491269 }
12501270
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
12511299 fn make(step: &Step) -> %void {
12521300 const self = @fieldParentPtr(CLibExeObjStep, "step", step);
12531301 const cc = os.getEnv("CC") ?? "cc";
......@@ -1265,14 +1313,7 @@ pub const CLibExeObjStep = struct {
12651313 %%cc_args.append("-o");
12661314 %%cc_args.append(output_path);
12671315
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);
12761317
12771318 %return builder.spawnChild(cc, cc_args.toSliceConst());
12781319 },
......@@ -1295,14 +1336,7 @@ pub const CLibExeObjStep = struct {
12951336 %%cc_args.append("-o");
12961337 %%cc_args.append(cache_o_file);
12971338
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);
13061340
13071341 %return builder.spawnChild(cc, cc_args.toSliceConst());
13081342
std/hash_map.zig+1-1
......@@ -5,7 +5,7 @@ const mem = @import("mem.zig");
55const Allocator = mem.Allocator;
66const builtin = @import("builtin");
77
8const want_modification_safety = !builtin.is_release;
8const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
99const debug_u32 = if (want_modification_safety) u32 else void;
1010
1111pub fn HashMap(comptime K: type, comptime V: type,
std/special/build_file_template.zig+12-2
......@@ -1,10 +1,20 @@
11const Builder = @import("std").build.Builder;
2const Mode = @import("builtin").Mode;
23
34pub 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 };
515
616 const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");
7 exe.setRelease(release);
17 exe.setBuildMode(build_mode);
818
919 b.default_step.dependOn(&exe.step);
1020}
std/special/builtin.zig+1-1
......@@ -32,7 +32,7 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
3232}
3333
3434export fn __stack_chk_fail() {
35 if (builtin.is_release) {
35 if (builtin.mode == builtin.Mode.ReleaseFast) {
3636 @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal);
3737 unreachable;
3838 }
test/tests.zig+21-19
......@@ -9,6 +9,7 @@ const io = std.io;
99const mem = std.mem;
1010const fmt = std.fmt;
1111const List = std.list.List;
12const Mode = @import("builtin").Mode;
1213
1314const compare_output = @import("compare_output.zig");
1415const build_examples = @import("build_examples.zig");
......@@ -107,14 +108,13 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
107108 name:[] const u8, desc: []const u8) -> &build.Step
108109{
109110 const step = b.step(b.fmt("test-{}", name), desc);
110 for ([]bool{false, true}) |release| {
111 for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| {
111112 for ([]bool{false, true}) |link_libc| {
112113 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),
115115 if (link_libc) "c" else "bare"));
116116 these_tests.setFilter(test_filter);
117 these_tests.setRelease(release);
117 these_tests.setBuildMode(mode);
118118 if (link_libc) {
119119 these_tests.linkSystemLibrary("c");
120120 }
......@@ -372,9 +372,9 @@ pub const CompareOutputContext = struct {
372372 self.step.dependOn(&run_and_cmp_output.step);
373373 },
374374 Special.None => {
375 for ([]bool{false, true}) |release| {
375 for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| {
376376 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));
378378 test (self.test_filter) |filter| {
379379 if (mem.indexOf(u8, annotated_case_name, filter) == null)
380380 continue;
......@@ -382,7 +382,7 @@ pub const CompareOutputContext = struct {
382382
383383 const exe = b.addExecutable("test", root_src);
384384 exe.setOutputPath(exe_path);
385 exe.setRelease(release);
385 exe.setBuildMode(mode);
386386 if (case.link_libc) {
387387 exe.linkSystemLibrary("c");
388388 }
......@@ -465,10 +465,10 @@ pub const CompileErrorContext = struct {
465465 name: []const u8,
466466 test_index: usize,
467467 case: &const TestCase,
468 release: bool,
468 build_mode: Mode,
469469
470470 pub fn create(context: &CompileErrorContext, name: []const u8,
471 case: &const TestCase, release: bool) -> &CompileCmpOutputStep
471 case: &const TestCase, build_mode: Mode) -> &CompileCmpOutputStep
472472 {
473473 const allocator = context.b.allocator;
474474 const ptr = %%allocator.create(CompileCmpOutputStep);
......@@ -478,7 +478,7 @@ pub const CompileErrorContext = struct {
478478 .name = name,
479479 .test_index = context.test_index,
480480 .case = case,
481 .release = release,
481 .build_mode = build_mode,
482482 };
483483 context.test_index += 1;
484484 return ptr;
......@@ -501,8 +501,10 @@ pub const CompileErrorContext = struct {
501501 %%zig_args.append("--output");
502502 %%zig_args.append(b.pathFromRoot(obj_path));
503503
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"),
506508 }
507509
508510 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
......@@ -620,15 +622,15 @@ pub const CompileErrorContext = struct {
620622 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) {
621623 const b = self.b;
622624
623 for ([]bool{false, true}) |release| {
625 for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| {
624626 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})",
625 case.name, if (release) "release" else "debug");
627 case.name, @enumTagName(mode));
626628 test (self.test_filter) |filter| {
627629 if (mem.indexOf(u8, annotated_case_name, filter) == null)
628630 continue;
629631 }
630632
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);
632634 self.step.dependOn(&compile_and_cmp_errors.step);
633635
634636 for (case.sources.toSliceConst()) |src_file| {
......@@ -657,7 +659,7 @@ pub const BuildExamplesContext = struct {
657659 pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) {
658660 const b = self.b;
659661
660 const annotated_case_name = b.fmt("build {} (debug)", build_file);
662 const annotated_case_name = b.fmt("build {} (Debug)", build_file);
661663 test (self.test_filter) |filter| {
662664 if (mem.indexOf(u8, annotated_case_name, filter) == null)
663665 return;
......@@ -686,16 +688,16 @@ pub const BuildExamplesContext = struct {
686688 pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) {
687689 const b = self.b;
688690
689 for ([]bool{false, true}) |release| {
691 for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| {
690692 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})",
691 root_src, if (release) "release" else "debug");
693 root_src, @enumTagName(mode));
692694 test (self.test_filter) |filter| {
693695 if (mem.indexOf(u8, annotated_case_name, filter) == null)
694696 continue;
695697 }
696698
697699 const exe = b.addExecutable("test", root_src);
698 exe.setRelease(release);
700 exe.setBuildMode(mode);
699701 if (link_libc) {
700702 exe.linkSystemLibrary("c");
701703 }