8

In reading the documentation for zig, I was under the impression that zig could compile both C and C++ code. Consequently, I thought you could import a C++ file's header via @cImport and have zig build succeed. However, I can't seem to get this to work for a C++ library integration.

I first create my project, zig init-lib and then add my import to src/main.zig via the @cImport directive. Specifically, I @cInclude("hooks/hooks.h") the C++ header file of this library. If I attempt to zig build at this point, the build fails, unable to find the header. I fix this by modifying build.zig to lib.addIncludeDir("/usr/include/library").

Since this C++ library is now being parsed and uses the C++ standard library, the next error I get when I zig build is that the stdexcept header is not found. To fix this, I modify build.zig to lib.linkSystemLibrary("c++").

Lastly, and the error I'm stuck on now, is an assortment of errors in /path/to/zig-linux-x86_64-0.9.1/lib/libcxx/include/<files>. I get stuff like unknown type name '__LIBCPP_PUSH_MACROS, unknown type name 'namespace', or unknown type name 'template'. Googling this, the only thing of partial relevance that I could find was that this is due to clang's default interpretation of .h files is as C files which obviously don't have namespace or template keywords, but I don't know what to do with that knowledge. LLVM on MacOs - unknown type name 'template' in standard file iosfwd

Does anyone have any insight as to how to actually integrate with a C++ (not pure C) library through zig?

1 Answers1

7

Specifically, I @cInclude("hooks/hooks.h") the C++ header file of this library.

@cImport() is for translating C header files into zig so they can be used without writing bindings. Unfortunately, it does not support C++ headers. To use a C++ library, you'll have to write C bindings for it and then @cImport() those headers.

// src/bindings.cpp
#include <iostream>

extern "C" void doSomeCppThing(void) {
    std::cout << "Hello, World!\n";
}
// src/bindings.h
void doSomeCppThing(void);
// build.zig
const std = @import("std");

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

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "tmp",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    exe.linkLibC();
    exe.linkLibCpp();    
    exe.addIncludePath("src");
    exe.addCSourceFile("src/bindings.cpp", &.{});

    b.installArtifact(exe);
}
// src/main.zig
const c = @cImport({
    @cInclude("bindings.h");
});

pub fn main() !void {
    c.doSomeCppThing();
}
NaniNoni
  • 155
  • 11
pfg
  • 2,348
  • 1
  • 16
  • 37
  • For context, I'm attempting to use the kea hooks/hooks.h headers to implement a handler. In your example, it seems the point is for the interface to be pure C, irrespective of whether the implementation is pure C or includes C++. In which case, I'm still a little confused. Even with a C interface, if your C++ code includes , and subsequently libcxx/include/cstddef, won't you still have the parsing error I'm having where zig doesn't recognize `template` or `namespace`? – Ambiguous Illumination Sep 01 '22 at 23:45
  • @AmbiguousIllumination if the header file is designed to be compatible with C, the header won't include stdexcept, instead the implementation will include it. Looking at `hooks.h`, it seems like it is designed to be included by C++ code because it has namespaces and uses C++ features: https://github.com/isc-projects/kea/blob/master/src/lib/hooks/hooks.h – pfg Sep 02 '22 at 21:16
  • > With a C interface, if your C++ code includes won't you still have the parsing error < No. The C++ code is compiled in the build.zig file with `addCSourceCode()`. This is capable of handling C++. The C header file is parsed by `@cImport`, which cannot handle C++. – pfg Sep 02 '22 at 21:17
  • OK, I'm going to mark this as the answer for now. I'll try and experiment to see if I can properly create the pure C interface for the few C++ functionalities I'd need, assuming it's not beyond my skill. – Ambiguous Illumination Sep 03 '22 at 02:32