Zig项目导入C++头文件构建可执行文件报错求助
Zig调用simdjson时C导入失败问题
问题背景
原本通过zig c++ test.cpp simdjson.cpp -o test可正常编译包含simdjson的C代码,将test.cpp改写为test.zig并编写build.zig后,单独构建simdjson静态库正常,但添加可执行文件构建逻辑后出现C导入失败,报错提示simdjson需要C编译器等一系列错误。
相关代码
test.cpp
#include <iostream> #include "simdjson.h" using namespace simdjson; int main(void) { ondemand::parser parser; padded_string json = padded_string::load("twitter.json"); ondemand::document tweets = parser.iterate(json); std::cout << uint64_t(tweets["search_metadata"]["count"]) << " results." << std::endl; }
test.zig
const std = @import("std"); const json = @cImport({ @cInclude("simdjson.h"); }); pub fn main() !void{ const parser = json.ondemand.parser; const file = json.padded_string.load("twitter.json"); const tw = parser.iterate(file); const stdout = std.io.getStdOut().writer(); try stdout.print("Hello, {s}!\n", .{tw}); }
build.zig
const std = @import("std"); pub fn build(b: *std.build.Builder) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const cflags = [_][]const u8{"-std=c++17", "-fno-sanitize=undefined"}; const lib = b.addStaticLibrary(.{ .name = "simdjson", .target = target, .optimize = optimize, .link_libc = true, }); lib.linkLibCpp(); lib.addCSourceFile(.{ .file = std.Build.FileSource.relative("simdjson.cpp"), .flags = &cflags }); lib.addIncludePath(.{ .path = "./header" }); lib.installHeader("./header/simdjson.h", "simdjson.h"); //b.installArtifact(lib); const exe = b.addExecutable(.{ .name = "exe", .root_source_file = .{ .path = "test.zig" }, .target = target, .optimize = optimize, }); exe.linkLibrary(lib); exe.linkLibCpp(); exe.addCSourceFile(.{ .file = std.Build.FileSource.relative("simdjson.cpp"), .flags = &cflags }); //exe.addIncludePath(.{ .path = "./header" }); b.installArtifact(exe); }
错误日志
test.zig:3:14: error: C import failed const json = @cImport({ ^~~~~~~~ referenced by: main: test.zig:11:16 callMain: /home/mhn/zig/lib/std/start.zig:583:32 remaining reference traces hidden; use '-freference-trace' to see all reference traces /home/mhn/zig/lib/libcxx/include/__verbose_abort:20:1: error: unknown type name '_LIBCPP_BEGIN_NAMESPACE_STD' _LIBCPP_BEGIN_NAMESPACE_STD ^ /home/mhn/zig/lib/libcxx/include/__verbose_abort:24:17: error: expected ';' after top level declarator _LIBCPP_NORETURN _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) ^ /home/mhn/zig/lib/libcxx/include/__verbose_abort:58:1: error: unknown type name '_LIBCPP_END_NAMESPACE_STD' _LIBCPP_END_NAMESPACE_STD ^ /home/mhn/Projects/zig-build-test/zig-out/include/simdjson.h:52:2: error: simdjson requires a C++ compiler #error simdjson requires a C++ compiler ^ /home/mhn/Projects/zig-build-test/zig-out/include/simdjson.h:79:2: error: simdjson requires a compiler compliant with the C++11 standard #error simdjson requires a compiler compliant with the C++11 standard ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:18:1: error: unknown type name '_LIBCPP_BEGIN_NAMESPACE_STD' _LIBCPP_BEGIN_NAMESPACE_STD ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:20:9: error: expected ';' after top level declarator template <bool, class _Tp = void> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:22:1: error: unknown type name 'template' template <class _Tp> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:22:10: error: expected identifier or '(' template <class _Tp> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:27:1: error: unknown type name 'template' template <bool _Bp, class _Tp = void> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:27:10: error: expected identifier or '(' template <bool _Bp, class _Tp = void> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/enable_if.h:35:1: error: unknown type name '_LIBCPP_END_NAMESPACE_STD' _LIBCPP_END_NAMESPACE_STD ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:18:28: error: expected ';' after top level declarator _LIBCPP_BEGIN_NAMESPACE_STD ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:31:1: error: unknown type name 'template' template <class _Tp, _Tp __v> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:31:10: error: expected identifier or '(' template <class _Tp, _Tp __v> ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:34:9: error: unknown type name 'integral_constant' typedef integral_constant<bool, true> true_type; ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:34:26: error: expected identifier or '(' typedef integral_constant<bool, true> true_type; ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:35:9: error: unknown type name 'integral_constant' typedef integral_constant<bool, false> false_type; ^ /home/mhn/zig/lib/libcxx/include/__type_traits/integral_constant.h:35:26: error: expected identifier or '(' typedef integral_constant<bool, false> false_type; ^ error: too many errors emitted, stopping now
解决方案
1. 修复@cImport的C++编译模式问题
@cImport默认以C编译器模式解析头文件,无法处理C语法。需要在@cImport块中添加C编译标志,指定用C++标准解析头文件:
const json = @cImport({ @cFlags("-std=c++17"); @cInclude("simdjson.h"); });
2. 移除build.zig中的冗余编译逻辑
exe已经链接了编译好的simdjson静态库,不需要重复添加simdjson.cpp的编译,删除以下代码:
exe.addCSourceFile(.{ .file = std.Build.FileSource.relative("simdjson.cpp"), .flags = &cflags });
同时为exe添加simdjson的头文件路径,取消注释这一行:
exe.addIncludePath(.{ .path = "./header" });
3. 修正test.zig中C++类的调用方式
simdjson的命名空间是simdjson,Zig中需要通过json.simdjson访问;另外C++类的成员函数需要通过实例指针调用,修正后的test.zig如下:
const std = @import("std"); const json = @cImport({ @cFlags("-std=c++17"); @cInclude("simdjson.h"); }); pub fn main() !void { var parser = json.simdjson.ondemand.parser{}; const file = try json.simdjson.padded_string.load("twitter.json"); defer file.deinit(); const tweets = try parser.iterate(file); const count = tweets.get_object().?.get_object("search_metadata").?.get_uint64("count").?; const stdout = std.io.getStdOut().writer(); try stdout.print("{d} results.\n", .{count}); }
4. 调整build.zig中静态库的链接设置
静态库不需要link_libc,移除lib.link_libc = true;,保持lib.linkLibCpp();即可。
最终修正后的build.zig:
const std = @import("std"); pub fn build(b: *std.build.Builder) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const cflags = [_][]const u8{"-std=c++17", "-fno-sanitize=undefined"}; const lib = b.addStaticLibrary(.{ .name = "simdjson", .target = target, .optimize = optimize, }); lib.linkLibCpp(); lib.addCSourceFile(.{ .file = std.Build.FileSource.relative("simdjson.cpp"), .flags = &cflags }); lib.addIncludePath(.{ .path = "./header" }); lib.installHeader("./header/simdjson.h", "simdjson.h"); const exe = b.addExecutable(.{ .name = "exe", .root_source_file = .{ .path = "test.zig" }, .target = target, .optimize = optimize, }); exe.linkLibrary(lib); exe.linkLibCpp(); exe.addIncludePath(.{ .path = "./header" }); b.installArtifact(exe); }
内容的提问来源于stack exchange,提问作者mhn70
相关产品推荐
相关产品推荐

