kj4tmp
October 30, 2024, 5:32am
1
I am trying to depend on npcap https://npcap.com/
which provides an sdk with only headers in it (the user is expected to install npcap themselves) Npcap: Windows Packet Capture Library & Driver
I want to create a zig package for it so I can depend on it like a regular zig dependency.
Can someone point me to an existing example library or documentation that does something similar?
1 Like
kj4tmp
October 30, 2024, 5:41am
2
Found this example, which is think is what I need:
zlib ported to the zig build system
kj4tmp
October 30, 2024, 5:58am
3
I’ve gotten this far:
const std = @import("std");
pub fn build(b: *std.Build) void {
const upstream = b.dependency("npcap_sdk", .{});
const lib = b.addStaticLibrary(.{
.name = "npcap",
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
lib.installHeadersDirectory(upstream.path("include"), "", .{});
b.installArtifact(lib);
}
but I think I need to add the pre-compiled DLLs from the SDK somewhere?
jeff@jeff-debian:~/repos/npcap-zig$ zig build
install
└─ install npcap
└─ zig build-lib npcap Debug native failure
error: the linker needs one or more objects to link
Build Summary: 0/3 steps succeeded; 1 failed
install transitive failure
└─ install npcap transitive failure
└─ zig build-lib npcap Debug native failure
kj4tmp
October 30, 2024, 6:18am
4
well this builds but I think I should probably attempt a full build of npcap instead of relying on its published sdk?
const std = @import("std");
pub fn build(b: *std.Build) void {
const upstream = b.dependency("npcap_sdk", .{});
const lib = b.addStaticLibrary(.{
.name = "npcap",
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
lib.addObjectFile(upstream.path("Lib/wpcap.lib"));
lib.addObjectFile(upstream.path("Lib/Packet.lib"));
lib.installHeadersDirectory(upstream.path("Include"), "", .{});
b.installArtifact(lib);
}
kj4tmp
November 6, 2024, 6:14am
5
I gave up on compiling npcap from source so i will just use the pre-compiled SDK (has some .libs and some headers).
Is there a way to include this .lib
into my compiled executable? Also, I don’t know how to do this.
build.zig.zon
.{
.name = "gatorcat",
.version = "0.0.0",
.minimum_zig_version = "0.13.0",
.dependencies = .{
.flags = .{
.url = "https://github.com/n0s4/flags/archive/refs/tags/v0.10.0.tar.gz",
.hash = "12200d3243c5919d6ae3254f991bdf95956f349ccd6d3463f9beb5454d300a0f1e64",
},
.npcap_sdk = .{
.url = "https://npcap.com/dist/npcap-sdk-1.13.zip",
.hash = "12206001b370bb70f9dc47c846df6ad82725e4491650472dc7037c5e027792ba207e",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
"LICENSE",
"example",
},
}
build zig
// windows npcap dependency
const npcap_sdk = b.dependency("npcap_sdk", .{
.target = target,
.optimize = optimize,
});
const lib = b.addStaticLibrary(.{
.name = "npcap",
.target = target,
.optimize = optimize,
});
lib.addObjectFile(upstream_sdk.path("Lib/wpcap.lib"));
lib.addObjectFile(upstream_sdk.path("Lib/Packet.lib"));
lib.installHeadersDirectory(upstream_sdk.path("Include"), "", .{});
b.installArtifact(lib);
kj4tmp
November 6, 2024, 6:30am
6
Ok i think I’m pretty close with this, zls is now giving me autocomplete
// CLI tool
const cli_tool = b.addExecutable(.{
.name = "gatorcat",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
cli_tool.root_module.addImport("gatorcat", gatorcat_module);
// CLI tool dependencies
const flags = b.dependency("flags", .{
.target = target,
.optimize = optimize,
});
cli_tool.root_module.addImport("flags", flags.module("flags"));
b.installArtifact(cli_tool);
const npcap_sdk = b.dependency("npcap_sdk", .{
.target = target,
.optimize = optimize,
});
cli_tool.addObjectFile(npcap_sdk.path("Lib/wpcap.lib"));
cli_tool.addObjectFile(npcap_sdk.path("Lib/Packet.lib"));
cli_tool.addIncludePath(npcap_sdk.path("Include"));
const npcap = @cImport({
@cInclude("pcap/pcap.h");
});
pub const WindowsRawSocket = struct {
pub fn init() WindowsRawSocket {
npcap.
}
};
kj4tmp
November 6, 2024, 7:30am
7
got everything working, but forgot to link libc, and I will have to refactor this later to make it a conditional dependency to only occur on windows. Not sure how to do that, but that is a separate issue.
// CLI tool
const cli_tool = b.addExecutable(.{
.name = "gatorcat",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
cli_tool.root_module.addImport("gatorcat", gatorcat_module);
// CLI tool dependencies
const flags = b.dependency("flags", .{
.target = target,
.optimize = optimize,
});
cli_tool.root_module.addImport("flags", flags.module("flags"));
b.installArtifact(cli_tool);
cli_tool.addObjectFile(npcap_sdk.path("Lib/wpcap.lib"));
cli_tool.addObjectFile(npcap_sdk.path("Lib/Packet.lib"));
cli_tool.addIncludePath(npcap_sdk.path("Include"));
cli_tool.linkLibC();
1 Like
kj4tmp
November 6, 2024, 8:02am
8
nevermind, its not actually linking yet
error: lld-link: undefined symbol: pcap_open
note: referenced by /home/jeff/repos/gatorcat/src/nic.zig:388
note: /home/jeff/repos/gatorcat/.zig-cache/o/0fb452cb5eb5abf34acdbe0b3ac8c9c5/gatorcat.exe.obj:(nic.WindowsRawSocket.init)
kj4tmp
November 7, 2024, 5:52am
9
I was close, my target was x86_64
so I needed to link against the 64-bit versions of the DLLs.
here is the full solution, for a project that is depending on pre-compiled DLLs. Note that it should eventually contain logic to select the right DLL’s based on the target architecture.
build.zig.zon
.{
.name = "gatorcat",
.version = "0.0.0",
.minimum_zig_version = "0.13.0",
.dependencies = .{
.flags = .{
.url = "https://github.com/n0s4/flags/archive/refs/tags/v0.10.0.tar.gz",
.hash = "12200d3243c5919d6ae3254f991bdf95956f349ccd6d3463f9beb5454d300a0f1e64",
},
.npcap_sdk = .{
.url = "https://npcap.com/dist/npcap-sdk-1.13.zip",
.hash = "12206001b370bb70f9dc47c846df6ad82725e4491650472dc7037c5e027792ba207e",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
"LICENSE",
"example",
},
}
build.zig
// windows dependency
const npcap_sdk = b.dependency("npcap_sdk", .{
.target = target,
.optimize = optimize,
});
// CLI tool dependencies
const flags = b.dependency("flags", .{
.target = target,
.optimize = optimize,
});
cli_tool.root_module.addImport("flags", flags.module("flags"));
b.installArtifact(cli_tool);
cli_tool.addObjectFile(npcap_sdk.path("Lib/x64/wpcap.lib"));
cli_tool.addObjectFile(npcap_sdk.path("Lib/x64/Packet.lib"));
cli_tool.addIncludePath(npcap_sdk.path("Include"));
cli_tool.linkLibC();
1 Like