<-- Home |--c

C语言三分钟:用Zig工具链管理C程序main函数

依然是你好世界

我们还来从你好世界!开始。我们用makefile或者CMake来管理C语言程序是挺好的,但是我们就是要干一点不一样的事情。

我们要用C语言来写一个程序(编辑),但是用zig来完成编译链接、调试运行和发布。

1#include <stdio.h>
2
3int main()
4{
5    printf("Hello, World!\n");
6    return 0;
7}

其实Zig天然就能当C/Cpp语言编译器工具链,其实底下是clang。

1zig cc src/main.c -o hello

就这样可以直接得到可执行的hello,或者是hello.exe(Windows平台)。并且这个可执行文件还比直接用gcc编译的可执行文件小很多……真的小很多。

这不是什么重要的优点,优点反而是Zig和C的混合编程,Zig的工具链可以很好的管理C程序,而且Zig的工具链还是很现代化的。

Zig和C

我们首先用Zig的init命令来初始化一个Zig项目。

1zig init hellocpp

然后可以把src目录下的两个文件删除,把main.c文件放到hellocpp/src目录下,然后我们修改build.zig文件程如下的样子。

 1const std = @import("std");
 2
 3// Although this function looks imperative, note that its job is to
 4// declaratively construct a build graph that will be executed by an external
 5// runner.
 6pub fn build(b: *std.Build) void {
 7    // Standard target options allows the person running `zig build` to choose
 8    // what target to build for. Here we do not override the defaults, which
 9    // means any target is allowed, and the default is native. Other options
10    // for restricting supported target set are available.
11    const target = b.standardTargetOptions(.{});
12
13    // Standard optimization options allow the person running `zig build` to select
14    // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
15    // set a preferred release mode, allowing the user to decide how to optimize.
16    const optimize = b.standardOptimizeOption(.{});
17
18    // 主要修改的地方就在这里,去掉了原来的库文件的引用
19    const exe = b.addExecutable(.{
20        .name = "helloworld",
21        .target = target,
22        .optimize = optimize,
23    });
24    // 单独添加一个C文件
25    exe.addCSourceFile(.{ .file = b.path("src/main.c"), .flags = &[_][]const u8{} });
26    exe.linkLibC();
27
28    // This declares intent for the executable to be installed into the
29    // standard location when the user invokes the "install" step (the default
30    // step when running `zig build`).
31    b.installArtifact(exe);
32
33    // This *creates* a Run step in the build graph, to be executed when another
34    // step is evaluated that depends on it. The next line below will establish
35    // such a dependency.
36    const run_cmd = b.addRunArtifact(exe);
37
38    // By making the run step depend on the install step, it will be run from the
39    // installation directory rather than directly from within the cache directory.
40    // This is not necessary, however, if the application depends on other installed
41    // files, this ensures they will be present and in the expected location.
42    run_cmd.step.dependOn(b.getInstallStep());
43
44    // This allows the user to pass arguments to the application in the build
45    // command itself, like this: `zig build run -- arg1 arg2 etc`
46    if (b.args) |args| {
47        run_cmd.addArgs(args);
48    }
49
50    // This creates a build step. It will be visible in the `zig build --help` menu,
51    // and can be selected like this: `zig build run`
52    // This will evaluate the `run` step rather than the default, which is "install".
53    const run_step = b.step("run", "Run the app");
54    run_step.dependOn(&run_cmd.step);
55}

现在就能够用zig build来编译我们的C程序了。

1zig build

zig-out/bin目录下就能看到hellocpp可执行文件了。

1./zig-out/bin/hellocpp

当然,我们还可以直接用zig build run来运行我们的程序。

1zig build run

这样就能够用Zig的工具链来管理我们的C程序了。

总结

找了Zig的英文和中文文档,都没有找到这个功能的介绍。只有一个帖子是抱怨没办法用Zig来管理C程序的main函数。在0.13.0版本之后,Zig支持得挺不错的。

后面我们更改程序,可以直接完成调试运行和发布。

那么,我这么做的初衷是什么呢?根本上,我就是想利用Zig来写C语言函数的单元测试,毕竟Zig的测试真的香。


文章标签

|-->c |-->zig |-->addExecutable |-->build.zig


GitHub