master
  1pub const Env = enum {
  2    /// zig1 features
  3    /// - `-ofmt=c` only
  4    /// - `-OReleaseFast` or `-OReleaseSmall` only
  5    /// - no `@setRuntimeSafety(true)`
  6    bootstrap,
  7
  8    /// zig2 features
  9    core,
 10
 11    /// stage3 features
 12    full,
 13
 14    /// - `zig cc`
 15    /// - `zig c++`
 16    /// - `zig translate-c`
 17    c_source,
 18
 19    /// - `zig ast-check`
 20    /// - `zig changelist`
 21    /// - `zig dump-zir`
 22    ast_gen,
 23
 24    /// - ast_gen
 25    /// - `zig build-* -fno-emit-bin`
 26    sema,
 27
 28    /// - sema
 29    /// - `zig build-* -fincremental -fno-llvm -fno-lld -target aarch64-linux --listen=-`
 30    @"aarch64-linux",
 31
 32    /// - `zig build-* -ofmt=c`
 33    cbe,
 34
 35    /// - sema
 36    /// - `zig build-* -fincremental -fno-llvm -fno-lld -target powerpc(64)(le)-linux --listen=-`
 37    @"powerpc-linux",
 38
 39    /// - sema
 40    /// - `zig build-* -fno-llvm -fno-lld -target riscv64-linux`
 41    @"riscv64-linux",
 42
 43    /// - sema
 44    /// - `zig build-* -fno-llvm -fno-lld -target spirv(32/64)-* --listen=-`
 45    spirv,
 46
 47    /// - sema
 48    /// - `zig build-* -fno-llvm -fno-lld -target wasm32-* --listen=-`
 49    wasm,
 50
 51    /// - sema
 52    /// - `zig build-* -fincremental -fno-llvm -fno-lld -target x86_64-linux --listen=-`
 53    @"x86_64-linux",
 54
 55    pub inline fn supports(comptime dev_env: Env, comptime feature: Feature) bool {
 56        return switch (dev_env) {
 57            .full => true,
 58            .bootstrap => switch (feature) {
 59                .build_exe_command,
 60                .build_obj_command,
 61                .ast_gen,
 62                .sema,
 63                .c_backend,
 64                .c_linker,
 65                => true,
 66                else => false,
 67            },
 68            .core => switch (feature) {
 69                .build_exe_command,
 70                .build_lib_command,
 71                .build_obj_command,
 72                .test_command,
 73                .run_command,
 74                .ar_command,
 75                .build_command,
 76                .clang_command,
 77                .stdio_listen,
 78                .build_import_lib,
 79                .make_executable,
 80                .make_writable,
 81                .incremental,
 82                .ast_gen,
 83                .sema,
 84                .legalize,
 85                .c_compiler,
 86                .llvm_backend,
 87                .c_backend,
 88                .wasm_backend,
 89                .arm_backend,
 90                .x86_64_backend,
 91                .aarch64_backend,
 92                .x86_backend,
 93                .powerpc_backend,
 94                .riscv64_backend,
 95                .sparc64_backend,
 96                .spirv_backend,
 97                .lld_linker,
 98                .coff_linker,
 99                .coff2_linker,
100                .elf_linker,
101                .elf2_linker,
102                .macho_linker,
103                .c_linker,
104                .wasm_linker,
105                .spirv_linker,
106                .plan9_linker,
107                => true,
108                .cc_command,
109                .translate_c_command,
110                .fmt_command,
111                .jit_command,
112                .fetch_command,
113                .init_command,
114                .targets_command,
115                .version_command,
116                .env_command,
117                .zen_command,
118                .help_command,
119                .ast_check_command,
120                .detect_cpu_command,
121                .changelist_command,
122                .dump_zir_command,
123                .llvm_ints_command,
124                .docs_emit,
125                // Avoid dragging networking into zig2.c because it adds dependencies on some
126                // linker symbols that are annoying to satisfy while bootstrapping.
127                .network_listen,
128                .win32_resource,
129                => false,
130            },
131            .c_source => switch (feature) {
132                .clang_command,
133                .cc_command,
134                .translate_c_command,
135                .c_compiler,
136                => true,
137                else => false,
138            },
139            .ast_gen => switch (feature) {
140                .ast_check_command,
141                .changelist_command,
142                .dump_zir_command,
143                .make_executable,
144                .make_writable,
145                .incremental,
146                .ast_gen,
147                => true,
148                else => false,
149            },
150            .sema => switch (feature) {
151                .build_exe_command,
152                .build_lib_command,
153                .build_obj_command,
154                .test_command,
155                .run_command,
156                .sema,
157                => true,
158                else => Env.ast_gen.supports(feature),
159            },
160            .@"aarch64-linux" => switch (feature) {
161                .build_command,
162                .stdio_listen,
163                .incremental,
164                .aarch64_backend,
165                .elf_linker,
166                .elf2_linker,
167                => true,
168                else => Env.sema.supports(feature),
169            },
170            .cbe => switch (feature) {
171                .legalize,
172                .c_backend,
173                .c_linker,
174                => true,
175                else => Env.sema.supports(feature),
176            },
177            .@"powerpc-linux" => switch (feature) {
178                .build_command,
179                .stdio_listen,
180                .incremental,
181                .x86_64_backend,
182                .elf_linker,
183                => true,
184                else => Env.sema.supports(feature),
185            },
186            .@"riscv64-linux" => switch (feature) {
187                .riscv64_backend,
188                .elf_linker,
189                => true,
190                else => Env.sema.supports(feature),
191            },
192            .spirv => switch (feature) {
193                .spirv_backend,
194                .spirv_linker,
195                .legalize,
196                => true,
197                else => Env.sema.supports(feature),
198            },
199            .wasm => switch (feature) {
200                .stdio_listen,
201                .incremental,
202                .wasm_backend,
203                .wasm_linker,
204                => true,
205                else => Env.sema.supports(feature),
206            },
207            .@"x86_64-linux" => switch (feature) {
208                .build_command,
209                .stdio_listen,
210                .incremental,
211                .legalize,
212                .x86_64_backend,
213                .elf_linker,
214                .elf2_linker,
215                => true,
216                else => Env.sema.supports(feature),
217            },
218        };
219    }
220
221    pub inline fn supportsAny(comptime dev_env: Env, comptime features: []const Feature) bool {
222        inline for (features) |feature| if (dev_env.supports(feature)) return true;
223        return false;
224    }
225
226    pub inline fn supportsAll(comptime dev_env: Env, comptime features: []const Feature) bool {
227        inline for (features) |feature| if (!dev_env.supports(feature)) return false;
228        return true;
229    }
230};
231
232pub const Feature = enum {
233    build_exe_command,
234    build_lib_command,
235    build_obj_command,
236    test_command,
237    run_command,
238    ar_command,
239    build_command,
240    clang_command,
241    cc_command,
242    translate_c_command,
243    fmt_command,
244    jit_command,
245    fetch_command,
246    init_command,
247    targets_command,
248    version_command,
249    env_command,
250    zen_command,
251    help_command,
252    ast_check_command,
253    detect_cpu_command,
254    changelist_command,
255    dump_zir_command,
256    llvm_ints_command,
257
258    docs_emit,
259    stdio_listen,
260    network_listen,
261    build_import_lib,
262    win32_resource,
263    make_executable,
264    make_writable,
265    incremental,
266    ast_gen,
267    sema,
268    legalize,
269
270    c_compiler,
271
272    llvm_backend,
273    c_backend,
274    wasm_backend,
275    arm_backend,
276    x86_64_backend,
277    aarch64_backend,
278    x86_backend,
279    powerpc_backend,
280    riscv64_backend,
281    sparc64_backend,
282    spirv_backend,
283
284    lld_linker,
285    coff_linker,
286    coff2_linker,
287    elf_linker,
288    elf2_linker,
289    macho_linker,
290    c_linker,
291    wasm_linker,
292    spirv_linker,
293    plan9_linker,
294};
295
296/// Makes the code following the call to this function unreachable if `feature` is disabled.
297pub fn check(comptime feature: Feature) if (env.supports(feature)) void else noreturn {
298    if (env.supports(feature)) return;
299    @panic("development environment " ++ @tagName(env) ++ " does not support feature " ++ @tagName(feature));
300}
301
302/// Makes the code following the call to this function unreachable if all of `features` are disabled.
303pub fn checkAny(comptime features: []const Feature) if (env.supportsAny(features)) void else noreturn {
304    if (env.supportsAny(features)) return;
305    comptime var feature_tags: []const u8 = "";
306    inline for (features[0 .. features.len - 1]) |feature| feature_tags = feature_tags ++ @tagName(feature) ++ ", ";
307    feature_tags = feature_tags ++ "or " ++ @tagName(features[features.len - 1]);
308    @panic("development environment " ++ @tagName(env) ++ " does not support feature " ++ feature_tags);
309}
310
311/// Makes the code following the call to this function unreachable if any of `features` are disabled.
312pub fn checkAll(comptime features: []const Feature) if (env.supportsAll(features)) void else noreturn {
313    if (env.supportsAll(features)) return;
314    inline for (features) |feature| if (!env.supports(feature))
315        @panic("development environment " ++ @tagName(env) ++ " does not support feature " ++ @tagName(feature));
316}
317
318const build_options = @import("build_options");
319
320pub const env: Env = if (@hasDecl(build_options, "dev"))
321    @field(Env, @tagName(build_options.dev))
322else if (@hasDecl(build_options, "only_c") and build_options.only_c)
323    .bootstrap
324else if (@hasDecl(build_options, "only_core_functionality") and build_options.only_core_functionality)
325    .core
326else
327    .full;