From 5191b40accb6c860c6d1292c4149c7bea42aca63 Mon Sep 17 00:00:00 2001 From: Fergus Baker Date: Fri, 8 Sep 2023 23:39:15 +0100 Subject: [PATCH] Allow other zig projects to use libsodium as a dependency (#1300) * fix(build.zig): derive cwd from builder Using fs.cwd() only resolves the libsodium directory when building from within libsodium. Deriving the absolute path to the libsodium directory from the builder allows the build script to be invoked from other projects. * feat(build.zig): add options for building libsodium Added the options to build either the static, shared, and/or tests. The tests depend on the static library, and therefore imply the static library. * feat(build.zig): include header files --- build.zig | 104 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/build.zig b/build.zig index ac964d63..9b993c47 100644 --- a/build.zig +++ b/build.zig @@ -7,47 +7,67 @@ const LibExeObjStep = std.build.LibExeObjStep; const Target = std.Target; pub fn build(b: *std.build.Builder) !void { + const root_path = b.pathFromRoot("."); + var cwd = try fs.openDirAbsolute(root_path, .{}); + defer cwd.close(); + const src_path = "src/libsodium"; - const src_dir = try fs.Dir.openIterableDir(fs.cwd(), src_path, .{ .no_follow = true }); + const src_dir = try fs.Dir.openIterableDir(cwd, src_path, .{ .no_follow = true }); const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const enable_benchmarks = b.option(bool, "enable_benchmarks", "Whether tests should be benchmarks.") orelse false; const benchmarks_iterations = b.option(u32, "iterations", "Number of iterations for benchmarks.") orelse 200; + var build_static = b.option(bool, "static", "Build libsodium as a static library.") orelse true; + const build_shared = b.option(bool, "shared", "Build libsodium as a shared library.") orelse true; - const static = b.addStaticLibrary(.{ + const build_tests = b.option(bool, "test", "Build the tests (implies -Dstatic=true)") orelse true; + + if (build_tests) { + build_static = true; + } + const static_lib = b.addStaticLibrary(.{ .name = "sodium", .target = target, .optimize = optimize, }); - - const shared = b.addSharedLibrary(.{ + const shared_lib = b.addSharedLibrary(.{ .name = if (target.isWindows()) "sodium_shared" else "sodium", .target = target, .optimize = optimize, }); - const libs = [_]*LibExeObjStep{ static, shared }; + // work out which libraries we are building + var libs = std.ArrayList(*LibExeObjStep).init(b.allocator); + defer libs.deinit(); + if (build_static) { + try libs.append(static_lib); + } + if (build_shared) { + try libs.append(shared_lib); + } const prebuilt_version_file_path = "builds/msvc/version.h"; const version_file_path = "include/sodium/version.h"; if (src_dir.dir.access(version_file_path, .{ .mode = .read_only })) {} else |_| { - try fs.cwd().copyFile(prebuilt_version_file_path, src_dir.dir, version_file_path, .{}); + try cwd.copyFile(prebuilt_version_file_path, src_dir.dir, version_file_path, .{}); } - for (libs) |lib| { - if (lib == shared and + for (libs.items) |lib| { + if (lib.isDynamicLibrary() and !(target.isDarwin() or target.isDragonFlyBSD() or target.isFreeBSD() or target.isLinux() or target.isNetBSD() or target.isOpenBSD() or target.isWindows())) { continue; } - if (optimize != .Debug and !target.isWindows() and lib != static) { + if (optimize != .Debug and !target.isWindows() and !lib.isStaticLibrary()) { lib.strip = true; } b.installArtifact(lib); + lib.installHeader(src_path ++ "/include/sodium.h", "sodium.h"); + lib.installHeadersDirectory(src_path ++ "/include/sodium", "sodium"); lib.linkLibC(); lib.addIncludePath(.{ .path = "src/libsodium/include/sodium" }); @@ -99,7 +119,7 @@ pub fn build(b: *std.build.Builder) !void { .windows => { lib.defineCMacro("HAVE_RAISE", "1"); lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); - if (lib == static) { + if (lib.isStaticLibrary()) { lib.defineCMacro("SODIUM_STATIC", "1"); } }, @@ -208,41 +228,43 @@ pub fn build(b: *std.build.Builder) !void { const test_path = "test/default"; const out_bin_path = "zig-out/bin"; - const test_dir = try fs.Dir.openIterableDir(fs.cwd(), test_path, .{ .no_follow = true }); - fs.Dir.makePath(fs.cwd(), out_bin_path) catch {}; - const out_bin_dir = try fs.Dir.openDir(fs.cwd(), out_bin_path, .{}); + const test_dir = try fs.Dir.openIterableDir(cwd, test_path, .{ .no_follow = true }); + fs.Dir.makePath(cwd, out_bin_path) catch {}; + const out_bin_dir = try fs.Dir.openDir(cwd, out_bin_path, .{}); try test_dir.dir.copyFile("run.sh", out_bin_dir, "run.sh", .{}); var allocator = heap.page_allocator; var walker = try test_dir.walk(allocator); - while (try walker.next()) |entry| { - const name = entry.basename; - if (mem.endsWith(u8, name, ".exp")) { - try test_dir.dir.copyFile(name, out_bin_dir, name, .{}); - continue; - } - if (!mem.endsWith(u8, name, ".c")) { - continue; - } - const exe_name = name[0 .. name.len - 2]; - var exe = b.addExecutable(.{ - .name = exe_name, - .target = target, - .optimize = optimize, - }); - exe.linkLibC(); - exe.strip = true; - exe.linkLibrary(static); - exe.addIncludePath(.{ .path = "src/libsodium/include" }); - exe.addIncludePath(.{ .path = "test/quirks" }); - const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ test_path, entry.path }); - exe.addCSourceFiles(&.{full_path}, &.{}); + if (build_tests) { + while (try walker.next()) |entry| { + const name = entry.basename; + if (mem.endsWith(u8, name, ".exp")) { + try test_dir.dir.copyFile(name, out_bin_dir, name, .{}); + continue; + } + if (!mem.endsWith(u8, name, ".c")) { + continue; + } + const exe_name = name[0 .. name.len - 2]; + var exe = b.addExecutable(.{ + .name = exe_name, + .target = target, + .optimize = optimize, + }); + exe.linkLibC(); + exe.strip = true; + exe.linkLibrary(static_lib); + exe.addIncludePath(.{ .path = "src/libsodium/include" }); + exe.addIncludePath(.{ .path = "test/quirks" }); + const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ test_path, entry.path }); + exe.addCSourceFiles(&.{full_path}, &.{}); - if (enable_benchmarks) { - exe.defineCMacro("BENCHMARKS", "1"); - var buf: [16]u8 = undefined; - exe.defineCMacro("ITERATIONS", std.fmt.bufPrintIntToSlice(&buf, benchmarks_iterations, 10, .lower, .{})); - } + if (enable_benchmarks) { + exe.defineCMacro("BENCHMARKS", "1"); + var buf: [16]u8 = undefined; + exe.defineCMacro("ITERATIONS", std.fmt.bufPrintIntToSlice(&buf, benchmarks_iterations, 10, .lower, .{})); + } - b.installArtifact(exe); + b.installArtifact(exe); + } } }