Search code examples
compilationcompile-timeconditional-compilationbuild-systemzig

How to do conditional compilation with Zig?


For example, I can add definitions for C/C++ preprocessor with CMake

add_definitions(-DFOO -DBAR ...)

and then I can use them for conditional compilation

#ifdef FOO
   code ...
#endif

#ifdef BAR
   code ...
#endif

Is there a way to do the same thing with Zig and its build system using compilation arguments or something like that?


Solution

  • You can do something similar using the build system. This requires some boilerplate code to do the option handling. Following the tutorial on https://zig.news/xq/zig-build-explained-part-1-59lf for the build system and https://ziggit.dev/t/custom-build-options/138/8 for the option handling:

    1. Create a separate file called build.zig that contains a function build():
    const std = @import("std");
    
    pub fn build(b: *std.build.Builder) !void {
        const build_options = b.addOptions();
        // add command line flag
        // and set default value
        build_options.addOption(bool, "sideways", b.option(bool, "sideways", "print sideways") orelse false);
    
        // set executable name and source code
        const exe = b.addExecutable("hello", "hello.zig");
        exe.addOptions("build_options", build_options);
        // compile and copy to zig-out/bin
        exe.install();
    }
    
    1. Use the option for conditional compilation in a separate file hello.zig using @import("build_options"):
    const std = @import("std");
    
    pub fn main() !void {
        const print_sideways = @import("build_options").sideways;
        const stdout = std.io.getStdOut().writer();
        if (print_sideways) {
           try stdout.print("Sideways Hello, {s}!\n", .{"world"});
        } else {
           try stdout.print("Regular Hello, {s}!\n", .{"world"});
        }
    }
    
    1. Compile with:
    zig build -Dsideways=true
    
    1. Executing zig-out/bin/hello gives the following output:
    Sideways Hello, world!