build baseline: pinned sqlite + mbedtls, static musl cross targets, cli stub
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
.zig-cache/
|
||||||
|
zig-out/
|
||||||
|
zig-pkg/
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (builtin.zig_version.major != 0 or builtin.zig_version.minor != 16) {
|
||||||
|
@compileError("nxdns requires Zig 0.16.x, found " ++ builtin.zig_version_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cross_targets = [_][]const u8{
|
||||||
|
"x86_64-linux-musl",
|
||||||
|
"aarch64-linux-musl",
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const integration = b.option(bool, "integration", "Run hermetic integration tests (loopback sockets only)") orelse false;
|
||||||
|
const live = b.option(bool, "live", "Run tests that reach external network hosts") orelse false;
|
||||||
|
const version_string = b.option([]const u8, "version-string", "Version reported by `nxdns version`") orelse "0.1.0-dev";
|
||||||
|
const git_commit = b.option([]const u8, "git-commit", "Git commit reported by `nxdns version`") orelse "unknown";
|
||||||
|
|
||||||
|
const options = b.addOptions();
|
||||||
|
options.addOption(bool, "integration", integration);
|
||||||
|
options.addOption(bool, "live", live);
|
||||||
|
options.addOption([]const u8, "version_string", version_string);
|
||||||
|
options.addOption([]const u8, "git_commit", git_commit);
|
||||||
|
options.addOption([]const u8, "zig_version_string", builtin.zig_version_string);
|
||||||
|
|
||||||
|
const exe = addExecutable(b, target, optimize, options);
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const run = b.addRunArtifact(exe);
|
||||||
|
run.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run.addArgs(args);
|
||||||
|
b.step("run", "Run nxdns").dependOn(&run.step);
|
||||||
|
|
||||||
|
const tests = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/tests.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
tests.root_module.addOptions("build_options", options);
|
||||||
|
tests.root_module.linkLibrary(sqliteLibrary(b, target, optimize));
|
||||||
|
tests.root_module.linkLibrary(mbedtlsLibrary(b, target, optimize));
|
||||||
|
tests.root_module.addCSourceFile(.{ .file = b.path("src/platform/mbedtls_shim.c") });
|
||||||
|
addMbedtlsThreadingMacros(tests.root_module);
|
||||||
|
tests.root_module.addAnonymousImport("test_fixtures", .{
|
||||||
|
.root_source_file = b.path("tests/fixtures/fixtures.zig"),
|
||||||
|
});
|
||||||
|
b.step("test", "Run the test suite").dependOn(&b.addRunArtifact(tests).step);
|
||||||
|
|
||||||
|
const cross = b.step("cross", "Build static musl executables for every deploy target");
|
||||||
|
for (cross_targets) |triple| {
|
||||||
|
const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch |err| {
|
||||||
|
std.debug.panic("invalid cross target '{s}': {t}", .{ triple, err });
|
||||||
|
};
|
||||||
|
const cross_exe = addExecutable(b, b.resolveTargetQuery(query), optimize, options);
|
||||||
|
cross_exe.linkage = .static;
|
||||||
|
const install = b.addInstallArtifact(cross_exe, .{
|
||||||
|
.dest_dir = .{ .override = .{ .custom = b.fmt("cross/{s}", .{triple}) } },
|
||||||
|
});
|
||||||
|
cross.dependOn(&install.step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addExecutable(
|
||||||
|
b: *std.Build,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
options: *std.Build.Step.Options,
|
||||||
|
) *std.Build.Step.Compile {
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "nxdns",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
exe.root_module.addOptions("build_options", options);
|
||||||
|
exe.root_module.linkLibrary(sqliteLibrary(b, target, optimize));
|
||||||
|
exe.root_module.linkLibrary(mbedtlsLibrary(b, target, optimize));
|
||||||
|
return exe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SQLite 3.53.4 amalgamation (see build.zig.zon for the pinned URL and hash).
|
||||||
|
fn sqliteLibrary(
|
||||||
|
b: *std.Build,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *std.Build.Step.Compile {
|
||||||
|
const dep = b.dependency("sqlite", .{});
|
||||||
|
const lib = b.addLibrary(.{
|
||||||
|
.name = "sqlite3",
|
||||||
|
.linkage = .static,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
lib.root_module.addIncludePath(dep.path(""));
|
||||||
|
lib.root_module.addCSourceFile(.{
|
||||||
|
.file = dep.path("sqlite3.c"),
|
||||||
|
.flags = &.{
|
||||||
|
"-DSQLITE_ENABLE_FTS5",
|
||||||
|
"-DSQLITE_THREADSAFE=1",
|
||||||
|
"-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1",
|
||||||
|
"-DSQLITE_OMIT_LOAD_EXTENSION",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mbed TLS 3.6.7 LTS, stock `mbedtls_config.h` (see build.zig.zon for the pinned URL and hash).
|
||||||
|
fn mbedtlsLibrary(
|
||||||
|
b: *std.Build,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
) *std.Build.Step.Compile {
|
||||||
|
const dep = b.dependency("mbedtls", .{});
|
||||||
|
const lib = b.addLibrary(.{
|
||||||
|
.name = "mbedtls",
|
||||||
|
.linkage = .static,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
addMbedtlsThreadingMacros(lib.root_module);
|
||||||
|
|
||||||
|
for ([_][]const u8{
|
||||||
|
"include",
|
||||||
|
"library",
|
||||||
|
"3rdparty/everest/include",
|
||||||
|
"3rdparty/everest/include/everest",
|
||||||
|
"3rdparty/everest/include/everest/kremlib",
|
||||||
|
"3rdparty/p256-m/p256-m/include",
|
||||||
|
"3rdparty/p256-m/p256-m_driver_interface",
|
||||||
|
}) |include_dir| {
|
||||||
|
lib.root_module.addIncludePath(dep.path(include_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
lib.root_module.addCSourceFiles(.{
|
||||||
|
.root = dep.path("library"),
|
||||||
|
.files = &mbedtls_library_sources,
|
||||||
|
});
|
||||||
|
lib.root_module.addCSourceFiles(.{
|
||||||
|
.root = dep.path("3rdparty"),
|
||||||
|
.files = &mbedtls_3rdparty_sources,
|
||||||
|
});
|
||||||
|
lib.installHeadersDirectory(dep.path("include/mbedtls"), "mbedtls", .{});
|
||||||
|
lib.installHeadersDirectory(dep.path("include/psa"), "psa", .{});
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Context sizes change with threading enabled, so every compilation unit that
|
||||||
|
/// includes mbedTLS headers (the library itself and `mbedtls_shim.c`) must see
|
||||||
|
/// the same macros. Concurrent handshakes share `ssl_config`, the CTR-DRBG, and
|
||||||
|
/// global PSA state; without MBEDTLS_THREADING_C those race.
|
||||||
|
fn addMbedtlsThreadingMacros(m: *std.Build.Module) void {
|
||||||
|
m.addCMacro("MBEDTLS_THREADING_C", "1");
|
||||||
|
m.addCMacro("MBEDTLS_THREADING_PTHREAD", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every `library/*.c` of the release, matching `library/Makefile`.
|
||||||
|
const mbedtls_library_sources = [_][]const u8{
|
||||||
|
"aes.c", "aesce.c",
|
||||||
|
"aesni.c", "aria.c",
|
||||||
|
"asn1parse.c", "asn1write.c",
|
||||||
|
"base64.c", "bignum.c",
|
||||||
|
"bignum_core.c", "bignum_mod.c",
|
||||||
|
"bignum_mod_raw.c", "block_cipher.c",
|
||||||
|
"camellia.c", "ccm.c",
|
||||||
|
"chacha20.c", "chachapoly.c",
|
||||||
|
"cipher.c", "cipher_wrap.c",
|
||||||
|
"cmac.c", "constant_time.c",
|
||||||
|
"ctr_drbg.c", "debug.c",
|
||||||
|
"des.c", "dhm.c",
|
||||||
|
"ecdh.c", "ecdsa.c",
|
||||||
|
"ecjpake.c", "ecp.c",
|
||||||
|
"ecp_curves.c", "ecp_curves_new.c",
|
||||||
|
"entropy.c", "entropy_poll.c",
|
||||||
|
"error.c", "gcm.c",
|
||||||
|
"hkdf.c", "hmac_drbg.c",
|
||||||
|
"lmots.c", "lms.c",
|
||||||
|
"md.c", "md5.c",
|
||||||
|
"memory_buffer_alloc.c", "mps_reader.c",
|
||||||
|
"mps_trace.c", "net_sockets.c",
|
||||||
|
"nist_kw.c", "oid.c",
|
||||||
|
"padlock.c", "pem.c",
|
||||||
|
"pk.c", "pk_ecc.c",
|
||||||
|
"pk_wrap.c", "pkcs12.c",
|
||||||
|
"pkcs5.c", "pkcs7.c",
|
||||||
|
"pkparse.c", "pkwrite.c",
|
||||||
|
"platform.c", "platform_util.c",
|
||||||
|
"poly1305.c", "psa_crypto.c",
|
||||||
|
"psa_crypto_aead.c", "psa_crypto_cipher.c",
|
||||||
|
"psa_crypto_client.c", "psa_crypto_driver_wrappers_no_static.c",
|
||||||
|
"psa_crypto_ecp.c", "psa_crypto_ffdh.c",
|
||||||
|
"psa_crypto_hash.c", "psa_crypto_mac.c",
|
||||||
|
"psa_crypto_pake.c", "psa_crypto_random.c",
|
||||||
|
"psa_crypto_rsa.c", "psa_crypto_se.c",
|
||||||
|
"psa_crypto_slot_management.c", "psa_crypto_storage.c",
|
||||||
|
"psa_its_file.c", "psa_util.c",
|
||||||
|
"ripemd160.c", "rsa.c",
|
||||||
|
"rsa_alt_helpers.c", "sha1.c",
|
||||||
|
"sha256.c", "sha3.c",
|
||||||
|
"sha512.c", "ssl_cache.c",
|
||||||
|
"ssl_ciphersuites.c", "ssl_client.c",
|
||||||
|
"ssl_cookie.c", "ssl_debug_helpers_generated.c",
|
||||||
|
"ssl_msg.c", "ssl_ticket.c",
|
||||||
|
"ssl_tls.c", "ssl_tls12_client.c",
|
||||||
|
"ssl_tls12_server.c", "ssl_tls13_client.c",
|
||||||
|
"ssl_tls13_generic.c", "ssl_tls13_keys.c",
|
||||||
|
"ssl_tls13_server.c", "threading.c",
|
||||||
|
"timing.c", "version.c",
|
||||||
|
"version_features.c", "x509.c",
|
||||||
|
"x509_create.c", "x509_crl.c",
|
||||||
|
"x509_crt.c", "x509_csr.c",
|
||||||
|
"x509write.c", "x509write_crt.c",
|
||||||
|
"x509write_csr.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The object lists of `3rdparty/everest/Makefile.inc` and `3rdparty/p256-m/Makefile.inc`.
|
||||||
|
/// The stock config enables neither driver, so these compile to empty objects.
|
||||||
|
const mbedtls_3rdparty_sources = [_][]const u8{
|
||||||
|
"everest/library/everest.c",
|
||||||
|
"everest/library/x25519.c",
|
||||||
|
"everest/library/Hacl_Curve25519_joined.c",
|
||||||
|
"p256-m/p256-m_driver_entrypoints.c",
|
||||||
|
"p256-m/p256-m/p256-m.c",
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
.{
|
||||||
|
.name = .nxdns,
|
||||||
|
.version = "0.1.0",
|
||||||
|
.minimum_zig_version = "0.16.0",
|
||||||
|
.paths = .{""},
|
||||||
|
.fingerprint = 0x3307b311dded1d91,
|
||||||
|
.dependencies = .{
|
||||||
|
.sqlite = .{
|
||||||
|
.url = "https://sqlite.org/2026/sqlite-amalgamation-3530400.zip",
|
||||||
|
.hash = "N-V-__8AAGVtrgCcOcmjrOJnagmnRyMrcKaOo09KbU-vu8w8",
|
||||||
|
},
|
||||||
|
.mbedtls = .{
|
||||||
|
.url = "https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/mbedtls-3.6.7.tar.gz",
|
||||||
|
.hash = "N-V-__8AALrvlQKVtYlvv9dpBnbrJfdwR_F0wAgwsvZhAF1Y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const version = @import("version.zig");
|
||||||
|
|
||||||
|
const usage =
|
||||||
|
\\usage: nxdns <command>
|
||||||
|
\\
|
||||||
|
\\commands:
|
||||||
|
\\ run serve DNS
|
||||||
|
\\ check validate the configuration
|
||||||
|
\\ export write local records to stdout
|
||||||
|
\\ import read local records from stdin
|
||||||
|
\\ version print version information
|
||||||
|
\\
|
||||||
|
;
|
||||||
|
|
||||||
|
const exit_ok = 0;
|
||||||
|
const exit_not_implemented = 2;
|
||||||
|
const exit_usage = 64;
|
||||||
|
|
||||||
|
pub fn main(init: std.process.Init) u8 {
|
||||||
|
var args = init.minimal.args.iterate();
|
||||||
|
_ = args.skip();
|
||||||
|
const command = args.next() orelse return fail(init.io, usage);
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "version")) {
|
||||||
|
return print(init.io, "nxdns {s} ({s})\nzig {s}\n", .{
|
||||||
|
version.string,
|
||||||
|
version.git_commit,
|
||||||
|
version.zig_version_string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for ([_][]const u8{ "run", "check", "export", "import" }) |known| {
|
||||||
|
if (std.mem.eql(u8, command, known)) {
|
||||||
|
_ = print(init.io, "not implemented\n", .{});
|
||||||
|
return exit_not_implemented;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fail(init.io, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(io: std.Io, comptime format: []const u8, arguments: anytype) u8 {
|
||||||
|
var buffer: [512]u8 = undefined;
|
||||||
|
var file_writer = std.Io.File.stdout().writer(io, &buffer);
|
||||||
|
file_writer.interface.print(format, arguments) catch return 1;
|
||||||
|
file_writer.interface.flush() catch return 1;
|
||||||
|
return exit_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fail(io: std.Io, message: []const u8) u8 {
|
||||||
|
var buffer: [512]u8 = undefined;
|
||||||
|
var file_writer = std.Io.File.stderr().writer(io, &buffer);
|
||||||
|
file_writer.interface.writeAll(message) catch {};
|
||||||
|
file_writer.interface.flush() catch {};
|
||||||
|
return exit_usage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
_ = @import("main.zig");
|
||||||
|
_ = @import("version.zig");
|
||||||
|
_ = @import("platform/address.zig");
|
||||||
|
_ = @import("platform/tls_client.zig");
|
||||||
|
_ = @import("platform/tls_client_integration_test.zig");
|
||||||
|
_ = @import("platform/tls_server.zig");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern fn sqlite3_libversion() [*:0]const u8;
|
||||||
|
/// Mbed TLS documents 18 bytes as the minimum buffer size for this call.
|
||||||
|
extern fn mbedtls_version_get_string_full(buffer: [*]u8) void;
|
||||||
|
|
||||||
|
test "sqlite3 links and reports a version" {
|
||||||
|
const reported = std.mem.span(sqlite3_libversion());
|
||||||
|
try std.testing.expect(reported.len > 0);
|
||||||
|
try std.testing.expect(std.mem.startsWith(u8, reported, "3."));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "mbedtls links and reports a version" {
|
||||||
|
var buffer: [32]u8 = undefined;
|
||||||
|
mbedtls_version_get_string_full(&buffer);
|
||||||
|
const reported = std.mem.sliceTo(&buffer, 0);
|
||||||
|
try std.testing.expect(reported.len > 0);
|
||||||
|
try std.testing.expect(std.mem.startsWith(u8, reported, "Mbed TLS 3.6"));
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
const build_options = @import("build_options");
|
||||||
|
|
||||||
|
pub const string: []const u8 = build_options.version_string;
|
||||||
|
pub const git_commit: []const u8 = build_options.git_commit;
|
||||||
|
pub const zig_version_string: []const u8 = build_options.zig_version_string;
|
||||||
Reference in New Issue
Block a user