Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at dev 195 lines 9.7 kB view raw
1const std = @import("std"); 2 3// Although this function looks imperative, it does not perform the build 4// directly and instead it mutates the build graph (`b`) that will be then 5// executed by an external runner. The functions in `std.Build` implement a DSL 6// for defining build steps and express dependencies between them, allowing the 7// build runner to parallelize the build automatically (and the cache system to 8// know when a step doesn't need to be re-run). 9pub fn build(b: *std.Build) void { 10 // Ensure the license is included in the output directory 11 b.installFile("LICENSE.md", "LICENSE.md"); 12 b.installFile("README.md", "README.md"); 13 // Standard target options allow the person running `zig build` to choose 14 // what target to build for. Here we do not override the defaults, which 15 // means any target is allowed, and the default is native. Other options 16 // for restricting supported target set are available. 17 const target = b.standardTargetOptions(.{}); 18 // Standard optimization options allow the person running `zig build` to select 19 // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not 20 // set a preferred release mode, allowing the user to decide how to optimize. 21 const optimize = b.standardOptimizeOption(.{}); 22 // It's also possible to define more custom flags to toggle optional features 23 // of this build script using `b.option()`. All defined flags (including 24 // target and optimize options) will be listed when running `zig build --help` 25 // in this directory. 26 27 // Get default install step (called with `zig build` or `zig build install`) 28 const install_step = b.getInstallStep(); 29 30 // This creates a module, which represents a collection of source files alongside 31 // some compilation options, such as optimization mode and linked system libraries. 32 // Zig modules are the preferred way of making Zig code available to consumers. 33 // addModule defines a module that we intend to make available for importing 34 // to our consumers. We must give it a name because a Zig package can expose 35 // multiple modules and consumers will need to be able to specify which 36 // module they want to access. 37 const mod = b.addModule("zaprus", .{ 38 // The root source file is the "entry point" of this module. Users of 39 // this module will only be able to access public declarations contained 40 // in this file, which means that if you have declarations that you 41 // intend to expose to consumers that were defined in other files part 42 // of this module, you will have to make sure to re-export them from 43 // the root file. 44 .root_source_file = b.path("src/root.zig"), 45 // Later on we'll use this module as the root module of a test executable 46 // which requires us to specify a target. 47 .target = target, 48 }); 49 50 // Only used to generate the documentation 51 const zaprus_lib = b.addLibrary(.{ 52 .name = "zaprus", 53 .root_module = mod, 54 }); 55 56 const docs_step = b.step("doc", "Emit documentation"); 57 const docs_install = b.addInstallDirectory(.{ 58 .install_dir = .prefix, 59 .install_subdir = "docs", 60 .source_dir = zaprus_lib.getEmittedDocs(), 61 }); 62 63 docs_step.dependOn(&docs_install.step); 64 install_step.dependOn(docs_step); 65 66 // Create static library 67 const lib = b.addLibrary(.{ 68 .name = "zaprus", 69 .root_module = b.createModule(.{ 70 .root_source_file = b.path("src/c_api.zig"), 71 .target = target, 72 .optimize = optimize, 73 .link_libc = true, 74 .imports = &.{ 75 .{ .name = "zaprus", .module = mod }, 76 }, 77 }), 78 }); 79 80 b.installArtifact(lib); 81 lib.installHeader(b.path("include/zaprus.h"), "zaprus.h"); 82 83 // Here we define an executable. An executable needs to have a root module 84 // which needs to expose a `main` function. While we could add a main function 85 // to the module defined above, it's sometimes preferable to split business 86 // logic and the CLI into two separate modules. 87 // 88 // If your goal is to create a Zig library for others to use, consider if 89 // it might benefit from also exposing a CLI tool. A parser library for a 90 // data serialization format could also bundle a CLI syntax checker, for example. 91 // 92 // If instead your goal is to create an executable, consider if users might 93 // be interested in also being able to embed the core functionality of your 94 // program in their own executable in order to avoid the overhead involved in 95 // subprocessing your CLI tool. 96 // 97 // If neither case applies to you, feel free to delete the declaration you 98 // don't need and to put everything under a single module. 99 const exe = b.addExecutable(.{ 100 .name = "zaprus", 101 .root_module = b.createModule(.{ 102 // b.createModule defines a new module just like b.addModule but, 103 // unlike b.addModule, it does not expose the module to consumers of 104 // this package, which is why in this case we don't have to give it a name. 105 .root_source_file = b.path("src/main.zig"), 106 // Target and optimization levels must be explicitly wired in when 107 // defining an executable or library (in the root module), and you 108 // can also hardcode a specific target for an executable or library 109 // definition if desireable (e.g. firmware for embedded devices). 110 .target = target, 111 .optimize = optimize, 112 // List of modules available for import in source files part of the 113 // root module. 114 .imports = &.{ 115 // Here "zaprus" is the name you will use in your source code to 116 // import this module (e.g. `@import("zaprus")`). The name is 117 // repeated because you are allowed to rename your imports, which 118 // can be extremely useful in case of collisions (which can happen 119 // importing modules from different packages). 120 .{ .name = "zaprus", .module = mod }, 121 }, 122 }), 123 }); 124 125 // This declares intent for the executable to be installed into the 126 // install prefix when running `zig build` (i.e. when executing the default 127 // step). By default the install prefix is `zig-out/` but can be overridden 128 // by passing `--prefix` or `-p`. 129 b.installArtifact(exe); 130 131 // This creates a top level step. Top level steps have a name and can be 132 // invoked by name when running `zig build` (e.g. `zig build run`). 133 // This will evaluate the `run` step rather than the default step. 134 // For a top level step to actually do something, it must depend on other 135 // steps (e.g. a Run step, as we will see in a moment). 136 const run_step = b.step("run", "Run the app"); 137 138 // This creates a RunArtifact step in the build graph. A RunArtifact step 139 // invokes an executable compiled by Zig. Steps will only be executed by the 140 // runner if invoked directly by the user (in the case of top level steps) 141 // or if another step depends on it, so it's up to you to define when and 142 // how this Run step will be executed. In our case we want to run it when 143 // the user runs `zig build run`, so we create a dependency link. 144 const run_cmd = b.addRunArtifact(exe); 145 run_step.dependOn(&run_cmd.step); 146 147 // By making the run step depend on the default step, it will be run from the 148 // installation directory rather than directly from within the cache directory. 149 run_cmd.step.dependOn(b.getInstallStep()); 150 151 // This allows the user to pass arguments to the application in the build 152 // command itself, like this: `zig build run -- arg1 arg2 etc` 153 if (b.args) |args| { 154 run_cmd.addArgs(args); 155 } 156 157 // Creates an executable that will run `test` blocks from the provided module. 158 // Here `mod` needs to define a target, which is why earlier we made sure to 159 // set the releative field. 160 const mod_tests = b.addTest(.{ 161 .root_module = mod, 162 }); 163 164 // A run step that will run the test executable. 165 const run_mod_tests = b.addRunArtifact(mod_tests); 166 167 // Creates an executable that will run `test` blocks from the executable's 168 // root module. Note that test executables only test one module at a time, 169 // hence why we have to create two separate ones. 170 const exe_tests = b.addTest(.{ 171 .root_module = exe.root_module, 172 }); 173 174 // A run step that will run the second test executable. 175 const run_exe_tests = b.addRunArtifact(exe_tests); 176 177 // A top level step for running all tests. dependOn can be called multiple 178 // times and since the two run steps do not depend on one another, this will 179 // make the two of them run in parallel. 180 const test_step = b.step("test", "Run tests"); 181 test_step.dependOn(&run_mod_tests.step); 182 test_step.dependOn(&run_exe_tests.step); 183 184 // Just like flags, top level steps are also listed in the `--help` menu. 185 // 186 // The Zig build system is entirely implemented in userland, which means 187 // that it cannot hook into private compiler APIs. All compilation work 188 // orchestrated by the build system will result in other Zig compiler 189 // subcommands being invoked with the right flags defined. You can observe 190 // these invocations when one fails (or you pass a flag to increase 191 // verbosity) to validate assumptions and diagnose problems. 192 // 193 // Lastly, the Zig build system is relatively simple and self-contained, 194 // and reading its source code will allow you to master it. 195}