Compare commits

...

4 Commits

Author SHA1 Message Date
9679f074d2
build: update for zig-0.12.0-dev.2208+4debd4338
Incorporate various build API changes. Hopefully there won't be any
other major API changes before the 0.12.0 release.
2024-01-15 15:38:06 -08:00
c673c25fc9
readme: update 2024-01-15 15:38:06 -08:00
7940593eb8
build: remove unused code 2024-01-15 15:30:20 -08:00
e68d5f484b
build: handle architecture include more gracefully
The "openssl/opensslconf.h" header is copied from an
architecture-specific source file, which means that specific path is
not valid within the source tree. I previously hacked around this by
copying the file within the source tree, but that had the major
downside of invalidating various cache layers after the copy was
performed.

Since we install this header with the right name, a slightly better
solution, hopefully, is to add the header install path as an include
directory. In theory, this will not invalidate any caching and improve
the build process slightly.
2024-01-15 15:28:44 -08:00
2 changed files with 28 additions and 76 deletions

View File

@ -4,13 +4,13 @@ This is a somewhat hacky port of the LibreSSL build system to Zig. It builds Lib
Notes: Notes:
1. In order for this to work, `.\update.sh` must have first been run to bring in the LibreSSL OpenBSD sources. (Or, if you trust me, you may use the `zig-3.8.1` branch which has the upstream sources committed to the repository, for ease of use with the Zig package manager). 1. In order for this to work, `.\update.sh` must have first been run to bring in the LibreSSL OpenBSD sources. (Or, if you trust me, you may use the `zig-3.8.2` branch which has the upstream sources committed to the repository, for ease of use with the Zig package manager).
2. I don't know if this causes LibreSSL to be compiled in a way that Compromises Its Cryptographic Integrity. Hopefully it is not even possible to do such a thing in the first place. But I am not an expert, and I ain't looking to port the tests. 2. I don't know if this causes LibreSSL to be compiled in a way that Compromises Its Cryptographic Integrity. Hopefully it is not even possible to do such a thing in the first place. But I am not an expert, and I ain't looking to port the tests.
3. This does not (currently) compile the assembly routines, only the C versions, which may cause reduced performance on some platforms. 3. This does not (currently) compile the assembly routines, only the C versions, which may cause reduced performance on some platforms.
4. Only the "big 3" platforms are supported (namely: macOS, Linux, and Windows), and they may be poorly supported, at that. I can cross compile to them from my computer but I have not tried natively compiling on all platforms. 4. Only the "big 3" platforms are supported (namely: macOS, Linux, and Windows). Native and cross-compilation appears to work on modern versions of all three, but this has not been exhaustively tested.
5. Why LibreSSL? It has a CMake-based build system rather than the insane hand-rolled perl mess that OpenSSL does, so it was very straightforward to follow the build process for the purposes of porting it. In theory, its OpenSSL compatibility layer makes it possible to use with a variety of other programs that want to link OpenSSL. 5. Why LibreSSL? It has a CMake-based build system rather than the insane hand-rolled perl mess that OpenSSL does, so it was very straightforward to follow the build process for the purposes of porting it. In theory, its OpenSSL compatibility layer makes it possible to use with a variety of other programs that want to link OpenSSL.

100
build.zig
View File

