Heng30的博客
搜索 分类 关于 订阅

如何使用Zig编译器来构建Zig和C混合的C语言项目?

2025-03-31

最近在学Zig,发现它是一门很不错的语言,有很多现代语言的特性。而且能够和C语言很好的融合。zig编译器也是一个很好的C语言编译器,能够很好的组织项目,无论是纯C语言项目,还是C语言和Zig语言的混合项目都能够很好地支持。由于Zig还在不断的发展,有些API会被抛弃掉。下面的项目是基于zig 0.14.0,实现了使用Zig编译器来构建Zig和C的C语言项目。

目录结构

├── build.zig
├── lib
│   ├── add.zig
│   └── libadd.a
└── src
    ├── include
    │   ├── header.h
    │   └── max.h
    ├── main.c
    ├── max.c
    └── sub.zig

代码

// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "header.h"
#include "max.h"

int main(int argc, char *argv[]) {
    printf("1 + 2 = %d\n", add(1, 2));
    printf("2 - 1 = %d\n", sub(2, 1));
    printf("max(1, 2) = %d\n", max(1, 2));
    return 0;
}

// max.c

#include "max.h"

int max(int a, int b) { return a > b ? a : b; }

// header.h

#pragma once

int add(int a, int b);

int sub(int a, int b);

// max.h

#pragma once

int max(int a, int b);

// sub.zig

export fn sub(a: i32, b: i32) i32 {
    return a - b;
}

// add.zig

// 编译静态库:zig build-lib add.zig
// 编译动态库:zig build-lib add.zig -dynamic

export fn add(a: i32, b: i32) i32 {
    return a + b;
}

构建脚本

// build.zig

const std = @import("std");

const c_flags = [_][]const u8{"-std=c99"};

const c_source_files = [_][]const u8{
    "src/main.c",
    "src/max.c",
};

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // 将zig代码编译成静态库
    const lib_sub = b.addStaticLibrary(.{
        .name = "sub",
        .root_source_file = b.path("src/sub.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(lib_sub);

    // 编译可执行程序
    const exe = b.addExecutable(.{
        .name = "main",
        .optimize = optimize,
        .target = target,
    });

    exe.addIncludePath(.{
        .src_path = .{
            .owner = b,
            .sub_path = "./src/include",
        },
    });

    exe.addCSourceFiles(
        .{
            .files = &c_source_files,
            .flags = &c_flags,
        },
    );

    exe.addLibraryPath(.{
        .src_path = .{
            .owner = b,
            .sub_path = "./lib",
        },
    });

    exe.linkLibC();
    exe.linkLibrary(lib_sub); // 编译脚本直接将zig源文件编译成库
    exe.linkSystemLibrary("add"); // zig文件编译出来的库
    b.installArtifact(exe);

    // 定义`zig build run`命令
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

测试

  • 编译:zig build

  • 运行:zig build run