| ... | ... | @@ -1156,10 +1156,8 @@ fn addOne(number: i32) i32 { |
| 1156 | 1156 | {#link|identifier|Identifiers#}, followed by a {#link|block|Blocks#} containing any valid Zig code that |
| 1157 | 1157 | is allowed in a {#link|function|Functions#}. |
| 1158 | 1158 | </p> |
| 1159 | | <aside> |
| 1160 | | By convention, non-named tests should only be used to {#link|make other tests run|Nested Container Tests#}. |
| 1161 | | Non-named tests cannot be {#link|filtered|Skip Tests#}. |
| 1162 | | </aside> |
| 1159 | <p>Non-named test blocks always run during test builds and are exempt from |
| 1160 | {#link|Skip Tests#}.</p> |
| 1163 | 1161 | <p> |
| 1164 | 1162 | Test declarations are similar to {#link|Functions#}: they have a return type and a block of code. The implicit |
| 1165 | 1163 | return type of {#syntax#}test{#endsyntax#} is the {#link|Error Union Type#} {#syntax#}anyerror!void{#endsyntax#}, |
| ... | ... | @@ -1173,74 +1171,6 @@ fn addOne(number: i32) i32 { |
| 1173 | 1171 | </p> |
| 1174 | 1172 | {#see_also|The Global Error Set|Grammar#} |
| 1175 | 1173 | {#header_close#} |
| 1176 | | {#header_open|Nested Container Tests#} |
| 1177 | | <p> |
| 1178 | | When the <kbd>zig test</kbd> tool is building a test runner, only resolved {#syntax#}test{#endsyntax#} |
| 1179 | | declarations are included in the build. Initially, only the given Zig source file's top-level |
| 1180 | | declarations are resolved. Unless nested {#link|containers|Containers#} are referenced from a top-level test declaration, |
| 1181 | | nested container tests will not be resolved. |
| 1182 | | </p> |
| 1183 | | <p> |
| 1184 | | The code sample below uses the {#syntax#}std.testing.refAllDecls(@This()){#endsyntax#} function call to |
| 1185 | | reference all of the containers that are in the file including the imported Zig source file. The code |
| 1186 | | sample also shows an alternative way to reference containers using the {#syntax#}_ = C;{#endsyntax#} |
| 1187 | | syntax. This syntax tells the compiler to ignore the result of the expression on the right side of the |
| 1188 | | assignment operator. |
| 1189 | | </p> |
| 1190 | | {#code_begin|test|testing_nested_container_tests#} |
| 1191 | | const std = @import("std"); |
| 1192 | | const expect = std.testing.expect; |
| 1193 | | |
| 1194 | | // Imported source file tests will run when referenced from a top-level test declaration. |
| 1195 | | // The next line alone does not cause "testing_introduction.zig" tests to run. |
| 1196 | | const imported_file = @import("testing_introduction.zig"); |
| 1197 | | |
| 1198 | | test { |
| 1199 | | // To run nested container tests, either, call `refAllDecls` which will |
| 1200 | | // reference all declarations located in the given argument. |
| 1201 | | // `@This()` is a builtin function that returns the innermost container it is called from. |
| 1202 | | // In this example, the innermost container is this file (implicitly a struct). |
| 1203 | | std.testing.refAllDecls(@This()); |
| 1204 | | |
| 1205 | | // or, reference each container individually from a top-level test declaration. |
| 1206 | | // The `_ = C;` syntax is a no-op reference to the identifier `C`. |
| 1207 | | _ = S; |
| 1208 | | _ = U; |
| 1209 | | _ = @import("testing_introduction.zig"); |
| 1210 | | } |
| 1211 | | |
| 1212 | | const S = struct { |
| 1213 | | test "S demo test" { |
| 1214 | | try expect(true); |
| 1215 | | } |
| 1216 | | |
| 1217 | | const SE = enum { |
| 1218 | | V, |
| 1219 | | |
| 1220 | | // This test won't run because its container (SE) is not referenced. |
| 1221 | | test "This Test Won't Run" { |
| 1222 | | try expect(false); |
| 1223 | | } |
| 1224 | | }; |
| 1225 | | }; |
| 1226 | | |
| 1227 | | const U = union { // U is referenced by the file's top-level test declaration |
| 1228 | | s: US, // and US is referenced here; therefore, "U.Us demo test" will run |
| 1229 | | |
| 1230 | | const US = struct { |
| 1231 | | test "U.US demo test" { |
| 1232 | | // This test is a top-level test declaration for the struct. |
| 1233 | | // The struct is nested (declared) inside of a union. |
| 1234 | | try expect(true); |
| 1235 | | } |
| 1236 | | }; |
| 1237 | | |
| 1238 | | test "U demo test" { |
| 1239 | | try expect(true); |
| 1240 | | } |
| 1241 | | }; |
| 1242 | | {#code_end#} |
| 1243 | | {#header_close#} |
| 1244 | 1174 | {#header_open|Test Failure#} |
| 1245 | 1175 | <p> |
| 1246 | 1176 | The default test runner checks for an {#link|error|Errors#} returned from a test. |
| ... | ... | @@ -2856,9 +2786,11 @@ test "volatile" { |
| 2856 | 2786 | </p> |
| 2857 | 2787 | {#header_close#} |
| 2858 | 2788 | <p> |
| 2859 | | To convert one pointer type to another, use {#link|@ptrCast#}. This is an unsafe |
| 2860 | | operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other |
| 2861 | | conversions are not possible. |
| 2789 | {#link|@ptrCast#} converts a pointer's element type to another. This |
| 2790 | creates a new pointer that can cause undetectable illegal behavior |
| 2791 | depending on the loads and stores that pass through it. Generally, other |
| 2792 | kinds of type conversions are preferable to |
| 2793 | {#syntax#}@ptrCast{#endsyntax#} if possible. |
| 2862 | 2794 | </p> |
| 2863 | 2795 | {#code_begin|test|test_pointer_casting#} |
| 2864 | 2796 | const std = @import("std"); |
| ... | ... | @@ -5075,12 +5007,12 @@ test "if error union with optional" { |
| 5075 | 5007 | {#see_also|Optionals|Errors#} |
| 5076 | 5008 | {#header_close#} |
| 5077 | 5009 | {#header_open|defer#} |
| 5010 | <p>Executes an expression unconditionally at scope exit.</p> |
| 5078 | 5011 | {#code_begin|test|test_defer#} |
| 5079 | 5012 | const std = @import("std"); |
| 5080 | 5013 | const expect = std.testing.expect; |
| 5081 | 5014 | const print = std.debug.print; |
| 5082 | 5015 | |
| 5083 | | // defer will execute an expression at the end of the current scope. |
| 5084 | 5016 | fn deferExample() !usize { |
| 5085 | 5017 | var a: usize = 1; |
| 5086 | 5018 | |
| ... | ... | @@ -5097,10 +5029,14 @@ fn deferExample() !usize { |
| 5097 | 5029 | test "defer basics" { |
| 5098 | 5030 | try expect((try deferExample()) == 5); |
| 5099 | 5031 | } |
| 5032 | {#code_end#} |
| 5033 | <p>Defer expressions are evaluated in reverse order.</p> |
| 5034 | {#code_begin|test|defer_unwind#} |
| 5035 | const std = @import("std"); |
| 5036 | const expect = std.testing.expect; |
| 5037 | const print = std.debug.print; |
| 5100 | 5038 | |
| 5101 | | // If multiple defer statements are specified, they will be executed in |
| 5102 | | // the reverse order they were run. |
| 5103 | | fn deferUnwindExample() void { |
| 5039 | test "defer unwinding" { |
| 5104 | 5040 | print("\n", .{}); |
| 5105 | 5041 | |
| 5106 | 5042 | defer { |
| ... | ... | @@ -5116,63 +5052,15 @@ fn deferUnwindExample() void { |
| 5116 | 5052 | } |
| 5117 | 5053 | } |
| 5118 | 5054 | } |
| 5119 | | |
| 5120 | | test "defer unwinding" { |
| 5121 | | deferUnwindExample(); |
| 5122 | | } |
| 5123 | 5055 | {#code_end#} |
| 5056 | <p>Inside a defer expression the return statement is not allowed.</p> |
| 5124 | 5057 | {#code_begin|test_err|test_invalid_defer|cannot return from defer expression#} |
| 5125 | | // Inside a defer expression the return statement is not allowed. |
| 5126 | 5058 | fn deferInvalidExample() !void { |
| 5127 | 5059 | defer { |
| 5128 | 5060 | return error.DeferError; |
| 5129 | 5061 | } |
| 5130 | 5062 | |
| 5131 | 5063 | return error.DeferError; |
| 5132 | | } |
| 5133 | | {#code_end#} |
| 5134 | | {#code_begin|test|test_errdefer#} |
| 5135 | | const std = @import("std"); |
| 5136 | | const print = std.debug.print; |
| 5137 | | |
| 5138 | | // The errdefer keyword is similar to defer, but will only execute if the |
| 5139 | | // scope returns with an error. |
| 5140 | | // |
| 5141 | | // This is especially useful in allowing a function to clean up properly |
| 5142 | | // on error, and replaces goto error handling tactics as seen in c. |
| 5143 | | fn deferErrorExample(is_error: bool) !void { |
| 5144 | | print("\nstart of function\n", .{}); |
| 5145 | | |
| 5146 | | // This will always be executed on exit |
| 5147 | | defer { |
| 5148 | | print("end of function\n", .{}); |
| 5149 | | } |
| 5150 | | |
| 5151 | | errdefer { |
| 5152 | | print("encountered an error!\n", .{}); |
| 5153 | | } |
| 5154 | | |
| 5155 | | if (is_error) { |
| 5156 | | return error.DeferError; |
| 5157 | | } |
| 5158 | | } |
| 5159 | | |
| 5160 | | // The errdefer keyword also supports an alternative syntax to capture the |
| 5161 | | // generated error. |
| 5162 | | // |
| 5163 | | // This is useful for printing an additional error message during clean up. |
| 5164 | | fn deferErrorCaptureExample() !void { |
| 5165 | | errdefer |err| { |
| 5166 | | std.debug.print("the error is {s}\n", .{@errorName(err)}); |
| 5167 | | } |
| 5168 | | |
| 5169 | | return error.DeferError; |
| 5170 | | } |
| 5171 | | |
| 5172 | | test "errdefer unwinding" { |
| 5173 | | deferErrorExample(false) catch {}; |
| 5174 | | deferErrorExample(true) catch {}; |
| 5175 | | deferErrorCaptureExample() catch {}; |
| 5176 | 5064 | } |
| 5177 | 5065 | {#code_end#} |
| 5178 | 5066 | {#see_also|Errors#} |
| ... | ... | @@ -8660,7 +8548,8 @@ test "decl access by string" { |
| 8660 | 8548 | <pre>{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}</pre> |
| 8661 | 8549 | <p> |
| 8662 | 8550 | Converts an integer to the closest floating point representation. The return type is the inferred result type. |
| 8663 | | 			To convert the other way, use {#link|@intFromFloat#}. This cast is always safe. |
| 8551 | 			To convert the other way, use {#link|@intFromFloat#}. This operation is legal |
| 8552 | for all values of all integer types. |
| 8664 | 8553 | </p> |
| 8665 | 8554 | {#header_close#} |
| 8666 | 8555 | |
| ... | ... | @@ -10873,6 +10762,9 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; |
| 10873 | 10762 | Some examples of tasks the build system can help with: |
| 10874 | 10763 | </p> |
| 10875 | 10764 | <ul> |
| 10765 | <li>Performing tasks in parallel and caching the results.</li> |
| 10766 | <li>Depending on other projects.</li> |
| 10767 | <li>Providing a package for other projects to depend on.</li> |
| 10876 | 10768 | <li>Creating build artifacts by executing the Zig compiler. This includes |
| 10877 | 10769 | building Zig source code as well as C and C++ source code.</li> |
| 10878 | 10770 | <li>Capturing user-configured options and using those options to configure |
| ... | ... | @@ -10891,148 +10783,10 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; |
| 10891 | 10783 | to see a command-line usage help menu. This will include project-specific |
| 10892 | 10784 | options that were declared in the build.zig script. |
| 10893 | 10785 | </p> |
| 10894 | | |
| 10895 | | {#header_open|Building an Executable#} |
| 10896 | | <p>This <code class="file">build.zig</code> file is automatically generated |
| 10897 | | by <kbd>zig init-exe</kbd>.</p> |
| 10898 | | {#code_begin|syntax|build_executable#} |
| 10899 | | const std = @import("std"); |
| 10900 | | |
| 10901 | | // Although this function looks imperative, note that its job is to |
| 10902 | | // declaratively construct a build graph that will be executed by an external |
| 10903 | | // runner. |
| 10904 | | pub fn build(b: *std.Build) void { |
| 10905 | | // Standard target options allows the person running `zig build` to choose |
| 10906 | | // what target to build for. Here we do not override the defaults, which |
| 10907 | | // means any target is allowed, and the default is native. Other options |
| 10908 | | // for restricting supported target set are available. |
| 10909 | | const target = b.standardTargetOptions(.{}); |
| 10910 | | |
| 10911 | | // Standard optimization options allow the person running `zig build` to select |
| 10912 | | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not |
| 10913 | | // set a preferred release mode, allowing the user to decide how to optimize. |
| 10914 | | const optimize = b.standardOptimizeOption(.{}); |
| 10915 | | |
| 10916 | | const exe = b.addExecutable(.{ |
| 10917 | | .name = "example", |
| 10918 | | // In this case the main source file is merely a path, however, in more |
| 10919 | | // complicated build scripts, this could be a generated file. |
| 10920 | | .root_source_file = .{ .path = "src/main.zig" }, |
| 10921 | | .target = target, |
| 10922 | | .optimize = optimize, |
| 10923 | | }); |
| 10924 | | |
| 10925 | | // This declares intent for the executable to be installed into the |
| 10926 | | // standard location when the user invokes the "install" step (the default |
| 10927 | | // step when running `zig build`). |
| 10928 | | b.installArtifact(exe); |
| 10929 | | |
| 10930 | | // This *creates* a Run step in the build graph, to be executed when another |
| 10931 | | // step is evaluated that depends on it. The next line below will establish |
| 10932 | | // such a dependency. |
| 10933 | | const run_cmd = b.addRunArtifact(exe); |
| 10934 | | |
| 10935 | | // By making the run step depend on the install step, it will be run from the |
| 10936 | | // installation directory rather than directly from within the cache directory. |
| 10937 | | // This is not necessary, however, if the application depends on other installed |
| 10938 | | // files, this ensures they will be present and in the expected location. |
| 10939 | | run_cmd.step.dependOn(b.getInstallStep()); |
| 10940 | | |
| 10941 | | // This allows the user to pass arguments to the application in the build |
| 10942 | | // command itself, like this: `zig build run -- arg1 arg2 etc` |
| 10943 | | if (b.args) |args| { |
| 10944 | | run_cmd.addArgs(args); |
| 10945 | | } |
| 10946 | | |
| 10947 | | // This creates a build step. It will be visible in the `zig build --help` menu, |
| 10948 | | // and can be selected like this: `zig build run` |
| 10949 | | // This will evaluate the `run` step rather than the default, which is "install". |
| 10950 | | const run_step = b.step("run", "Run the app"); |
| 10951 | | run_step.dependOn(&run_cmd.step); |
| 10952 | | |
| 10953 | | // Creates a step for unit testing. This only builds the test executable |
| 10954 | | // but does not run it. |
| 10955 | | const unit_tests = b.addTest(.{ |
| 10956 | | .root_source_file = .{ .path = "src/main.zig" }, |
| 10957 | | .target = target, |
| 10958 | | .optimize = optimize, |
| 10959 | | }); |
| 10960 | | |
| 10961 | | const run_unit_tests = b.addRunArtifact(unit_tests); |
| 10962 | | |
| 10963 | | // Similar to creating the run step earlier, this exposes a `test` step to |
| 10964 | | // the `zig build --help` menu, providing a way for the user to request |
| 10965 | | // running the unit tests. |
| 10966 | | const test_step = b.step("test", "Run unit tests"); |
| 10967 | | test_step.dependOn(&run_unit_tests.step); |
| 10968 | | } |
| 10969 | | {#code_end#} |
| 10970 | | {#header_close#} |
| 10971 | | |
| 10972 | | {#header_open|Building a Library#} |
| 10973 | | <p>This <code class="file">build.zig</code> file is automatically generated |
| 10974 | | by <kbd>zig init-lib</kbd>.</p> |
| 10975 | | {#code_begin|syntax|build_library#} |
| 10976 | | const std = @import("std"); |
| 10977 | | |
| 10978 | | // Although this function looks imperative, note that its job is to |
| 10979 | | // declaratively construct a build graph that will be executed by an external |
| 10980 | | // runner. |
| 10981 | | pub fn build(b: *std.Build) void { |
| 10982 | | // Standard target options allows the person running `zig build` to choose |
| 10983 | | // what target to build for. Here we do not override the defaults, which |
| 10984 | | // means any target is allowed, and the default is native. Other options |
| 10985 | | // for restricting supported target set are available. |
| 10986 | | const target = b.standardTargetOptions(.{}); |
| 10987 | | |
| 10988 | | // Standard optimization options allow the person running `zig build` to select |
| 10989 | | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not |
| 10990 | | // set a preferred release mode, allowing the user to decide how to optimize. |
| 10991 | | const optimize = b.standardOptimizeOption(.{}); |
| 10992 | | |
| 10993 | | const lib = b.addStaticLibrary(.{ |
| 10994 | | .name = "example", |
| 10995 | | // In this case the main source file is merely a path, however, in more |
| 10996 | | // complicated build scripts, this could be a generated file. |
| 10997 | | .root_source_file = .{ .path = "src/main.zig" }, |
| 10998 | | .target = target, |
| 10999 | | .optimize = optimize, |
| 11000 | | }); |
| 11001 | | |
| 11002 | | // This declares intent for the library to be installed into the standard |
| 11003 | | // location when the user invokes the "install" step (the default step when |
| 11004 | | // running `zig build`). |
| 11005 | | b.installArtifact(lib); |
| 11006 | | |
| 11007 | | // Creates a step for unit testing. This only builds the test executable |
| 11008 | | // but does not run it. |
| 11009 | | const main_tests = b.addTest(.{ |
| 11010 | | .root_source_file = .{ .path = "src/main.zig" }, |
| 11011 | | .target = target, |
| 11012 | | .optimize = optimize, |
| 11013 | | }); |
| 11014 | | |
| 11015 | | const run_main_tests = b.addRunArtifact(main_tests); |
| 11016 | | |
| 11017 | | // This creates a build step. It will be visible in the `zig build --help` menu, |
| 11018 | | // and can be selected like this: `zig build test` |
| 11019 | | // This will evaluate the `test` step rather than the default, which is "install". |
| 11020 | | const test_step = b.step("test", "Run library tests"); |
| 11021 | | test_step.dependOn(&run_main_tests.step); |
| 11022 | | } |
| 11023 | | {#code_end#} |
| 11024 | | {#header_close#} |
| 11025 | | |
| 11026 | | {#header_open|Compiling C Source Code#} |
| 11027 | | <pre>{#syntax#} |
| 11028 | | lib.addCSourceFile(.{ .file = .{ .path = "src/lib.c" }, .flags = &.{ |
| 11029 | | "-Wall", |
| 11030 | | "-Wextra", |
| 11031 | | "-Werror", |
| 11032 | | } }); |
| 11033 | | {#endsyntax#}</pre> |
| 11034 | | {#header_close#} |
| 11035 | | |
| 10786 | <p> |
| 10787 | For the time being, the build system documentation is hosted externally: |
| 10788 | <a href="https://ziglang.org/learn/build-system/">Build System Documentation</a> |
| 10789 | </p> |
| 11036 | 10790 | {#header_close#} |
| 11037 | 10791 | {#header_open|C#} |
| 11038 | 10792 | <p> |