const std = @import("std"); const c_lib_files = &[_][]const u8{ "tokenizer.c", "ast.c", "zig1.c" }; const all_c_files = c_lib_files ++ &[_][]const u8{"main.c"}; const cflags = &[_][]const u8{ "-std=c11", "-Wall", "-Wvla", "-Wextra", "-Werror", "-Wshadow", "-Wswitch", "-Walloca", "-Wformat=2", "-fno-common", "-Wconversion", "-Wswitch-enum", "-Wuninitialized", "-Wdouble-promotion", "-fstack-protector-all", "-Wimplicit-fallthrough", //"-D_FORTIFY_SOURCE=2", // consider when optimization flags are enabled }; pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const lib = b.addStaticLibrary(.{ .name = "tokenizer", .optimize = optimize, .target = target, }); const cc = b.option([]const u8, "cc", "C compiler") orelse "zig"; if (std.mem.eql(u8, cc, "zig")) lib.addCSourceFiles(.{ .files = c_lib_files, .flags = cflags }) else for (c_lib_files) |cfile| { const objfile = try std.fmt.allocPrint( b.allocator, "{s}.o", .{cfile[0 .. cfile.len - 2]}, ); const cc1 = b.addSystemCommand(&.{cc}); cc1.addArgs(cflags); cc1.addArg("-g"); cc1.addArgs(switch (optimize) { .Debug => &.{"-O0"}, .ReleaseFast, .ReleaseSafe => &.{"-O3"}, // TODO ubsan? .ReleaseSmall => &.{"-Os"}, }); cc1.addArg("-c"); cc1.addFileArg(b.path(cfile)); cc1.addArg("-o"); const obj = cc1.addOutputFileArg(objfile); lib.addObjectFile(obj); } lib.linkLibC(); const test_step = b.step("test", "Run unit tests"); const test_exe = b.addTest(.{ .root_source_file = b.path("test_all.zig"), .optimize = optimize, }); test_exe.linkLibrary(lib); test_exe.addIncludePath(b.path(".")); test_step.dependOn(&b.addRunArtifact(test_exe).step); const lint_step = b.step("lint", "Run linters"); const clang_format = b.addSystemCommand(&.{"clang-format"}); clang_format.addArgs(&.{ "--style=webkit", "-i" }); for (all_c_files) |cfile| clang_format.addFileArg(b.path(cfile)); lint_step.dependOn(&clang_format.step); const clang_analyze = b.addSystemCommand(&.{"clang"}); clang_analyze.addArgs(&.{ "--analyze", "--analyzer-output", "text", "-Wno-unused-command-line-argument", "-Werror", }); for (all_c_files) |cfile| clang_analyze.addFileArg(b.path(cfile)); lint_step.dependOn(&clang_analyze.step); const gcc_analyze = b.addSystemCommand(&.{"gcc"}); gcc_analyze.addArgs(&.{ "--analyzer", "-Werror", "-o", "/dev/null" }); for (all_c_files) |cfile| gcc_analyze.addFileArg(b.path(cfile)); lint_step.dependOn(&gcc_analyze.step); const cppcheck = b.addSystemCommand(&.{"cppcheck"}); cppcheck.addArgs(&.{ "--enable=all", "--suppress=missingIncludeSystem", "--suppress=checkersReport", "--quiet", "--suppress=unusedFunction", // TODO remove after plumbing is done }); for (all_c_files) |cfile| cppcheck.addFileArg(b.path(cfile)); lint_step.dependOn(&cppcheck.step); }