diff --git a/.gitmodules b/.gitmodules index 4df722c19..40da184a3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,6 @@ [submodule "vendor/mach-glfw"] path = vendor/mach-glfw url = https://github.com/mitchellh/mach-glfw.git +[submodule "vendor/libxml2"] + path = vendor/libxml2 + url = https://github.com/GNOME/libxml2.git diff --git a/pkg/libxml2/build.zig b/pkg/libxml2/build.zig new file mode 100644 index 000000000..979021308 --- /dev/null +++ b/pkg/libxml2/build.zig @@ -0,0 +1,221 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) !void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const upstream_root = "../../vendor/libxml2"; + + const lib = b.addStaticLibrary(.{ + .name = "xml2", + .target = target, + .optimize = optimize, + }); + lib.linkLibC(); + + lib.addIncludePath(.{ .path = upstream_root ++ "/include" }); + lib.addIncludePath(.{ .path = "override/include" }); + if (target.isWindows()) { + lib.addIncludePath(.{ .path = "override/config/win32" }); + lib.linkSystemLibrary("ws2_32"); + } else { + lib.addIncludePath(.{ .path = "override/config/posix" }); + } + + var flags = std.ArrayList([]const u8).init(b.allocator); + defer flags.deinit(); + try flags.appendSlice(&.{ + // Version info, hardcoded + comptime "-DLIBXML_VERSION=" ++ Version.number(), + comptime "-DLIBXML_VERSION_STRING=" ++ Version.string(), + "-DLIBXML_VERSION_EXTRA=\"\"", + comptime "-DLIBXML_DOTTED_VERSION=" ++ Version.dottedString(), + + // These might now always be true (particularly Windows) but for + // now we just set them all. We should do some detection later. + "-DSEND_ARG2_CAST=", + "-DGETHOSTBYNAME_ARG_CAST=", + "-DGETHOSTBYNAME_ARG_CAST_CONST=", + + // Always on + "-DLIBXML_STATIC=1", + "-DLIBXML_AUTOMATA_ENABLED=1", + "-DWITHOUT_TRIO=1", + }); + if (!target.isWindows()) { + try flags.appendSlice(&.{ + "-DHAVE_ARPA_INET_H=1", + "-DHAVE_ARPA_NAMESER_H=1", + "-DHAVE_DL_H=1", + "-DHAVE_NETDB_H=1", + "-DHAVE_NETINET_IN_H=1", + "-DHAVE_PTHREAD_H=1", + "-DHAVE_SHLLOAD=1", + "-DHAVE_SYS_DIR_H=1", + "-DHAVE_SYS_MMAN_H=1", + "-DHAVE_SYS_NDIR_H=1", + "-DHAVE_SYS_SELECT_H=1", + "-DHAVE_SYS_SOCKET_H=1", + "-DHAVE_SYS_TIMEB_H=1", + "-DHAVE_SYS_TIME_H=1", + "-DHAVE_SYS_TYPES_H=1", + }); + } + + // Enable our `./configure` options. For bool-type fields we translate + // it to the `LIBXML_{field}_ENABLED` C define where field is uppercased. + inline for (std.meta.fields(Options)) |field| { + const opt = b.option(bool, field.name, "Configure flag") orelse + @as(*const bool, @ptrCast(field.default_value.?)).*; + if (opt) { + var nameBuf: [32]u8 = undefined; + const name = std.ascii.upperString(&nameBuf, field.name); + const define = try std.fmt.allocPrint(b.allocator, "-DLIBXML_{s}_ENABLED=1", .{name}); + try flags.append(define); + + if (std.mem.eql(u8, field.name, "history")) { + try flags.appendSlice(&.{ + "-DHAVE_LIBHISTORY=1", + "-DHAVE_LIBREADLINE=1", + }); + } + if (std.mem.eql(u8, field.name, "mem_debug")) { + try flags.append("-DDEBUG_MEMORY_LOCATION=1"); + } + if (std.mem.eql(u8, field.name, "regexp")) { + try flags.append("-DLIBXML_UNICODE_ENABLED=1"); + } + if (std.mem.eql(u8, field.name, "run_debug")) { + try flags.append("-DLIBXML_DEBUG_RUNTIME=1"); + } + if (std.mem.eql(u8, field.name, "thread")) { + try flags.append("-DHAVE_LIBPTHREAD=1"); + } + } + } + + inline for (srcs) |src| { + lib.addCSourceFile(.{ + .file = .{ .path = upstream_root ++ "/" ++ src }, + .flags = flags.items, + }); + } + + lib.installHeader("override/include/libxml/xmlversion.h", "libxml/xmlversion.h"); + lib.installHeadersDirectoryOptions(.{ + .source_dir = .{ .path = upstream_root ++ "/include" }, + .install_dir = .header, + .install_subdir = "", + .include_extensions = &.{".h"}, + }); + + b.installArtifact(lib); +} + +/// The version information for this library. This is hardcoded for now but +/// in the future we will parse this from configure.ac. +pub const Version = struct { + pub const major = "2"; + pub const minor = "11"; + pub const micro = "5"; + + pub fn number() []const u8 { + return comptime major ++ "0" ++ minor ++ "0" ++ micro; + } + + pub fn string() []const u8 { + return comptime "\"" ++ number() ++ "\""; + } + + pub fn dottedString() []const u8 { + return comptime "\"" ++ major ++ "." ++ minor ++ "." ++ micro ++ "\""; + } +}; + +/// Compile-time options for the library. These mostly correspond to +/// options exposed by the native build system used by the library. +/// These are mapped to `b.option` calls. +const Options = struct { + // These options are all defined in libxml2's configure.c and correspond + // to `--with-X` options for `./configure`. Their defaults are properly set. + c14n: bool = true, + catalog: bool = true, + debug: bool = true, + ftp: bool = false, + history: bool = true, + html: bool = true, + iconv: bool = true, + icu: bool = false, + iso8859x: bool = true, + legacy: bool = false, + mem_debug: bool = false, + minimum: bool = true, + output: bool = true, + pattern: bool = true, + push: bool = true, + reader: bool = true, + regexp: bool = true, + run_debug: bool = false, + sax1: bool = true, + schemas: bool = true, + schematron: bool = true, + thread: bool = true, + thread_alloc: bool = false, + tree: bool = true, + valid: bool = true, + writer: bool = true, + xinclude: bool = true, + xpath: bool = true, + xptr: bool = true, + xptr_locs: bool = false, + modules: bool = true, + lzma: bool = false, + zlib: bool = false, +}; + +const srcs = &.{ + "buf.c", + "c14n.c", + "catalog.c", + "chvalid.c", + "debugXML.c", + "dict.c", + "encoding.c", + "entities.c", + "error.c", + "globals.c", + "hash.c", + "HTMLparser.c", + "HTMLtree.c", + "legacy.c", + "list.c", + "nanoftp.c", + "nanohttp.c", + "parser.c", + "parserInternals.c", + "pattern.c", + "relaxng.c", + "SAX.c", + "SAX2.c", + "schematron.c", + "threads.c", + "tree.c", + "uri.c", + "valid.c", + "xinclude.c", + "xlink.c", + "xmlIO.c", + "xmlmemory.c", + "xmlmodule.c", + "xmlreader.c", + "xmlregexp.c", + "xmlsave.c", + "xmlschemas.c", + "xmlschemastypes.c", + "xmlstring.c", + "xmlunicode.c", + "xmlwriter.c", + "xpath.c", + "xpointer.c", + "xzlib.c", +}; diff --git a/pkg/libxml2/build.zig.zon b/pkg/libxml2/build.zig.zon new file mode 100644 index 000000000..403292ca3 --- /dev/null +++ b/pkg/libxml2/build.zig.zon @@ -0,0 +1,5 @@ +.{ + .name = "libxml2", + .version = "2.11.5", + .dependencies = .{}, +} diff --git a/pkg/libxml2/override/config/posix/config.h b/pkg/libxml2/override/config/posix/config.h new file mode 100644 index 000000000..442284980 --- /dev/null +++ b/pkg/libxml2/override/config/posix/config.h @@ -0,0 +1,80 @@ +// This recreates parts of the generated config.h from cmake. Most of the +// defines actually happen directly in libxml2.zig. Some of these SHOULD +// be converted to build-time determined. + +/* Whether struct sockaddr::__ss_family exists */ +// #define HAVE_BROKEN_SS_FAMILY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Have dlopen based dso */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `ftime' function. */ +#define HAVE_FTIME 1 + +/* Define if getaddrinfo is there */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isascii' function. */ +#define HAVE_ISASCII 1 + +/* Define to 1 if you have the `mmap' function. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* mmap() is no good without munmap() */ +#if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP) +# undef /**/ HAVE_MMAP +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if you have the `rand_r' function. */ +#define HAVE_RAND_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define to 1 if you have the `stat' function. */ +#define HAVE_STAT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Whether va_copy() is available */ +#define HAVE_VA_COPY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ZLIB_H 1 + +/* Whether __va_copy() is available */ +#define HAVE___VA_COPY 1 + +/* Support for IPv6 */ +#define SUPPORT_IP6 1 + +/* Define if va_list is an array type */ +#define VA_LIST_IS_ARRAY 1 diff --git a/pkg/libxml2/override/config/win32/config.h b/pkg/libxml2/override/config/win32/config.h new file mode 100644 index 000000000..5108d08c0 --- /dev/null +++ b/pkg/libxml2/override/config/win32/config.h @@ -0,0 +1,20 @@ +#ifndef __LIBXML_WIN32_CONFIG__ +#define __LIBXML_WIN32_CONFIG__ + +#define SEND_ARG2_CAST +#define GETHOSTBYNAME_ARG_CAST + +#define HAVE_SYS_STAT_H +#define HAVE_STAT +#define HAVE_FCNTL_H + +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_STDINT_H +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif + +#endif /* __LIBXML_WIN32_CONFIG__ */ diff --git a/pkg/libxml2/override/include/libxml/xmlversion.h b/pkg/libxml2/override/include/libxml/xmlversion.h new file mode 100644 index 000000000..039d704dc --- /dev/null +++ b/pkg/libxml2/override/include/libxml/xmlversion.h @@ -0,0 +1,18 @@ +// This recreates parts of the generated libxml/xmlversion.h.in that we need +// to build libxml2 without actually templating the header file. We define most +// of the defines in that file using flags to the compiler in libxml2.zig + +#ifndef __XML_VERSION_H__ +#define __XML_VERSION_H__ + +#include + +// We are not GCC. +#define XML_IGNORE_FPTR_CAST_WARNINGS +#define XML_POP_WARNINGS +#define LIBXML_ATTR_FORMAT(fmt,args) +#define LIBXML_ATTR_ALLOC_SIZE(x) +#define ATTRIBUTE_UNUSED +#define XML_DEPRECATED + +#endif diff --git a/vendor/libxml2 b/vendor/libxml2 new file mode 160000 index 000000000..58de9d31d --- /dev/null +++ b/vendor/libxml2 @@ -0,0 +1 @@ +Subproject commit 58de9d31da4d0e8cb6bcf7f5e99714f9df2c4411