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
This commit is contained in:
Fergus Baker
2023-09-09 00:39:15 +02:00
committed by GitHub
parent 94c650ae80
commit 5191b40acc
+63 -41
View File
@@ -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);
}
}
}