@ -5,11 +5,12 @@ const LibreSslBuildOptions = struct {
libcrypto_name: []const u8 = "crypto", libcrypto_name: []const u8 = "crypto",
libssl_name: []const u8 = "ssl", libssl_name: []const u8 = "ssl",
libtls_name: []const u8 = "tls", libtls_name: []const u8 = "tls",
target: std.zig.CrossTarget, target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode, optimize: std.builtin.OptimizeMode,
}; };
const LibreSslLibs = struct { const LibreSslLibs = struct {
target: std.Build.ResolvedTarget,
libcrypto: *std.Build.Step.Compile, libcrypto: *std.Build.Step.Compile,
libssl: *std.Build.Step.Compile, libssl: *std.Build.Step.Compile,
libtls: *std.Build.Step.Compile, libtls: *std.Build.Step.Compile,
@ -44,7 +45,7 @@ const LibreSslLibs = struct {
base: []const u8, base: []const u8,
skiplist: []const SkipSpec, skiplist: []const SkipSpec,
) !void { ) !void {
const dir = try b.build_root.handle.openIterableDir(base, .{}); const dir = try b.build_root.handle.openDir(base, .{ .iterate = true });
var walker = try dir.walk(b.allocator); var walker = try dir.walk(b.allocator);
defer walker.deinit(); defer walker.deinit();
@ -68,18 +69,12 @@ const LibreSslLibs = struct {
} }
}; };
// TODO: this doesn't get cached, so it runs on every single build, which kind of sucks.
// Also it won't work on windows.
pub fn patchLibresslCompat(b: *std.Build) !void {
var child = std.ChildProcess.init(&.{ "/bin/sh", "update.sh" }, b.allocator);
_ = try child.spawnAndWait();
}
pub fn libresslBuild( pub fn libresslBuild(
b: *std.Build, b: *std.Build,
options: LibreSslBuildOptions, options: LibreSslBuildOptions,
) !LibreSslLibs { ) !LibreSslLibs {
const libressl_libs: LibreSslLibs = .{ const libressl_libs: LibreSslLibs = .{
.target = options.target,
.libcrypto = b.addStaticLibrary(.{ .libcrypto = b.addStaticLibrary(.{
.name = options.libcrypto_name, .name = options.libcrypto_name,
.target = options.target, .target = options.target,
@ -101,7 +96,7 @@ pub fn libresslBuild(
libressl_libs.linkLibC(); libressl_libs.linkLibC();
const tinfo = libressl_libs.libcrypto.target_info.target; const tinfo = libressl_libs.target.result;
const common_cflags = [_][]const u8{ const common_cflags = [_][]const u8{
"-fno-sanitize=undefined", "-fno-sanitize=undefined",
@ -113,13 +108,13 @@ pub fn libresslBuild(
else => &common_cflags, else => &common_cflags,
}; };
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_sources, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_sources, .flags = cflags });
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_nonasm, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_nonasm, .flags = cflags });
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_nonasm_or_armv4, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_nonasm_or_armv4, .flags = cflags });
libressl_libs.libssl.addCSourceFiles(&libssl_sources, cflags); libressl_libs.libssl.addCSourceFiles(.{ .files = &libssl_sources, .flags = cflags });
libressl_libs.libtls.addCSourceFiles(&libtls_sources, cflags); libressl_libs.libtls.addCSourceFiles(.{ .files = &libtls_sources, .flags = cflags });
libressl_libs.defineCMacro("LIBRESSL_INTERNAL", null); libressl_libs.defineCMacro("LIBRESSL_INTERNAL", null);
libressl_libs.defineCMacro("OPENSSL_NO_HW_PADLOCK", null); libressl_libs.defineCMacro("OPENSSL_NO_HW_PADLOCK", null);
@ -130,8 +125,8 @@ pub fn libresslBuild(
switch (tinfo.os.tag) { switch (tinfo.os.tag) {
.macos => { .macos => {
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_unix_sources, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_unix_sources, .flags = cflags });
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_macos_compat, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_macos_compat, .flags = cflags });
libressl_libs.defineCMacro("HAVE_CLOCK_GETTIME", null); libressl_libs.defineCMacro("HAVE_CLOCK_GETTIME", null);
libressl_libs.defineCMacro("HAVE_ASPRINTF", null); libressl_libs.defineCMacro("HAVE_ASPRINTF", null);
@ -154,8 +149,8 @@ pub fn libresslBuild(
libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null); libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null);
}, },
.linux => { .linux => {
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_unix_sources, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_unix_sources, .flags = cflags });
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_compat, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_compat, .flags = cflags });
libressl_libs.defineCMacro("_DEFAULT_SOURCE", null); libressl_libs.defineCMacro("_DEFAULT_SOURCE", null);
libressl_libs.defineCMacro("_BSD_SOURCE", null); libressl_libs.defineCMacro("_BSD_SOURCE", null);
@ -183,9 +178,9 @@ pub fn libresslBuild(
libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null); libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null);
if (tinfo.abi.isGnu()) { if (tinfo.abi.isGnu()) {
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_glibc_compat, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_glibc_compat, .flags = cflags });
} else if (tinfo.abi.isMusl()) { } else if (tinfo.abi.isMusl()) {
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_musl_compat, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_musl_compat, .flags = cflags });
libressl_libs.defineCMacro("HAVE_STRLCAT", null); libressl_libs.defineCMacro("HAVE_STRLCAT", null);
libressl_libs.defineCMacro("HAVE_STRLCPY", null); libressl_libs.defineCMacro("HAVE_STRLCPY", null);
@ -195,9 +190,9 @@ pub fn libresslBuild(
libressl_libs.linkSystemLibrary("pthread"); libressl_libs.linkSystemLibrary("pthread");
}, },
.windows => { .windows => {
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_windows_sources, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_windows_sources, .flags = cflags });
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_windows_compat, cflags); libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_windows_compat, .flags = cflags });
libressl_libs.libtls.addCSourceFiles(&libtls_windows_sources, cflags); libressl_libs.libtls.addCSourceFiles(.{ .files = &libtls_windows_sources, .flags = cflags });
if (tinfo.abi != .msvc) { if (tinfo.abi != .msvc) {
libressl_libs.defineCMacro("_GNU_SOURCE", null); libressl_libs.defineCMacro("_GNU_SOURCE", null);
@ -243,13 +238,6 @@ pub fn libresslBuild(
else => @panic("unsupported target CPU arch"), else => @panic("unsupported target CPU arch"),
}; };
try b.build_root.handle.copyFile(
conf_header,
b.build_root.handle,
source_header_prefix ++ "openssl/opensslconf.h",
.{},
);
libressl_libs.libcrypto.installHeader(conf_header, "openssl/opensslconf.h"); libressl_libs.libcrypto.installHeader(conf_header, "openssl/opensslconf.h");
libressl_libs.libssl.installHeader(conf_header, "openssl/opensslconf.h"); libressl_libs.libssl.installHeader(conf_header, "openssl/opensslconf.h");
libressl_libs.libtls.installHeader(conf_header, "openssl/opensslconf.h"); libressl_libs.libtls.installHeader(conf_header, "openssl/opensslconf.h");
@ -296,6 +284,13 @@ pub fn libresslBuild(
else => @panic("unsupported target CPU arch"), else => @panic("unsupported target CPU arch"),
} }
// add the header install path to the include path so that compilation will pick
// up "openssl/opensslconf.h". This is added last to avoid interfering with the
// somewhat messy include handling that libressl does.
libressl_libs.libcrypto.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
libressl_libs.libssl.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
libressl_libs.libtls.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
libressl_libs.libssl.linkLibrary(libressl_libs.libcrypto); libressl_libs.libssl.linkLibrary(libressl_libs.libcrypto);
// cmake builds libtls with libcrypto and libssl symbols jammed into it. However, // cmake builds libtls with libcrypto and libssl symbols jammed into it. However,
@ -314,7 +309,6 @@ pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
// if (builtin.os.tag != .windows) try patchLibresslCompat(b);
_ = try libresslBuild(b, .{ .target = target, .optimize = optimize }); _ = try libresslBuild(b, .{ .target = target, .optimize = optimize });
} }
@ -454,48 +448,6 @@ const libcrypto_windows_compat = [_][]const u8{
libcrypto_src_prefix ++ "compat/timingsafe_memcmp.c", libcrypto_src_prefix ++ "compat/timingsafe_memcmp.c",
}; };
// const libcrypto_compat_sources = [_][]const u8{
// libcrypto_src_prefix ++ "compat/bsd-asprintf.c",
// libcrypto_src_prefix ++ "compat/freezero.c",
// libcrypto_src_prefix ++ "compat/getpagesize.c",
// libcrypto_src_prefix ++ "compat/getprogname_windows.c",
// libcrypto_src_prefix ++ "compat/getprogname_linux.c",
// libcrypto_src_prefix ++ "compat/getprogname_unimpl.c",
// libcrypto_src_prefix ++ "compat/reallocarray.c",
// libcrypto_src_prefix ++ "compat/recallocarray.c",
// libcrypto_src_prefix ++ "compat/strcasecmp.c",
// libcrypto_src_prefix ++ "compat/strlcat.c",
// libcrypto_src_prefix ++ "compat/strlcpy.c",
// libcrypto_src_prefix ++ "compat/strndup.c",
// libcrypto_src_prefix ++ "compat/strnlen.c",
// libcrypto_src_prefix ++ "compat/strsep.c",
// libcrypto_src_prefix ++ "compat/strtonum.c",
// libcrypto_src_prefix ++ "compat/syslog_r.c",
// libcrypto_src_prefix ++ "compat/timegm.c",
// libcrypto_src_prefix ++ "compat/explicit_bzero_win.c",
// libcrypto_src_prefix ++ "compat/explicit_bzero.c",
// libcrypto_src_prefix ++ "compat/arc4random.c",
// libcrypto_src_prefix ++ "compat/arc4random_uniform.c",
// libcrypto_src_prefix ++ "compat/getentropy_win.c",
// libcrypto_src_prefix ++ "compat/getentropy_aix.c",
// libcrypto_src_prefix ++ "compat/getentropy_freebsd.c",
// libcrypto_src_prefix ++ "compat/getentropy_hpux.c",
// libcrypto_src_prefix ++ "compat/getentropy_linux.c",
// libcrypto_src_prefix ++ "compat/getentropy_netbsd.c",
// libcrypto_src_prefix ++ "compat/getentropy_osx.c",
// libcrypto_src_prefix ++ "compat/getentropy_solaris.c",
// libcrypto_src_prefix ++ "compat/timingsafe_bcmp.c",
// libcrypto_src_prefix ++ "compat/timingsafe_memcmp.c",
// };
const libcrypto_sources = [_][]const u8{ const libcrypto_sources = [_][]const u8{
libcrypto_src_prefix ++ "cpt_err.c", libcrypto_src_prefix ++ "cpt_err.c",
libcrypto_src_prefix ++ "cryptlib.c", libcrypto_src_prefix ++ "cryptlib.c",