Skip to content

Commit 70cd398

Browse files
committed
initial commit
0 parents  commit 70cd398

File tree

7 files changed

+399
-0
lines changed

7 files changed

+399
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.zig text eol=lf
2+
*.zon text eol=lf

.github/workflows/ci.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
workflow_dispatch:
11+
12+
jobs:
13+
build:
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
zig-version: [master]
18+
os: [ubuntu-latest, macos-latest, windows-latest]
19+
include:
20+
- zig-version: "0.12.1"
21+
os: ubuntu-latest
22+
- zig-version: "0.13.0"
23+
os: ubuntu-latest
24+
runs-on: ${{ matrix.os }}
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup Zig
30+
uses: mlugg/setup-zig@v1
31+
with:
32+
version: ${{ matrix.zig-version }}
33+
34+
- name: Check Formatting
35+
run: zig fmt --ast-check --check .
36+
37+
- name: Build
38+
run: zig build -Diconv=false --summary all

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.zig-cache
2+
zig-cache
3+
zig-out

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (Expat)
2+
3+
Copyright (c) contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[![CI](https://github.com/allyourcodebase/libxml2/actions/workflows/ci.yaml/badge.svg)](https://github.com/allyourcodebase/libxml2/actions)
2+
3+
# libxml2
4+
5+
This is [libxml2](https://gitlab.gnome.org/GNOME/libxml2), packaged for [Zig](https://ziglang.org/).
6+
7+
## Installation
8+
9+
First, update your `build.zig.zon`:
10+
11+
```
12+
# Initialize a `zig build` project if you haven't already
13+
zig init
14+
zig fetch --save git+https://github.com/allyourcodebase/libxml2.git
15+
```
16+
17+
You can then import `libxml2` in your `build.zig` with:
18+
19+
```zig
20+
const libxml2_dependency = b.dependency("libxml2", .{
21+
.target = target,
22+
.optimize = optimize,
23+
.iconv = false, // This would link to `libiconv` otherwise
24+
});
25+
your_exe.linkLibrary(libxml2_dependency.artifact("libxml2"));
26+
```

build.zig

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
const std = @import("std");
2+
3+
const version: std.SemanticVersion = .{ .major = 2, .minor = 13, .patch = 5 };
4+
5+
pub fn build(b: *std.Build) void {
6+
const upstream = b.dependency("libxml2", .{});
7+
const target = b.standardTargetOptions(.{});
8+
const optimize = b.standardOptimizeOption(.{});
9+
10+
// Most of these config options have not been tested.
11+
12+
const minimum = b.option(bool, "minimum", "build a minimally sized library (default=false)") orelse false;
13+
const legacy = b.option(bool, "legacy", "maximum ABI compatibility (default=false)") orelse false;
14+
const tls = b.option(bool, "tls", "thread-local storage (default=false)") orelse false;
15+
16+
var c14n = b.option(bool, "c14n", "Canonical XML 1.0 support (default=true)") orelse !minimum;
17+
const catalog = b.option(bool, "catalog", "XML Catalogs support (default=true)") orelse !minimum;
18+
const debug = b.option(bool, "debug", "debugging module (default=true)") orelse !minimum;
19+
const ftp = b.option(bool, "ftp", "FTP support (default=false)") orelse false;
20+
const history = b.option(bool, "history", "history support for xmllint shell (default=false)") orelse false;
21+
var readline = b.option(bool, "readline", "use readline in DIR for shell (default=off)") orelse !minimum and history;
22+
const html = b.option(bool, "html", "HTML parser (default=true)") orelse !minimum;
23+
const http = b.option(bool, "http", "HTTP support (default=false)") orelse legacy;
24+
const iconv = b.option(bool, "iconv", "iconv support (default=on)") orelse !minimum;
25+
const icu = b.option(bool, "icu", "ICU support (default=false)") orelse false;
26+
const iso8859x = b.option(bool, "iso8859x", "ISO-8859-X support if no iconv (default=true)") orelse !minimum;
27+
const lzma = b.option(bool, "lzma", "use liblzma in DIR (default=off)") orelse legacy;
28+
// const modules = b.option(bool, "modules", "dynamic modules support (default=true)") orelse !minimum;
29+
var output = b.option(bool, "output", "serialization support (default=true)") orelse !minimum;
30+
var pattern = b.option(bool, "pattern", "xmlPattern selection interface (default=true)") orelse !minimum;
31+
var push = b.option(bool, "push", "push parser interfaces (default=true)") orelse !minimum;
32+
// const python = b.option(bool, "python", "Python bindings (default=true)") orelse !minimum;
33+
var reader = b.option(bool, "reader", "xmlReader parsing interface (default=true)") orelse !minimum;
34+
var regexps = b.option(bool, "regexps", "regular expressions support (default=true)") orelse !minimum;
35+
const sax1 = b.option(bool, "sax1", "older SAX1 interface (default=true)") orelse !minimum;
36+
var schemas = b.option(bool, "schemas", "XML Schemas 1.0 and RELAX NG support (default=true)") orelse !minimum;
37+
var schematron = b.option(bool, "schematron", "Schematron support (default=true)") orelse !minimum;
38+
const threads = b.option(bool, "threads", "multithreading support (default=true)") orelse !minimum;
39+
const thread_alloc = b.option(bool, "thread-alloc", "per-thread malloc hooks (default=false)") orelse false;
40+
const valid = b.option(bool, "valid", "DTD validation support (default=true)") orelse !minimum;
41+
var writer = b.option(bool, "writer", "xmlWriter serialization interface (default=true)") orelse !minimum;
42+
var xinclude = b.option(bool, "xinclude", "XInclude 1.0 support (default=true)") orelse !minimum;
43+
var xpath = b.option(bool, "xpath", "XPath 1.0 support (default=true)") orelse !minimum;
44+
var xptr = b.option(bool, "xptr", "XPointer support (default=true)") orelse !minimum;
45+
const xptr_locs = b.option(bool, "xptr-locs", "XPointer ranges and points (default=false)") orelse false;
46+
const zlib = b.option(bool, "zlib", "use libz in DIR") orelse legacy;
47+
48+
if (c14n) {
49+
if (!output) {
50+
std.log.warn("-Dc14n overrides -Doutput=false", .{});
51+
output = true;
52+
}
53+
if (!xpath) {
54+
std.log.warn("-Dc14n overrides -Dxpath=false", .{});
55+
xpath = true;
56+
}
57+
}
58+
if (schemas) {
59+
if (!pattern) {
60+
std.log.warn("-Dschemas overrides -Dpattern=false", .{});
61+
pattern = true;
62+
}
63+
if (!regexps) {
64+
std.log.warn("-Dschemas overrides -Dregexps=false", .{});
65+
regexps = true;
66+
}
67+
}
68+
if (schematron) {
69+
if (!pattern) {
70+
std.log.warn("-Dschematron overrides -Dpattern=false", .{});
71+
pattern = true;
72+
}
73+
if (!xpath) {
74+
std.log.warn("-Dschematron overrides -Dxpath=false", .{});
75+
xpath = true;
76+
}
77+
}
78+
if (reader) {
79+
if (!push) {
80+
std.log.warn("-Dreader overrides -Dpush=false", .{});
81+
push = true;
82+
}
83+
}
84+
if (writer) {
85+
if (!output) {
86+
std.log.warn("-Dwriter overrides -Doutput=false", .{});
87+
output = true;
88+
}
89+
if (!push) {
90+
std.log.warn("-Dwriter overrides -Dpush=false", .{});
91+
push = true;
92+
}
93+
}
94+
if (xinclude) {
95+
if (!xpath) {
96+
std.log.warn("-Dxinclude overrides -Dxpath=false", .{});
97+
xpath = true;
98+
}
99+
}
100+
if (xptr_locs) {
101+
if (!xpath) {
102+
std.log.warn("-Dxptr-locs overrides -Dxptr=false", .{});
103+
xpath = true;
104+
}
105+
}
106+
if (xptr) {
107+
if (!xpath) {
108+
std.log.warn("-Dxptr overrides -Dxpath=false", .{});
109+
xpath = true;
110+
}
111+
}
112+
if (history) {
113+
if (!readline) {
114+
std.log.warn("-Dhistory overrides -Dreadline=false", .{});
115+
readline = true;
116+
}
117+
}
118+
119+
if (!minimum) {
120+
if (!output) {
121+
c14n = false;
122+
writer = false;
123+
}
124+
if (!pattern) {
125+
schemas = false;
126+
schematron = false;
127+
}
128+
if (!push) {
129+
reader = false;
130+
writer = false;
131+
}
132+
if (!regexps) {
133+
schemas = false;
134+
}
135+
if (!xpath) {
136+
c14n = false;
137+
schematron = false;
138+
xinclude = false;
139+
xptr = false;
140+
}
141+
}
142+
143+
const xml_version_header = b.addConfigHeader(.{
144+
.include_path = "libxml/xmlversion.h",
145+
.style = .{ .cmake = upstream.path("include/libxml/xmlversion.h.in") },
146+
}, .{
147+
.VERSION = b.fmt("{}", .{version}),
148+
.LIBXML_VERSION_NUMBER = @as(i64, version.major * 10000 + version.major * 100 + version.patch),
149+
.LIBXML_VERSION_EXTRA = "",
150+
.WITH_THREADS = threads,
151+
.WITH_THREAD_ALLOC = threads and thread_alloc,
152+
.WITH_TREE = true,
153+
.WITH_OUTPUT = output,
154+
.WITH_PUSH = push,
155+
.WITH_READER = reader,
156+
.WITH_PATTERN = pattern,
157+
.WITH_WRITER = writer,
158+
.WITH_SAX1 = sax1,
159+
.WITH_FTP = ftp,
160+
.WITH_HTTP = http,
161+
.WITH_VALID = valid,
162+
.WITH_HTML = html,
163+
.WITH_LEGACY = legacy,
164+
.WITH_C14N = c14n,
165+
.WITH_CATALOG = catalog,
166+
.WITH_XPATH = xpath,
167+
.WITH_XPTR = xptr,
168+
.WITH_XPTR_LOCS = xptr_locs,
169+
.WITH_XINCLUDE = xinclude,
170+
.WITH_ICONV = iconv,
171+
.WITH_ICU = icu,
172+
.WITH_ISO8859X = iso8859x,
173+
.WITH_DEBUG = debug,
174+
.WITH_REGEXPS = regexps,
175+
.WITH_SCHEMAS = schemas,
176+
.WITH_SCHEMATRON = schematron,
177+
.WITH_MODULES = false,
178+
.WITH_ZLIB = zlib,
179+
.WITH_LZMA = lzma,
180+
});
181+
182+
const config_header = b.addConfigHeader(.{}, .{
183+
.HAVE_STDINT_H = true,
184+
.HAVE_FCNTL_H = true,
185+
.HAVE_UNISTD_H = true,
186+
.HAVE_SYS_STAT_H = true,
187+
.HAVE_SYS_MMAN_H = true,
188+
.HAVE_SYS_TIME_H = true,
189+
.HAVE_SYS_TIMEB_H = true,
190+
.HAVE_SYS_RANDOM_H = true,
191+
.HAVE_DL_H = true,
192+
.HAVE_DLFCN_H = true,
193+
.HAVE_GLOB_H = true,
194+
.HAVE_DECL_GETENTROPY = true,
195+
.HAVE_DECL_GLOB = true,
196+
.HAVE_DECL_MMAP = true,
197+
.HAVE_POLL_H = true,
198+
.HAVE_ATTRIBUTE_DESTRUCTOR = true,
199+
.ATTRIBUTE_DESTRUCTOR = .@"__attribute__((destructor))",
200+
});
201+
if (tls) {
202+
config_header.addValues(.{ .XML_THREAD_LOCAL = ._Thread_local });
203+
}
204+
205+
const xml_lib = b.addStaticLibrary(.{
206+
.name = "xml",
207+
.target = target,
208+
.optimize = optimize,
209+
.version = version,
210+
.link_libc = true,
211+
});
212+
b.installArtifact((xml_lib));
213+
xml_lib.addConfigHeader(config_header);
214+
xml_lib.addConfigHeader(xml_version_header);
215+
xml_lib.installHeader(xml_version_header.getOutput(), "libxml/xmlversion.h");
216+
xml_lib.addIncludePath(upstream.path("include"));
217+
xml_lib.addCSourceFiles(.{ .files = xml_src, .root = upstream.path(""), .flags = xml_flags });
218+
xml_lib.installHeadersDirectory(upstream.path("include/libxml"), "libxml", .{});
219+
if (target.result.os.tag != .windows) xml_lib.root_module.addCMacro("HAVE_PTHREAD_H", "1");
220+
if (target.result.os.tag == .windows) xml_lib.root_module.addCMacro("LIBXML_STATIC", "1");
221+
if (c14n) xml_lib.addCSourceFile(.{ .file = upstream.path("c14n.c"), .flags = xml_flags });
222+
if (catalog) xml_lib.addCSourceFile(.{ .file = upstream.path("catalog.c"), .flags = xml_flags });
223+
if (debug) xml_lib.addCSourceFile(.{ .file = upstream.path("debugXML.c"), .flags = xml_flags });
224+
if (ftp) xml_lib.addCSourceFile(.{ .file = upstream.path("nanoftp.c"), .flags = xml_flags });
225+
if (html) xml_lib.addCSourceFiles(.{ .files = &.{ "HTMLparser.c", "HTMLtree.c" }, .root = upstream.path(""), .flags = xml_flags });
226+
if (http) xml_lib.addCSourceFile(.{ .file = upstream.path("nanohttp.c"), .flags = xml_flags });
227+
if (legacy) xml_lib.addCSourceFile(.{ .file = upstream.path("legacy.c"), .flags = xml_flags });
228+
if (lzma) xml_lib.addCSourceFile(.{ .file = upstream.path("xzlib.c"), .flags = xml_flags });
229+
// if (modules) xml_lib.addCSourceFile(.{ .file = upstream.path("xmlmodule.c"), .flags = xml_flags });
230+
if (output) xml_lib.addCSourceFile(.{ .file = upstream.path("xmlsave.c"), .flags = xml_flags });
231+
if (pattern) xml_lib.addCSourceFile(.{ .file = upstream.path("pattern.c"), .flags = xml_flags });
232+
if (reader) xml_lib.addCSourceFile(.{ .file = upstream.path("xmlreader.c"), .flags = xml_flags });
233+
if (regexps) xml_lib.addCSourceFiles(.{ .files = &.{ "xmlregexp.c", "xmlunicode.c" }, .root = upstream.path(""), .flags = xml_flags });
234+
if (schemas) xml_lib.addCSourceFiles(.{ .files = &.{ "relaxng.c", "xmlschemas.c", "xmlschemastypes.c" }, .root = upstream.path(""), .flags = xml_flags });
235+
if (schematron) xml_lib.addCSourceFile(.{ .file = upstream.path("schematron.c"), .flags = xml_flags });
236+
if (writer) xml_lib.addCSourceFile(.{ .file = upstream.path("xmlwriter.c"), .flags = xml_flags });
237+
if (xinclude) xml_lib.addCSourceFile(.{ .file = upstream.path("xinclude.c"), .flags = xml_flags });
238+
if (xpath) xml_lib.addCSourceFile(.{ .file = upstream.path("xpath.c"), .flags = xml_flags });
239+
if (xptr) xml_lib.addCSourceFiles(.{ .files = &.{ "xlink.c", "xpointer.c" }, .root = upstream.path(""), .flags = xml_flags });
240+
if (readline) {
241+
xml_lib.linkSystemLibrary("readline");
242+
xml_lib.root_module.addCMacro("HAVE_LIBREADLINE", "1");
243+
}
244+
if (history) {
245+
xml_lib.linkSystemLibrary("history");
246+
xml_lib.root_module.addCMacro("HAVE_LIBHISTORY", "1");
247+
}
248+
if (zlib) xml_lib.linkSystemLibrary("zlib");
249+
if (lzma) xml_lib.linkSystemLibrary("lzma");
250+
if (icu) xml_lib.linkSystemLibrary("icu-i18n");
251+
if (iconv) xml_lib.linkSystemLibrary("iconv");
252+
if (target.result.os.tag == .windows) xml_lib.linkSystemLibrary("bcrypt");
253+
if (http and target.result.os.tag == .windows) xml_lib.linkSystemLibrary("ws2_32");
254+
}
255+
256+
pub const xml_src: []const []const u8 = &.{
257+
"buf.c",
258+
"chvalid.c",
259+
"dict.c",
260+
"entities.c",
261+
"encoding.c",
262+
"error.c",
263+
"globals.c",
264+
"hash.c",
265+
"list.c",
266+
"parser.c",
267+
"parserInternals.c",
268+
"SAX2.c",
269+
"threads.c",
270+
"tree.c",
271+
"uri.c",
272+
"valid.c",
273+
"xmlIO.c",
274+
"xmlmemory.c",
275+
"xmlstring.c",
276+
};
277+
278+
pub const xml_flags: []const []const u8 = &.{
279+
"-pedantic",
280+
"-Wall",
281+
"-Wextra",
282+
"-Wshadow",
283+
"-Wpointer-arith",
284+
"-Wcast-align",
285+
"-Wwrite-strings",
286+
"-Wstrict-prototypes",
287+
"-Wmissing-prototypes",
288+
289+
"-Wno-long-long",
290+
"-Wno-format-extra-args",
291+
"-Wno-array-bounds",
292+
};

0 commit comments

Comments
 (0)