From f1d17b62c1fe3e9109ca56108a3acce5df275279 Mon Sep 17 00:00:00 2001 From: Daniel Hammer Date: Fri, 7 Aug 2026 20:11:55 +0200 Subject: [PATCH] feat: ports - libhubbub, libcss, libdom Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018Ae69wJS7sueQMUwNxV3nX --- .gitmodules | 9 ++++++ Makefile | 3 ++ dev-libs/libparserutils/Makefile | 2 ++ dev-libs/libwapcaplet/Makefile | 2 ++ mk/port.mk | 33 ++++++++++++++++--- net-libs/libcss/Makefile | 34 ++++++++++++++++++++ net-libs/libcss/upstream | 1 + net-libs/libdom/Makefile | 50 +++++++++++++++++++++++++++++ net-libs/libdom/upstream | 1 + net-libs/libhubbub/Makefile | 34 ++++++++++++++++++++ net-libs/libhubbub/upstream | 1 + test/Makefile | 4 +++ test/porttest.c | 55 ++++++++++++++++++++++++++++++++ 13 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 net-libs/libcss/Makefile create mode 160000 net-libs/libcss/upstream create mode 100644 net-libs/libdom/Makefile create mode 160000 net-libs/libdom/upstream create mode 100644 net-libs/libhubbub/Makefile create mode 160000 net-libs/libhubbub/upstream diff --git a/.gitmodules b/.gitmodules index c8851f7..5d29021 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,12 @@ [submodule "dev-libs/libparserutils/upstream"] path = dev-libs/libparserutils/upstream url = https://github.com/netsurf-browser/libparserutils.git +[submodule "net-libs/libhubbub/upstream"] + path = net-libs/libhubbub/upstream + url = https://github.com/netsurf-browser/libhubbub.git +[submodule "net-libs/libcss/upstream"] + path = net-libs/libcss/upstream + url = https://github.com/netsurf-browser/libcss.git +[submodule "net-libs/libdom/upstream"] + path = net-libs/libdom/upstream + url = https://github.com/netsurf-browser/libdom.git diff --git a/Makefile b/Makefile index c94e046..7020008 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,9 @@ PORTS := \ dev-libs/zlib \ dev-libs/libwapcaplet \ dev-libs/libparserutils \ + net-libs/libhubbub \ + net-libs/libcss \ + net-libs/libdom \ games-fps/doom # Bundle directories are keyed by port name, not category path. diff --git a/dev-libs/libparserutils/Makefile b/dev-libs/libparserutils/Makefile index 510f146..e6938de 100644 --- a/dev-libs/libparserutils/Makefile +++ b/dev-libs/libparserutils/Makefile @@ -17,6 +17,8 @@ UPSTREAM := upstream PORT_NAME := libparserutils PORT_LIB := 1 PORT_ARCHIVE := libparserutils.a +PORT_PC_IN := $(UPSTREAM)/libparserutils.pc.in +PORT_PC_VERSION := 0.2.5 PORT_HEADER_ROOT := $(UPSTREAM)/include PORT_HEADERS := $(shell find $(UPSTREAM)/include -name '*.h' 2>/dev/null) diff --git a/dev-libs/libwapcaplet/Makefile b/dev-libs/libwapcaplet/Makefile index 510202f..1da9aff 100644 --- a/dev-libs/libwapcaplet/Makefile +++ b/dev-libs/libwapcaplet/Makefile @@ -12,6 +12,8 @@ UPSTREAM := upstream PORT_NAME := libwapcaplet PORT_LIB := 1 PORT_ARCHIVE := libwapcaplet.a +PORT_PC_IN := $(UPSTREAM)/libwapcaplet.pc.in +PORT_PC_VERSION := 0.4.3 PORT_HEADER_ROOT := $(UPSTREAM)/include PORT_HEADERS := $(UPSTREAM)/include/libwapcaplet/libwapcaplet.h diff --git a/mk/port.mk b/mk/port.mk index 5ada495..00654b5 100644 --- a/mk/port.mk +++ b/mk/port.mk @@ -165,15 +165,24 @@ NS_MAKE_ARGS := \ # archive rule tries to *execute* the .a file (exit 127). NS_MAKE := MAKEFLAGS= $(MAKE) +# Their makefiles resolve dependencies through pkg-config, so point it at the +# ports sysroot (prepended, so host packages still resolve for host tools). +# PYTHON is forced to python3: libcss's codegen invokes $(PYTHON), and this +# host has no bare `python`. +NS_ENV := \ + PKG_CONFIG_PATH="$(PORT_SYSROOT_LIB)/pkgconfig:$$PKG_CONFIG_PATH" \ + PYTHON=python3 + # Build a NetSurf library in $(1) (its checkout dir) and copy the archive to # $(PORT_ARCHIVE). Usage in a recipe: $(call ns_build,upstream,wapcaplet) # A port may add its own flags by setting NS_CFLAGS_EXTRA (expanded at call # time, so it can be set after this file is included). ns_build = \ - CFLAGS="$(NS_CFLAGS) $(NS_CFLAGS_EXTRA)" $(NS_MAKE) -C $(1) $(NS_MAKE_ARGS) && \ + CFLAGS="$(NS_CFLAGS) $(NS_CFLAGS_EXTRA)" $(NS_ENV) \ + $(NS_MAKE) -C $(1) $(NS_MAKE_ARGS) $(NS_MAKE_ARGS_EXTRA) && \ cp $(1)/$(NS_BUILDDIR)/lib$(2).a $(PORT_ARCHIVE) -ns_clean = $(NS_MAKE) -C $(1) $(NS_MAKE_ARGS) clean >/dev/null 2>&1 || true +ns_clean = $(NS_ENV) $(NS_MAKE) -C $(1) $(NS_MAKE_ARGS) clean >/dev/null 2>&1 || true ifeq ($(PORT_LIB),1) @@ -197,13 +206,29 @@ $(PORT_SYSROOT_INC)/%: $(PORT_HEADER_ROOT)/% @mkdir -p $(dir $@) cp $< $@ +# Optional pkg-config file. NetSurf libraries locate their dependencies with +# pkg-config (REQUIRED_PKGS), so a library that others depend on must publish +# one into the sysroot or those builds fail to find it. Their .pc.in files use +# literal PREFIX/LIBDIR/INCLUDEDIR/VERSION placeholders, substituted here the +# same way their install step would. +ifneq ($(PORT_PC_IN),) +INSTALLED_PC := $(PORT_SYSROOT_LIB)/pkgconfig/$(PORT_NAME).pc + +$(INSTALLED_PC): $(PORT_PC_IN) Makefile + @mkdir -p $(dir $@) + sed -e 's|PREFIX|$(PORT_SYSROOT)|' \ + -e 's|LIBDIR|lib|' \ + -e 's|INCLUDEDIR|include|' \ + -e 's|VERSION|$(PORT_PC_VERSION)|' $< > $@ +endif + .PHONY: install-lib -install-lib: $(INSTALLED_LIB) $(INSTALLED_HEADERS) +install-lib: $(INSTALLED_LIB) $(INSTALLED_HEADERS) $(INSTALLED_PC) @echo "installed lib: $(PORT_NAME) -> $(PORT_SYSROOT)" .PHONY: clean-lib clean-lib: - rm -rf $(OBJDIR) $(PORT_ARCHIVE) $(INSTALLED_LIB) $(INSTALLED_HEADERS) + rm -rf $(OBJDIR) $(PORT_ARCHIVE) $(INSTALLED_LIB) $(INSTALLED_HEADERS) $(INSTALLED_PC) else diff --git a/net-libs/libcss/Makefile b/net-libs/libcss/Makefile new file mode 100644 index 0000000..4818540 --- /dev/null +++ b/net-libs/libcss/Makefile @@ -0,0 +1,34 @@ +# libcss for MontaukOS +# +# Upstream: https://github.com/netsurf-browser/libcss (official mirror of +# git.netsurf-browser.org; submodule at upstream/, pinned, no local patches). +# +# CSS parser and selection engine. Depends on libparserutils and +# libwapcaplet, both of which must already be in the ports sysroot. +# +# Needs perl AND python3 on the BUILD host: it generates its property +# parser/computed-style tables at build time. mk/port.mk forces PYTHON=python3 +# because the codegen invokes $(PYTHON) and Debian has no bare `python`. + +UPSTREAM := upstream + +PORT_NAME := libcss +PORT_LIB := 1 +PORT_DEPENDS := libparserutils libwapcaplet +PORT_ARCHIVE := libcss.a +PORT_PC_IN := $(UPSTREAM)/libcss.pc.in +PORT_PC_VERSION := 0.9.2 +PORT_HEADER_ROOT := $(UPSTREAM)/include +PORT_HEADERS := $(shell find $(UPSTREAM)/include -name '*.h' 2>/dev/null) + +include ../../mk/port.mk + +.PHONY: all clean +all: install-lib + +$(PORT_ARCHIVE): $(shell find $(UPSTREAM)/src $(UPSTREAM)/include -name '*.c' -o -name '*.h' 2>/dev/null) + $(call ns_build,$(UPSTREAM),css) + +clean: clean-lib + @$(call ns_clean,$(UPSTREAM)) + rm -rf $(UPSTREAM)/$(NS_BUILDDIR) diff --git a/net-libs/libcss/upstream b/net-libs/libcss/upstream new file mode 160000 index 0000000..58bff86 --- /dev/null +++ b/net-libs/libcss/upstream @@ -0,0 +1 @@ +Subproject commit 58bff86fa858c594b59198956e7f39bd0ecef41f diff --git a/net-libs/libdom/Makefile b/net-libs/libdom/Makefile new file mode 100644 index 0000000..52fa825 --- /dev/null +++ b/net-libs/libdom/Makefile @@ -0,0 +1,50 @@ +# libdom for MontaukOS +# +# Upstream: https://github.com/netsurf-browser/libdom (official mirror of +# git.netsurf-browser.org; submodule at upstream/, pinned, no local patches). +# +# DOM implementation. Depends on libparserutils, libwapcaplet and libhubbub, +# all of which must already be in the ports sysroot -- libdom finds the latter +# two through pkg-config (REQUIRED_PKGS), which is why the library ports +# publish .pc files into sysroot/lib/pkgconfig. +# +# Bindings come from libdom's checked-in Makefile.config, which defaults the +# expat AND hubbub bindings to yes. Those are plain `:=` assignments, so +# passing the variables on the sub-make command line overrides them without +# patching upstream or dropping a Makefile.config.override into the submodule: +# WITH_HUBBUB_BINDING=yes how NetSurf feeds HTML into the DOM; required. +# WITH_EXPAT_BINDING=no defaults to YES upstream and must be turned off +# -- it needs , which MontaukOS has no +# port of, and NetSurf does not use it. +# WITH_LIBXML_BINDING already no in their config; set explicitly so a +# future upstream flip cannot surprise us. +# +# Needs perl on the BUILD host. + +UPSTREAM := upstream + +PORT_NAME := libdom +PORT_LIB := 1 +PORT_DEPENDS := libparserutils libwapcaplet libhubbub +PORT_ARCHIVE := libdom.a +PORT_PC_IN := $(UPSTREAM)/libdom.pc.in +PORT_PC_VERSION := 0.4.2 +PORT_HEADER_ROOT := $(UPSTREAM)/include +PORT_HEADERS := $(shell find $(UPSTREAM)/include -name '*.h' 2>/dev/null) + +include ../../mk/port.mk + +NS_MAKE_ARGS_EXTRA := \ + WITH_HUBBUB_BINDING=yes \ + WITH_EXPAT_BINDING=no \ + WITH_LIBXML_BINDING=no + +.PHONY: all clean +all: install-lib + +$(PORT_ARCHIVE): $(shell find $(UPSTREAM)/src $(UPSTREAM)/bindings $(UPSTREAM)/include -name '*.c' -o -name '*.h' 2>/dev/null) + $(call ns_build,$(UPSTREAM),dom) + +clean: clean-lib + @$(call ns_clean,$(UPSTREAM)) + rm -rf $(UPSTREAM)/$(NS_BUILDDIR) diff --git a/net-libs/libdom/upstream b/net-libs/libdom/upstream new file mode 160000 index 0000000..f69781e --- /dev/null +++ b/net-libs/libdom/upstream @@ -0,0 +1 @@ +Subproject commit f69781e1f062444b5af3f62d431d7d94018da53b diff --git a/net-libs/libhubbub/Makefile b/net-libs/libhubbub/Makefile new file mode 100644 index 0000000..1254150 --- /dev/null +++ b/net-libs/libhubbub/Makefile @@ -0,0 +1,34 @@ +# libhubbub for MontaukOS +# +# Upstream: https://github.com/netsurf-browser/libhubbub (official mirror of +# git.netsurf-browser.org; submodule at upstream/, pinned, no local patches). +# +# HTML5 tokeniser and tree construction. Depends on libparserutils and +# libwapcaplet, both of which must already be in the ports sysroot. +# +# Needs perl on the BUILD host: src/tokeniser/entities.inc is generated from +# build/Entities by build/make-entities.pl. That is a host tool, not a target +# dependency. + +UPSTREAM := upstream + +PORT_NAME := libhubbub +PORT_LIB := 1 +PORT_DEPENDS := libparserutils libwapcaplet +PORT_ARCHIVE := libhubbub.a +PORT_PC_IN := $(UPSTREAM)/libhubbub.pc.in +PORT_PC_VERSION := 0.3.8 +PORT_HEADER_ROOT := $(UPSTREAM)/include +PORT_HEADERS := $(shell find $(UPSTREAM)/include -name '*.h' 2>/dev/null) + +include ../../mk/port.mk + +.PHONY: all clean +all: install-lib + +$(PORT_ARCHIVE): $(shell find $(UPSTREAM)/src $(UPSTREAM)/include -name '*.c' -o -name '*.h' 2>/dev/null) + $(call ns_build,$(UPSTREAM),hubbub) + +clean: clean-lib + @$(call ns_clean,$(UPSTREAM)) + rm -rf $(UPSTREAM)/$(NS_BUILDDIR) diff --git a/net-libs/libhubbub/upstream b/net-libs/libhubbub/upstream new file mode 160000 index 0000000..6651b8c --- /dev/null +++ b/net-libs/libhubbub/upstream @@ -0,0 +1 @@ +Subproject commit 6651b8cf87a4aa87bcdb2ff024a02659cd3f9402 diff --git a/test/Makefile b/test/Makefile index 6a2a410..588add3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -18,7 +18,11 @@ PORT_NAME := porttest include ../mk/port.mk +# Link order matters: dependents before their dependencies. SYSROOT_LIBS := \ + $(PORT_SYSROOT_LIB)/libdom.a \ + $(PORT_SYSROOT_LIB)/libcss.a \ + $(PORT_SYSROOT_LIB)/libhubbub.a \ $(PORT_SYSROOT_LIB)/libparserutils.a \ $(PORT_SYSROOT_LIB)/libwapcaplet.a \ $(PORT_SYSROOT_LIB)/libz.a diff --git a/test/porttest.c b/test/porttest.c index 5870bd0..59e242a 100644 --- a/test/porttest.c +++ b/test/porttest.c @@ -2,9 +2,23 @@ #include #include #include +#include +#include +#include +#include #include #include #include +/* libcss requires a URL resolver; relative resolution is not what is under + test here, so just duplicate the reference. */ +static css_error pt_resolve_url(void *pw, const char *base, + lwc_string *rel, lwc_string **abs) +{ + (void) pw; (void) base; + *abs = lwc_string_ref(rel); + return CSS_OK; +} + int main(void) { lwc_string *a = NULL, *b = NULL; bool same = false; @@ -55,6 +69,47 @@ int main(void) { printf("zlib %s: gzip roundtrip %lu->%lu %s\n", zlibVersion(), (unsigned long)strlen(s), (unsigned long)clen, gzok ? "PASS" : "FAIL"); + /* libhubbub / libcss / libdom: construct the real objects rather than + just resolving symbols -- a stub-out or a broken static init would + still link but fail here. */ + { + hubbub_parser *hp = NULL; + css_stylesheet *sheet = NULL; + css_stylesheet_params sp; + dom_document *doc = NULL; + dom_exception de; + hubbub_error he; + + he = hubbub_parser_create("UTF-8", false, &hp); + printf("libhubbub: parser_create %s\n", + (he == HUBBUB_OK && hp != NULL) ? "PASS" : "FAIL"); + if (hp != NULL) hubbub_parser_destroy(hp); + + memset(&sp, 0, sizeof(sp)); + sp.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; + sp.level = CSS_LEVEL_21; + sp.charset = "UTF-8"; + sp.url = "http://montaukos.local/"; + sp.resolve = pt_resolve_url; + if (css_stylesheet_create(&sp, &sheet) == CSS_OK && sheet != NULL) { + const char data[] = "body { color: #123456; margin: 4px; }"; + css_error ce = css_stylesheet_append_data(sheet, + (const uint8_t *) data, sizeof(data) - 1); + if (ce == CSS_NEEDDATA) ce = CSS_OK; + if (ce == CSS_OK) ce = css_stylesheet_data_done(sheet); + printf("libcss: parse stylesheet %s\n", ce == CSS_OK ? "PASS" : "FAIL"); + css_stylesheet_destroy(sheet); + } else { + printf("libcss: stylesheet_create FAIL\n"); + } + + de = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML, + NULL, NULL, NULL, NULL, NULL, &doc); + printf("libdom: create_document %s\n", + (de == DOM_NO_ERR && doc != NULL) ? "PASS" : "FAIL"); + if (doc != NULL) dom_node_unref(doc); + } + lwc_string_unref(a); lwc_string_unref(b); parserutils_buffer_destroy(buf); return 0;