~sircmpwn/hare-dev

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
4 3

[PATCH hare v6] Convert build system from Makefile to build.sh

Details
Message ID
<20230517035458.24131-1-autumnull@posteo.net>
DKIM signature
pass
Download raw message
Patch: +322 -6949
- automates the finding of source files and dependencies, so editing
  scripts/gen-stdlib is no longer necessary
- no longer special cases ARCH and PLATFORM tags, so building with
  arbitrary tags is possible
- no longer rebuilds dependent modules if their dependencies' api
  hasn't changed
- corrects installation so that it removes the existing files first
- tags all files in linux:: with +linux

Signed-off-by: Autumn! <autumnull@posteo.net>
---
fixed bug in getsrcs for excluding positive tags
 .builds/alpine.yml                            |    6 +-
 .builds/freebsd.yml                           |    6 +-
 .gitignore                                    |    2 +-
 Makefile                                      |  126 +-
 build.sh                                      |  259 +
 config.example.mk                             |   47 -
 config.example.sh                             |   42 +
 linux/{env.ha => env+linux.ha}                |    0
 linux/keyctl/{keyctl.ha => keyctl+linux.ha}   |    0
 linux/keyctl/{types.ha => types+linux.ha}     |    0
 linux/{start+libc.ha => start+linux+libc.ha}  |    0
 linux/{start.ha => start+linux.ha}            |    0
 .../timerfd/{timerfd.ha => timerfd+linux.ha}  |    0
 linux/vdso/{vdso.ha => vdso+linux.ha}         |    0
 scripts/gen-docs.sh                           |   32 -
 scripts/gen-stdlib                            | 1673 ------
 scripts/gen-stdlib.sh                         |  138 -
 scripts/install-mods                          |   47 -
 scripts/modules                               |   27 -
 stdlib.mk                                     | 4849 -----------------
 targets.mk                                    |   17 -
 21 files changed, 322 insertions(+), 6949 deletions(-)
 create mode 100755 build.sh
 delete mode 100644 config.example.mk
 create mode 100644 config.example.sh
 rename linux/{env.ha => env+linux.ha} (100%)
 rename linux/keyctl/{keyctl.ha => keyctl+linux.ha} (100%)
 rename linux/keyctl/{types.ha => types+linux.ha} (100%)
 rename linux/{start+libc.ha => start+linux+libc.ha} (100%)
 rename linux/{start.ha => start+linux.ha} (100%)
 rename linux/timerfd/{timerfd.ha => timerfd+linux.ha} (100%)
 rename linux/vdso/{vdso.ha => vdso+linux.ha} (100%)
 delete mode 100644 scripts/gen-docs.sh
 delete mode 100755 scripts/gen-stdlib
 delete mode 100644 scripts/gen-stdlib.sh
 delete mode 100755 scripts/install-mods
 delete mode 100755 scripts/modules
 delete mode 100644 stdlib.mk
 delete mode 100644 targets.mk

diff --git a/.builds/alpine.yml b/.builds/alpine.yml
index dc0dd0cb..242f9976 100644
--- a/.builds/alpine.yml
+++ b/.builds/alpine.yml
@@ -29,15 +29,15 @@ tasks:
    sudo make install
- hare: |
    cd hare
    cp config.example.mk config.mk
    cp config.example.sh config.sh
    make
    sudo make install
- tests: |
    cd hare
    make -j2 .bin/hare-tests
    hare test -o .bin/hare-tests
- check: |
    cd hare
    make check
    .bin/hare-tests
- tests_with_libc: |
    cd hare
    hare test -T+libc -lc -o .bin/hare-tests-libc
diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml
index f37d5be9..0b865f68 100644
--- a/.builds/freebsd.yml
+++ b/.builds/freebsd.yml
@@ -19,12 +19,12 @@ tasks:
    sudo make install
- hare: |
    cd hare
    sed -e 's/linux/freebsd/g' < config.example.mk > config.mk
    sed -e 's/linux/freebsd/g' < config.example.sh > config.sh
    make
    sudo make install
- tests: |
    cd hare
    make -j2 .bin/hare-tests
    hare test -o .bin/hare-tests
- check: |
    cd hare
    make check
    .bin/hare-tests
diff --git a/.gitignore b/.gitignore
index 30310524..ac48bcd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
config.mk
config.sh
.cache
.bin
*.1
diff --git a/Makefile b/Makefile
index 728d2d26..39a059b6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,125 +1,27 @@
.POSIX:
.SUFFIXES:
include config.mk
TESTCACHE = $(HARECACHE)/+test
TESTHAREFLAGS = $(HAREFLAGS) -T
STDLIB = .
stdlib_env = env
testlib_env = env

all:
	./build.sh all

.SUFFIXES: .ha .ssa .s .o .scd .1
.ssa.s:
	@printf 'QBE\t%s\n' "$@"
	@$(QBE) -o $@ $<
bins:
	./build.sh bins

.s.o:
	@printf 'AS\t%s\n' "$@"
	@$(AS) -g -o $@ $<
docs/html: bins
	./build.sh html

.scd.1:
	@printf 'SCDOC\t%s\n' "$@"
	@$(SCDOC) < $< > $@

include stdlib.mk

hare_srcs = \
	./cmd/hare/deps.ha \
	./cmd/hare/main.ha \
	./cmd/hare/plan.ha \
	./cmd/hare/progress.ha \
	./cmd/hare/release.ha \
	./cmd/hare/schedule.ha \
	./cmd/hare/subcmds.ha \
	./cmd/hare/target.ha

harec_srcs = \
	./cmd/harec/main.ha \
	./cmd/harec/errors.ha

haredoc_srcs = \
	./cmd/haredoc/main.ha \
	./cmd/haredoc/errors.ha \
	./cmd/haredoc/env.ha \
	./cmd/haredoc/hare.ha \
	./cmd/haredoc/html.ha \
	./cmd/haredoc/sort.ha \
	./cmd/haredoc/resolver.ha

include targets.mk

$(HARECACHE)/hare.ssa: $(hare_srcs) $(stdlib_deps_any) $(stdlib_deps_$(PLATFORM)) scripts/version
	@printf 'HAREC\t%s\n' "$@"
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) \
		$(HARE_DEFINES) -o $@ $(hare_srcs)

$(TESTCACHE)/hare.ssa: $(hare_srcs) $(testlib_deps_any) $(testlib_deps_$(PLATFORM)) scripts/version
	@printf 'HAREC\t%s\n' "$@"
	@$(testlib_env) $(HAREC) $(TESTHAREFLAGS) \
		$(HARE_DEFINES) -o $@ $(hare_srcs)

$(BINOUT)/hare: $(HARECACHE)/hare.o
	@mkdir -p $(BINOUT)
	@printf 'LD\t%s\n' "$@"
	@$(LD) $(LDLINKFLAGS) --gc-sections -T $(rtscript) -o $@ \
		$(HARECACHE)/hare.o $(stdlib_deps_any) $(stdlib_deps_$(PLATFORM))

$(BINOUT)/hare-tests: $(TESTCACHE)/hare.o
	@mkdir -p $(BINOUT)
	@printf 'LD\t%s\n' "$@"
	@$(LD) $(LDLINKFLAGS) -T $(rtscript) -o $@ \
		$(testlib_deps_any) $(testlib_deps_$(PLATFORM))

$(BINOUT)/harec2: $(BINOUT)/hare $(harec_srcs)
	@mkdir -p $(BINOUT)
	@printf 'HARE\t%s\n' "$@"
	@env HAREPATH=. HAREC=$(HAREC) QBE=$(QBE) $(BINOUT)/hare build \
		$(HARE_DEFINES) -o $(BINOUT)/harec2 cmd/harec

# Prevent $(BINOUT)/hare from running builds in parallel, workaround for build
# driver bugs
PARALLEL_HACK=$(BINOUT)/harec2

$(BINOUT)/haredoc: $(BINOUT)/hare $(haredoc_srcs) $(PARALLEL_HACK)
	@mkdir -p $(BINOUT)
	@printf 'HARE\t%s\n' "$@"
	@env HAREPATH=. HAREC=$(HAREC) QBE=$(QBE) $(BINOUT)/hare build \
		$(HARE_DEFINES) -o $(BINOUT)/haredoc ./cmd/haredoc

docs/html: $(BINOUT)/haredoc scripts/gen-docs.sh
	BINOUT=$(BINOUT) $(SHELL) ./scripts/gen-docs.sh

docs/hare.1: docs/hare.scd
docs/haredoc.1: docs/haredoc.scd

docs: docs/hare.1 docs/haredoc.1
docs:
	./build.sh docs

clean:
	rm -rf $(HARECACHE) $(BINOUT) docs/hare.1 docs/haredoc.1 docs/html

check: $(BINOUT)/hare-tests
	@$(BINOUT)/hare-tests

scripts/gen-docs.sh: scripts/gen-stdlib
scripts/gen-stdlib: scripts/gen-stdlib.sh
	./build.sh clean

all: $(BINOUT)/hare $(BINOUT)/harec2 $(BINOUT)/haredoc
check: bins
	./build.sh test

install: docs scripts/install-mods
	mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 \
		$(DESTDIR)$(SRCDIR)/hare/stdlib
	install -m755 $(BINOUT)/hare $(DESTDIR)$(BINDIR)/hare
	install -m755 $(BINOUT)/haredoc $(DESTDIR)$(BINDIR)/haredoc
	install -m644 docs/hare.1 $(DESTDIR)$(MANDIR)/man1/hare.1
	install -m644 docs/haredoc.1 $(DESTDIR)$(MANDIR)/man1/haredoc.1
	./scripts/install-mods "$(DESTDIR)$(SRCDIR)/hare/stdlib"
install: docs bins
	./build.sh install

uninstall:
	$(RM) $(DESTDIR)$(BINDIR)/hare
	$(RM) $(DESTDIR)$(BINDIR)/haredoc
	$(RM) $(DESTDIR)$(MANDIR)/man1/hare.1
	$(RM) $(DESTDIR)$(MANDIR)/man1/haredoc.1
	$(RM) -r $(DESTDIR)$(SRCDIR)/hare/stdlib
	./build.sh uninstall

.PHONY: all clean check docs install uninstall $(BINOUT)/harec2 $(BINOUT)/haredoc
.PHONY: all clean check docs install uninstall
diff --git a/build.sh b/build.sh
new file mode 100755
index 00000000..2b231652
--- /dev/null
@@ -0,0 +1,259 @@
#!/bin/sh -eu
. ./config.sh
export HARECACHE=$CACHE
DESTDIR=${DESTDIR:-}
TESTCACHE="$HARECACHE/+test"
TESTHAREFLAGS="$HAREFLAGS -T"
DEFINES="
	-D PLATFORM:str=\"$PLATFORM\" \
	-D ARCH:str=\"$ARCH\" \
	-D VERSION:str=\"$VERSION\" \
	-D HAREPATH:str=\"$HAREPATH\" \
	-D AARCH64_AR:str=\"$AARCH64_AR\" \
	-D AARCH64_AS:str=\"$AARCH64_AS\" \
	-D AARCH64_CC:str=\"$AARCH64_CC\" \
	-D AARCH64_LD:str=\"$AARCH64_LD\" \
	-D RISCV64_AR:str=\"$RISCV64_AR\" \
	-D RISCV64_AS:str=\"$RISCV64_AS\" \
	-D RISCV64_CC:str=\"$RISCV64_CC\" \
	-D RISCV64_LD:str=\"$RISCV64_LD\" \
	-D X86_64_AR:str=\"$X86_64_AR\" \
	-D X86_64_AS:str=\"$X86_64_AS\" \
	-D X86_64_CC:str=\"$X86_64_CC\" \
	-D X86_64_LD:str=\"$X86_64_LD\" \
	"

statmtime() {
	case $(uname -o) in
	Linux)
		stat -c%Y $@;;
	FreeBSD)
		stat -f%m $@;;
	esac
}

# get the list of source files for a module, given its tags
# usage: getsrcs <path> [tags...]
getsrcs() {
	path=$1
	shift
	tags=$(echo $@ | tr ' ' '|')
	find $path -type f \
	| awk "\$0 ~ \"^$path(/([+-][a-zA-Z0-9_]+)+)*/[^/]+.(ha|s)\$\" \
		&& \$0 !~ \"$path.*-($tags)[^a-zA-Z0-9_]]\"" \
	| while read line
		# the prior awk command filters out non-tag dirs and negative tags
		do
			# this command filters out tags that aren't in our tagset
			if echo $line \
				| sed -E "s/\\+($tags)([^a-zA-Z0-9_])/\\2/g" \
				| grep -qv +
			then
				echo $line
			fi
			# the rest of the command is designed to get the one with
			# the maximum number of tags
		done \
	| awk -F/ '{ print $NF, $0 }' \
	| sed -E 's/^([^.+-]*)[^.]*\.(ha|s) (.+)/\1.\2\n\3/g' \
	| sed s/-/+-/g \
	| awk -F+ ' \
		/\// { \
			if (ntags[current] < NF) { \
				ntags[current] = NF; path[current] = $0 } \
			next }\
		{ current = $0 } \
		END { for (p in path) { print path[p] } }' \
	| sed s/+-/-/g
}

# get the list of dependencies from a list of source files
# usage: getdeps files...
getdeps() {
	cat /dev/null $@ \
	| grep -E '^use' \
	| sed -E 's/^use +([^ ]+ *= *)?(([A-Za-z0-9_]+ *)(:: *[A-Za-z0-9_]+ *)*)(::\{[^}]+\})? *;/\2/g' \
	| sort \
	| uniq \
	| sed 's;::;/;g' \
	| while read line
		# format path/to/module into .cache/path/to/module/path_to_module.td
		do
			printf "$HARECACHE/%s/" $line
			echo $line | sed 's:/:_:g' | awk "{print \$0 \".td\"}"
		done
}

# checks if a set of dependencies are newer than the dependent
# usage: needsrebuild <dependent> [dependencies...]
needsrebuild() {
	parent=$1
	shift
	if ! [ -f $parent ]; then
		return 0
	else
		thisstat=$(statmtime $parent)
		for f in $@; do
			if [ $thisstat -lt $(statmtime $f) ]; then
				return 0
			fi
		done
	fi
	return 1
}

visited=":"
envvars=
objs=

# build a module, given the location of its .td file.
buildtd() {
	# only build each module once
	case $visited in
	*:$1:*)
		return;;
	esac
	visited=":$1$visited"

	mod=$(dirname $1 | sed "s;$HARECACHE/;;")
	mkdir -p $HARECACHE/$mod
	srcsfile=$HARECACHE/$mod/srcs.txt
	srcs=$(getsrcs $mod $TAGS | tee $srcsfile)
	depsfile=$HARECACHE/$mod/deps.txt
	if needsrebuild $depsfile $srcs; then
		deps=$(getdeps $srcs | tee $depsfile)
	else
		deps=$(cat $depsfile)
	fi
	
	for d in $deps; do
		buildtd $d
	done
	# sadly some vars need re-calculating - they get overwritten by recursion
	mod=$(dirname $1 | sed "s;$HARECACHE/;;")
	srcsfile=$HARECACHE/$mod/srcs.txt
	srcs=$(cat $srcsfile)
	haresrcs=$(echo $srcs | tr ' ' "\n" | grep -E "\.ha$")
	asmsrcs=$(echo $srcs | tr ' ' "\n" | grep -E "\.s$" || true)
	ssa="$HARECACHE/$mod/build.ssa"
	asm="$HARECACHE/$mod/build.s"
	obj="$HARECACHE/$mod/build.o"
	td="$HARECACHE/$mod/buildtd"
	namespace=$(echo $mod | sed 's:\./::' | sed 's;/;::;g')
	ns="-N$namespace"
	envvars="$envvars HARE_TD_$namespace=$1"

	case $mod in
	cmd/*)
		ns= # unset namespace for main
		DEFS=$DEFINES ;;
	*)
		objs="$objs $obj"
		DEFS= ;; # unset defines for non-cmd modules
	esac

	if ! needsrebuild $obj $deps $srcs; then
		return
	fi

	printf " HAREC\t$ssa\n"
	env $envvars $HAREC $HAREFLAGS $DEFS -t$td $ns $haresrcs > $ssa
	printf " QBE\t$asm\n"
	$QBE $ssa > $asm
	printf " AS\t$obj\n"
	$AS -o $obj $asm $asmsrcs
	if ! [ -f $1 ] || ! diff $1 $td > /dev/null; then
		mv $td $1
	fi
}

moddirs=$(
	find . -type d -maxdepth 1 \
	| cut -d/ -f2 \
	| sed -E '/^(\..*|scripts|cmd|docs|contrib)$/d'
)

args=$@
if [ $# -eq 0 ]; then
	args="all"
fi
args=$(echo " $args " | sed 's/ all / bins docs /')
for arg in $args; do
	case $arg in
	bins)
		mkdir -p $BINOUT
		mkdir -p $HARECACHE
		for bin in hare harec haredoc; do
			cmdtd=$HARECACHE/cmd/$bin/cmd_$bin.td
			buildtd $cmdtd
		done
		for bin in hare harec haredoc; do
			obj=$HARECACHE/cmd/$bin/build.o

			if needsrebuild $BINOUT/$bin $objs $obj; then
				printf "LD\t$BINOUT/$bin\n"
				$LD --gc-sections -T rt/hare.sc -o $BINOUT/$bin $objs $obj
			fi
		done
		;;
	clean)
		printf "RM\t$HARECACHE $BINOUT docs/hare.1 docs/haredoc.1 docs/html\n"
		rm -rf $HARECACHE $BINOUT docs/hare.1 docs/haredoc.1 docs/html
		;;
	docs)
		for doc in docs/hare docs/haredoc; do
			if needsrebuild $doc.1 $doc.scd; then
				printf "SCDOC\t$doc.1\n"
				$SCDOC < $doc.scd > $doc.1
			fi
		done
		;;
	html)
		mkdir -p docs/html
		for d in $moddirs; do
			find $d -type d | sed -E '/(\+|-)/d'
		done \
		| while read path
		do
			mod=$(echo $path | sed -E 's;/;::;g')
			echo $mod
			mkdir -p docs/html/$path
			"$BINOUT"/haredoc -Fhtml $mod > docs/html/$path/index.html
		done
		;;
	install)
		mkdir -p $DESTDIR$BINDIR $DESTDIR$MANDIR/man1 \
			$DESTDIR$SRCDIR/hare/stdlib
		printf "INSTALL\t$DESTDIR$BINDIR/hare\n"
		install -m755 $BINOUT/hare $DESTDIR$BINDIR/hare
		printf "INSTALL\t$DESTDIR$BINDIR/haredoc\n"
		install -m755 $BINOUT/haredoc $DESTDIR$BINDIR/haredoc
		printf "INSTALL\t$DESTDIR$MANDIR/man1/hare.1\n"
		install -m644 docs/hare.1 $DESTDIR$MANDIR/man1/hare.1
		printf "INSTALL\t$DESTDIR$MANDIR/man1/haredoc.1\n"
		install -m644 docs/haredoc.1 $DESTDIR$MANDIR/man1/haredoc.1
		rm -rf "$DESTDIR$STDLIB"
		mkdir -p $DESTDIR$STDLIB
		printf "CP\t$DESTDIR$STDLIB\n"
		cp -R $moddirs "$DESTDIR$STDLIB"
		;;
	uninstall)
		printf "RM\t$DESTDIR$BINDIR/hare\n"
		rm -f $DESTDIR$BINDIR/hare
		printf "RM\t$DESTDIR$BINDIR/haredoc\n"
		rm -f $DESTDIR$BINDIR/haredoc
		printf "RM\t$DESTDIR$MANDIR/man1/hare.1\n"
		rm -f $DESTDIR$MANDIR/man1/hare.1
		printf "RM\t$DESTDIR$MANDIR/man1/haredoc.1\n"
		rm -f $DESTDIR$MANDIR/man1/haredoc.1
		printf "RM\t$DESTDIR$STDLIB\n"
		rm -rf $DESTDIR$STDLIB
		;;
	test)
		$BINOUT/hare test;;
	*)
		printf \
		"Usage: $0 [(all|bins|clean|docs|html|install|uninstall|test)...]\n"
		exit 1
	esac
done
diff --git a/config.example.mk b/config.example.mk
deleted file mode 100644
index 75ef9a88..00000000
--- a/config.example.mk
@@ -1,47 +0,0 @@
## Install configuration

PREFIX = /usr/local
BINDIR = $(PREFIX)/bin
MANDIR = $(PREFIX)/share/man
SRCDIR = $(PREFIX)/src

# Where to install the stdlib tree
STDLIB = $(SRCDIR)/hare/stdlib

# Default HAREPATH
HAREPATH = $(SRCDIR)/hare/stdlib:$(SRCDIR)/hare/third-party

## Build configuration

# Platform to build for
PLATFORM = linux
ARCH = x86_64

# External tools and flags
HAREC = harec
HAREFLAGS =
QBE = qbe
AS = as
LD = ld
AR = ar
SCDOC = scdoc

# Where to store build artifacts
HARECACHE = .cache
BINOUT = .bin

# Cross-compiler toolchains
AARCH64_AS=aarch64-as
AARCH64_AR=aarch64-ar
AARCH64_CC=aarch64-cc
AARCH64_LD=aarch64-ld

RISCV64_AS=riscv64-as
RISCV64_AR=riscv64-ar
RISCV64_CC=riscv64-cc
RISCV64_LD=riscv64-ld

X86_64_AS=as
X86_64_AR=ar
X86_64_CC=cc
X86_64_LD=ld
diff --git a/config.example.sh b/config.example.sh
new file mode 100644
index 00000000..cc3dd5d6
--- /dev/null
+++ b/config.example.sh
@@ -0,0 +1,42 @@
# this file will be source'd by the build script.

# variables used to configure the build
ARCH=${ARCH:-x86_64}
PLATFORM=${PLATFORM:-linux}
TAGS="$ARCH $PLATFORM"
HAREFLAGS=

# commands used by the build script
AR=ar
AS=as
HAREC=harec
LD=ld
QBE=qbe
SCDOC=scdoc

# build locations
CACHE=.cache
BINOUT=.bin

# install locations
PREFIX=${PREFIX:-/usr/local}
BINDIR="$PREFIX/bin"
MANDIR="$PREFIX/share/man"
SRCDIR="$PREFIX/src"
STDLIB="$SRCDIR/hare/stdlib"

# variables that will be embedded in the binary with -D definitions
HAREPATH="$SRCDIR/hare/stdlib:$SRCDIR/hare/third-party"
VERSION=$(./scripts/version)
AARCH64_AR=aarch64-ar
AARCH64_AS=aarch64-as
AARCH64_CC=aarch64-cc
AARCH64_LD=aarch64-ld
RISCV64_AR=riscv64-ar
RISCV64_AS=riscv64-as
RISCV64_CC=riscv64-cc
RISCV64_LD=riscv64-ld
X86_64_AR=ar
X86_64_AS=as
X86_64_CC=cc
X86_64_LD=ld
diff --git a/linux/env.ha b/linux/env+linux.ha
similarity index 100%
rename from linux/env.ha
rename to linux/env+linux.ha
diff --git a/linux/keyctl/keyctl.ha b/linux/keyctl/keyctl+linux.ha
similarity index 100%
rename from linux/keyctl/keyctl.ha
rename to linux/keyctl/keyctl+linux.ha
diff --git a/linux/keyctl/types.ha b/linux/keyctl/types+linux.ha
similarity index 100%
rename from linux/keyctl/types.ha
rename to linux/keyctl/types+linux.ha
diff --git a/linux/start+libc.ha b/linux/start+linux+libc.ha
similarity index 100%
rename from linux/start+libc.ha
rename to linux/start+linux+libc.ha
diff --git a/linux/start.ha b/linux/start+linux.ha
similarity index 100%
rename from linux/start.ha
rename to linux/start+linux.ha
diff --git a/linux/timerfd/timerfd.ha b/linux/timerfd/timerfd+linux.ha
similarity index 100%
rename from linux/timerfd/timerfd.ha
rename to linux/timerfd/timerfd+linux.ha
diff --git a/linux/vdso/vdso.ha b/linux/vdso/vdso+linux.ha
similarity index 100%
rename from linux/vdso/vdso.ha
rename to linux/vdso/vdso+linux.ha
diff --git a/scripts/gen-docs.sh b/scripts/gen-docs.sh
deleted file mode 100644
index e12a1fcf..00000000
--- a/scripts/gen-docs.sh
@@ -1,32 +0,0 @@
# Yes, I am entirely aware that this is a hack
srcdir="$(dirname "$0")"
getmods() (
	DOCS=1
	. "$srcdir"/gen-stdlib
	IFS="
"
	for module in $modules; do
		if [ -z "$(echo "$module" | cut -sf1)" ]
		then
			echo "$module"
		else
			module="$(echo "$module" | cut -sf1)"
			echo $module
		fi
	done
	# Not listed in the stdlib for various reasons:
	echo crypto::keystore
	echo mime
)
modules="$(getmods)"

mkdir -p docs/html/

"$BINOUT"/haredoc -Fhtml > docs/html/index.html
for mod in $modules format encoding math crypto hare rt
do
	echo $mod
	path="$(echo $mod | sed -e 's?::?/?g')"
	mkdir -p docs/html/$path
	"$BINOUT"/haredoc -Fhtml $mod > docs/html/$path/index.html
done
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
deleted file mode 100755
index a272faa3..00000000
--- a/scripts/gen-stdlib
@@ -1,1673 +0,0 @@
#!/bin/sh
# The purpose of this script is to generate make targets for the Hare standard
# library. If you are adding new modules to the standard library, write a
# function for that module (e.g. encoding_utf8), and call the following helper
# commands:
#
# gen_srcs module::name list.ha of.ha sources.ha
# gen_ssa module::name list of module::names yours depends on
#
# Then add your module to the list of modules at the bottom.
#
# Then run ./scripts/gen-stdlib > stdlib.mk to generate new rules.

srcdir="$(dirname "$0")"
eval ". $srcdir/gen-stdlib.sh"

all_platforms="linux
freebsd"

gensrcs_rt() {
	gen_srcs -plinux rt \
		+linux/platform_abort.ha \
		+linux/env.ha \
		+linux/errno.ha \
		+linux/types.ha \
		+linux/segmalloc.ha \
		+linux/platformstart.ha \
		+linux/prctl.ha \
		+linux/'+$(ARCH)'.ha \
		+linux/syscallno+'$(ARCH)'.ha \
		+linux/syscalls.ha \
		+linux/syscallsarch+'$(ARCH)'.ha \
		+linux/signal.ha \
		+linux/stat.ha \
		+linux/socket.ha \
		'+$(ARCH)'/jmp.ha \
		'+$(ARCH)'/backtrace.ha \
		fenv_defs.ha \
		'+$(ARCH)'/cpuid.ha \
		ensure.ha \
		jmp.ha \
		malloc.ha \
		memcpy.ha \
		memmove.ha \
		memset.ha \
		strcmp.ha \
		$*
	gen_srcs -pfreebsd rt \
		+freebsd/platform_abort.ha \
		+freebsd/env.ha \
		+freebsd/errno.ha \
		+freebsd/platformstart.ha \
		+freebsd/segmalloc.ha \
		+freebsd/signal.ha \
		+freebsd/socket.ha \
		+freebsd/'+$(ARCH)'.ha \
		+freebsd/syscallno.ha \
		+freebsd/syscalls.ha \
		+freebsd/types.ha \
		+'$(ARCH)'/jmp.ha \
		+'$(ARCH)'/backtrace.ha \
		fenv_defs.ha \
		+'$(ARCH)'/cpuid.ha \
		ensure.ha \
		jmp.ha \
		malloc.ha \
		memcpy.ha \
		memmove.ha \
		memset.ha \
		strcmp.ha \
		$*
}

rt() {
	# This one is complicated, don't use it as a reference for other modules
	if [ $testing -eq 0 ]
	then
		printf '%s\n' 'rtscript = $(STDLIB)/rt/hare.sc'
		gensrcs_rt \
			abort.ha \
			start.ha
	else
		gensrcs_rt \
			abort+test.ha \
			start+test.ha \
			+test/signal.ha \
			+test/ztos.ha
	fi
	gen_ssa -plinux rt
	gen_ssa -pfreebsd rt
	cat <<EOF
\$($cache)/rt/start.o: \$(STDLIB)/rt/+\$(PLATFORM)/start+\$(ARCH)-libc.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(PLATFORM)/start+\$(ARCH)-libc.s

${stdlib}_asm = \$($cache)/rt/syscall.o \\
	\$($cache)/rt/setjmp.o \\
	\$($cache)/rt/longjmp.o \\
	\$($cache)/rt/restore.o \\
	\$($cache)/rt/getfp.o \\
	\$($cache)/rt/fenv.o \\
	\$($cache)/rt/start.o \\
	\$($cache)/rt/cpuid_native.o

\$($cache)/rt/syscall.o: \$(STDLIB)/rt/+\$(PLATFORM)/syscall+\$(ARCH).s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(PLATFORM)/syscall+\$(ARCH).s

\$($cache)/rt/setjmp.o: \$(STDLIB)/rt/+\$(ARCH)/setjmp.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/setjmp.s

\$($cache)/rt/longjmp.o: \$(STDLIB)/rt/+\$(ARCH)/longjmp.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/longjmp.s

\$($cache)/rt/restore.o: \$(STDLIB)/rt/+\$(ARCH)/restore.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/restore.s

\$($cache)/rt/fenv.o: \$(STDLIB)/rt/+\$(ARCH)/fenv.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/fenv.s

\$($cache)/rt/getfp.o: \$(STDLIB)/rt/+\$(ARCH)/getfp.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/getfp.s

\$($cache)/rt/cpuid_native.o: \$(STDLIB)/rt/+\$(ARCH)/cpuid_native.s
	@printf 'AS \t%s\n' "\$@"
	@mkdir -p \$($cache)/rt
	@\$(AS) -o \$@ \$(STDLIB)/rt/+\$(ARCH)/cpuid_native.s

\$($cache)/rt/rt-linux.a: \$($cache)/rt/rt-linux.o \$(${stdlib}_asm)
	@printf 'AR \t%s\n' "\$@"
	@\$(AR) -csr \$@ \$($cache)/rt/rt-linux.o \$(${stdlib}_asm)

\$($cache)/rt/rt-freebsd.a: \$($cache)/rt/rt-freebsd.o \$(${stdlib}_asm)
	@printf 'AR \t%s\n' "\$@"
	@\$(AR) -csr \$@ \$($cache)/rt/rt-freebsd.o \$(${stdlib}_asm)

${stdlib}_rt = \$($cache)/rt/rt-\$(PLATFORM).a
${stdlib}_env += HARE_TD_rt=\$($cache)/rt/rt.td
${stdlib}_deps_linux += \$(${stdlib}_rt)
${stdlib}_deps_freebsd += \$(${stdlib}_rt)
${stdlib}_deps_any += \$(${stdlib}_rt)

EOF
}

test() {
	if [ $testing -eq 0 ]; then
		gen_srcs test common.ha
		gen_ssa test
	else
		gen_srcs test common.ha +test.ha fail+test.ha
		gen_ssa test bufio encoding::hex encoding::utf8 fmt fnmatch io \
			os rt strings strio time unix::signal
	fi
}

ascii() {
	gen_srcs ascii \
		ctype.ha \
		string.ha \
		valid.ha
	gen_ssa ascii strings
}

bufio() {
	gen_srcs bufio \
		buffered.ha \
		memstream.ha \
		scanner.ha
	gen_ssa bufio io bytes strings encoding::utf8 errors types
}

bytes() {
	gen_srcs bytes \
		contains.ha \
		equal.ha \
		index.ha \
		reverse.ha \
		tokenize.ha \
		trim.ha \
		two_way.ha \
		zero.ha
	gen_ssa bytes types
}

datetime() {
	gen_srcs -plinux datetime \
		arithmetic.ha \
		chronology.ha \
		errors.ha \
		date.ha \
		datetime.ha \
		duration.ha \
		format.ha \
		parse.ha \
		period.ha \
		reckon.ha \
		time.ha \
		timezone.ha \
		virtual.ha
	gen_ssa -plinux datetime ascii errors fmt io strconv strings strio \
		time time::chrono
	gen_srcs -pfreebsd datetime \
		arithmetic.ha \
		chronology.ha \
		errors.ha \
		date.ha \
		datetime.ha \
		duration.ha \
		format.ha \
		parse.ha \
		period.ha \
		reckon.ha \
		time.ha \
		timezone.ha \
		virtual.ha
	gen_ssa -pfreebsd datetime ascii errors fmt io strconv strings strio \
		time time::chrono
}

crypto() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto \
			authenc.ha \
			keyderiv.ha
		gen_ssa crypto bufio bytes crypto::argon2 crypto::chacha \
			crypto::cihper crypto::poly1305 crypto::mac \
			crypto::math endian errors io
	else
		gen_srcs crypto \
			authenc.ha \
			keyderiv.ha \
			+test/authenc.ha
		gen_ssa crypto bytes bufio crypto::argon2 crypto::chacha \
			crypto::cihper crypto::poly1305 crypto::mac \
			crypto::math endian errors io
	fi
}

gensrcs_crypto_aes() {
	gen_srcs crypto::aes \
		aes.ha \
		aes_ct64.ha \
		block.ha \
		$*
}

crypto_aes() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_aes
		gen_ssa crypto::aes bytes crypto::cipher crypto::math endian \
			rt io
	else
		gensrcs_crypto_aes \
			ct64+test.ha \
			cbc+test.ha \
			ctr+test.ha \
			rt+test.ha \
			+test/gcm.ha
		gen_ssa crypto::aes bufio bytes crypto::cipher crypto::math \
			endian errors io rt 
	fi
}

crypto_aes_xts() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::aes::xts xts.ha
	else
		gen_srcs crypto::aes::xts xts.ha +test.ha
	fi
	gen_ssa crypto::aes::xts crypto::aes crypto::cipher bytes
}

crypto_argon2() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::argon2 argon2.ha
		gen_ssa crypto::argon2 bufio bytes crypto::blake2b \
			crypto::math endian errors hash io rt types
	else
		gen_srcs crypto::argon2 argon2.ha +test.ha
		gen_ssa crypto::argon2 bufio bytes crypto::blake2b \
			crypto::math encoding::hex endian errors hash io rt \
			strings types
	fi
}

crypto_bcrypt() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::bcrypt bcrypt.ha base64.ha
	else
		gen_srcs crypto::bcrypt bcrypt.ha base64.ha +test.ha
	fi
	gen_ssa crypto::bcrypt crypto::blowfish encoding::base64 bufio io \
		crypto crypto::random errors crypto::cipher strings fmt bytes \
		strconv
}

gensrcs_crypto_blake2b() {
	gen_srcs crypto::blake2b \
		blake2b.ha \
		$*
}

crypto_blake2b() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_blake2b
		gen_ssa crypto::blake2b bytes crypto::math endian hash io
	else
		gensrcs_crypto_blake2b +test.ha vectors+test.ha
		gen_ssa crypto::blake2b encoding::hex fmt hash io strings \
			strio crypto::math endian bytes
	fi
}

gensrcs_crypto_blowfish() {
	gen_srcs crypto::blowfish \
		blowfish.ha \
		const.ha \
		$*
}

crypto_blowfish() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_blowfish
	else
		gensrcs_crypto_blowfish +test.ha
	fi
	gen_ssa crypto::blowfish bytes crypto::cipher endian
}

gensrcs_crypto_bigint() {
		gen_srcs crypto::bigint arithm.ha encoding.ha monty.ha types.ha \
            util.ha $*
}

crypto_bigint() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_bigint
        gen_ssa crypto::bigint bytes crypto::math
	else
		gensrcs_crypto_bigint +test/arithm.ha +test/encoding.ha \
            +test/monty.ha +test/utils.ha
        gen_ssa crypto::bigint bytes crypto::math encoding::hex
	fi
}

crypto_chacha() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::chacha chacha20.ha
		gen_ssa crypto::chacha bytes crypto::cipher crypto::math \
			endian io
	else
		gen_srcs crypto::chacha chacha20.ha +test.ha
		gen_ssa crypto::chacha bytes crypto::cipher crypto::math \
			endian io bufio
	fi
}

crypto_cipher() {
	gen_srcs crypto::cipher \
		cipher.ha \
		block.ha \
		cbc.ha \
		ctr.ha \
		stream.ha \
		gcm.ha \
		ghash.ha
	gen_ssa crypto::cipher crypto::math bytes endian errors io types
}

crypto_hkdf() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::hkdf hkdf.ha
		gen_ssa crypto::hkdf bytes crypto::hmac crypto::mac hash
	else
		gen_srcs crypto::hkdf hkdf.ha +test.ha
		gen_ssa crypto::hkdf bytes crypto::hmac crypto::mac hash \
			crypto::sha1 crypto::sha256
	fi
}

crypto_hmac() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::hmac \
			hmac.ha \
			sha1.ha \
			sha256.ha
		gen_ssa crypto::hmac crypto::mac crypto::sha1 crypto::sha256 hash io bytes
	else
		gen_srcs crypto::hmac \
			hmac.ha \
			sha1.ha \
			sha256.ha \
			+test.ha
		gen_ssa crypto::hmac bytes crypto::mac hash crypto::sha1 \
			crypto::sha256 encoding::hex io strings
	fi
}

crypto_mac() {
	gen_srcs crypto::mac \
		mac.ha
	gen_ssa crypto::mac io
}

crypto_math() {
	gen_srcs crypto::math \
		arithm.ha bits.ha
	gen_ssa crypto::math
}

crypto_poly1305() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::poly1305 \
			poly1305.ha
		gen_ssa crypto::poly1305 bytes crypto::mac endian io
	else
		gen_srcs crypto::poly1305 \
			poly1305.ha \
			+test.ha
		gen_ssa crypto::poly1305 bytes crypto::mac endian encoding::hex io
	fi
}

crypto_random() {
	gen_srcs -plinux crypto::random \
		+linux.ha \
		random.ha
	gen_ssa -plinux crypto::random rt io errors

	gen_srcs -pfreebsd crypto::random \
		+freebsd.ha \
		random.ha
	gen_ssa -pfreebsd crypto::random rt io errors
}

gensrcs_crypto_rsa() {
	gen_srcs crypto::rsa core.ha  errors.ha  keys.ha  pkcs1.ha $*
}

genssa_crypto_rsa() {
	gen_ssa crypto::rsa bufio bytes crypto::bigint crypto::math \
		crypto::sha1 crypto::sha256 crypto::sha512 endian errors hash \
		io types $*
}

crypto_rsa() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_rsa
		genssa_crypto_rsa
	else
		gensrcs_crypto_rsa +test/core.ha +test/keys.ha +test/pkcs1.ha
		genssa_crypto_rsa
	fi
}

crypto_salsa() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::salsa salsa20.ha
		gen_ssa crypto::salsa bytes crypto::cipher crypto::math endian \
			io
	else
		gen_srcs crypto::salsa salsa20.ha +test.ha
		gen_ssa crypto::salsa bytes bufio crypto::cipher crypto::math \
			endian types io
	fi
}

gensrcs_crypto_sha256() {
	gen_srcs crypto::sha256 \
		sha256.ha \
		$*
}

genssa_crypto_sha256() {
	gen_ssa crypto::sha256 crypto::math bytes hash io endian $*
}

crypto_sha256() {
	if [ $testing -eq 0 ]
	then
		gensrcs_crypto_sha256
		genssa_crypto_sha256
	else
		gensrcs_crypto_sha256 \
			+test.ha
		genssa_crypto_sha256 fmt strings encoding::hex
	fi
}

crypto_sha1() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::sha1 sha1.ha
		gen_ssa crypto::sha1 crypto::math bytes hash io endian
	else
		gen_srcs crypto::sha1 sha1.ha +test.ha
		gen_ssa crypto::sha1 crypto::math bytes hash endian fmt strings encoding::hex
	fi
}

crypto_sha512() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::sha512 sha512.ha
		gen_ssa crypto::sha512 crypto::math bytes hash io endian
	else
		gen_srcs crypto::sha512 sha512.ha +test.ha
		gen_ssa crypto::sha512 crypto::math bytes hash endian fmt strings encoding::hex
	fi
}

crypto_curve25519() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::curve25519 curve25519.ha
		gen_ssa crypto::curve25519 bytes
	else
		gen_srcs crypto::curve25519 curve25519.ha +test.ha
		gen_ssa crypto::curve25519 bytes fmt io encoding::hex crypto::random
	fi
}

crypto_ed25519() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::ed25519 ed25519.ha edwards25519.ha
		gen_ssa crypto::ed25519 bytes crypto::sha512 hash
	else
		gen_srcs crypto::ed25519 ed25519.ha edwards25519.ha +test.ha
		gen_ssa crypto::ed25519 bytes crypto::sha512 hash encoding::hex strings
	fi
}

crypto_x25519() {
	if [ $testing -eq 0 ]
	then
		gen_srcs crypto::x25519 x25519.ha
		gen_ssa crypto::x25519 crypto::curve25519
	else
		gen_srcs crypto::x25519 x25519.ha +test.ha
		gen_ssa crypto::x25519 bytes crypto::curve25519 encoding::hex \
			crypto::random
	fi
}

dirs() {
	gen_srcs dirs \
		xdg.ha
	gen_ssa dirs errors fs io os path fmt unix
}

encoding_base64() {
	gen_srcs encoding::base64 \
		base64.ha
	gen_ssa encoding::base64 ascii bufio bytes errors io os strings
}

encoding_base32() {
	gen_srcs encoding::base32 \
		base32.ha
	gen_ssa encoding::base32 ascii bufio bytes errors io strings os
}

encoding_hex() {
	gen_srcs encoding::hex \
		hex.ha
	gen_ssa encoding::hex ascii bufio bytes errors fmt io strconv strio \
		strings
}

encoding_pem() {
	if [ $testing -eq 0 ]
	then
		gen_srcs encoding::pem \
			pem.ha
		gen_ssa encoding::pem strings bufio strio io errors \
			encoding::base64 ascii os fmt
	else
		gen_srcs encoding::pem \
			pem.ha \
			+test.ha
		gen_ssa encoding::pem strings bufio strio io errors \
			encoding::base64 ascii os fmt bytes
	fi
}

encoding_utf8() {
	gen_srcs encoding::utf8 \
		decode.ha \
		decodetable.ha \
		encode.ha \
		rune.ha
	gen_ssa encoding::utf8 types
}

endian() {
	gen_srcs endian \
		big.ha \
		network.ha \
		little.ha \
		endian.ha \
		'host+$(ARCH).ha'
	gen_ssa endian
}

errors() {
	gen_srcs errors \
		common.ha \
		opaque.ha \
		string.ha \
		rt.ha
	gen_ssa errors rt
}

fmt() {
	gen_srcs fmt \
		fmt.ha
	gen_ssa fmt ascii bufio encoding::utf8 io os strconv strings types
}

fnmatch() {
	if [ $testing -eq 0 ]
	then
		gen_srcs fnmatch fnmatch.ha
	else
		gen_srcs fnmatch fnmatch.ha +test.ha
	fi
	gen_ssa fnmatch ascii errors strings sort
}

format_elf() {
	gen_srcs format::elf \
		'arch+$(ARCH).ha' \
		'platform+$(PLATFORM).ha' \
		types.ha
	gen_ssa format::elf
}

gensrcs_format_ini() {
	gen_srcs format::ini \
		scan.ha \
		types.ha \
		$*
}

format_ini() {
	if [ $testing -eq 0 ]
	then
		gensrcs_format_ini
	else
		gensrcs_format_ini +test.ha
	fi
	gen_ssa format::ini bufio encoding::utf8 fmt io strings
}

format_tar() {
	gen_srcs format::tar \
		types.ha \
		reader.ha
	gen_ssa format::tar bufio bytes endian errors io strconv strio types::c
}

fs() {
	gen_srcs fs \
		types.ha \
		fs.ha \
		util.ha
	gen_ssa fs io strings path time errors
}

getopt() {
	gen_srcs getopt \
		getopts.ha
	gen_ssa getopt encoding::utf8 fmt io os strings
}

glob() {
	if [ $testing -eq 0 ]
	then
		gen_srcs glob glob.ha
	else
		gen_srcs glob glob.ha +test.ha
	fi
	gen_ssa glob fnmatch fs io os sort strings strio
}

hare_ast() {
	gen_srcs hare::ast \
		decl.ha \
		expr.ha \
		ident.ha \
		import.ha \
		type.ha \
		unit.ha
	gen_ssa hare::ast hare::lex strings
}

gensrcs_hare_types() {
	gen_srcs hare::types \
		'+$(ARCH)/writesize.ha' \
		arch.ha \
		builtins.ha \
		class.ha \
		hash.ha \
		lookup.ha \
		store.ha \
		types.ha \
		$*
}

hare_types() {
	if [ $testing -eq 1 ]
	then
		gensrcs_hare_types +test.ha
		gen_ssa hare::types hare::ast hash hash::fnv endian strings \
			errors sort fmt bufio hare::lex hare::parse io
	else
		gensrcs_hare_types
		gen_ssa hare::types hare::ast hash hash::fnv endian strings \
			errors sort fmt
	fi
}

gensrcs_hare_unit() {
	gen_srcs hare::unit \
		check.ha \
		context.ha \
		errors.ha \
		expr.ha \
		process.ha \
		scan.ha \
		scope.ha \
		unit.ha \
		$*
}

hare_unit() {
	if [ $testing -eq 1 ]
	then
		gensrcs_hare_unit +test.ha
		gen_ssa hare::unit hare::ast hare::types hash hash::fnv \
			strings hare::lex bufio hare::parse
	else
		gensrcs_hare_unit
		gen_ssa hare::unit hare::ast hare::types hash hash::fnv \
			strings hare::lex
	fi
}

hare_unparse() {
	gen_srcs hare::unparse \
		expr.ha \
		decl.ha \
		ident.ha \
		import.ha \
		type.ha \
		unit.ha \
		util.ha
	gen_ssa hare::unparse fmt io strings strio hare::ast hare::lex
}

gensrcs_hare_lex() {
	gen_srcs hare::lex \
		token.ha \
		lex.ha \
		$*
}

hare_lex() {
	if [ $testing -eq 0 ]
	then
		gensrcs_hare_lex
	else
		gensrcs_hare_lex \
			+test.ha
	fi
	gen_ssa hare::lex ascii io bufio encoding::utf8 strings fmt sort strio \
		strconv path
}

hare_module() {
	gen_srcs hare::module \
		types.ha \
		context.ha \
		scan.ha \
		manifest.ha \
		walk.ha
	gen_ssa hare::module \
		hare::ast hare::lex hare::parse hare::unparse strio fs io strings hash \
		crypto::sha256 dirs bytes encoding::utf8 ascii fmt time bufio \
		strconv os encoding::hex sort errors temp path
}

gensrcs_hare_parse() {
	gen_srcs hare::parse \
		decl.ha \
		expr.ha \
		ident.ha \
		import.ha \
		parse.ha \
		type.ha \
		unit.ha \
		$*
}

hare_parse() {
	if [ $testing -eq 0 ]
	then
		gensrcs_hare_parse
		gen_ssa hare::parse ascii hare::ast hare::lex fmt types \
			strings math
	else
		gensrcs_hare_parse \
			+test/expr.ha \
			+test/ident.ha \
			+test/loc.ha \
			+test/roundtrip.ha \
			+test/types.ha \
			+test/unit.ha
		gen_ssa hare::parse ascii bufio hare::ast hare::lex \
			hare::unparse io strio fmt types strings math \
			encoding::utf8
	fi
}

hash() {
	gen_srcs hash \
		hash.ha
	gen_ssa hash crypto::math io fmt
}

hash_adler32() {
	gen_srcs hash::adler32 \
		adler32.ha
	gen_ssa hash::adler32 endian hash io strings
}

hash_crc16() {
	gen_srcs hash::crc16 \
		crc16.ha
	gen_ssa hash::crc16 endian hash io strings
}

hash_crc32() {
	gen_srcs hash::crc32 \
		crc32.ha
	gen_ssa hash::crc32 endian hash io strings
}

hash_crc64() {
	gen_srcs hash::crc64 \
		crc64.ha
	gen_ssa hash::crc64 endian hash io strings
}

hash_fnv() {
	gen_srcs hash::fnv \
		'+$(ARCH).ha' \
		fnv.ha
	gen_ssa hash::fnv endian hash io strings
}

hash_siphash() {
	if [ $testing -eq 0 ]
	then
		gen_srcs hash::siphash siphash.ha
		gen_ssa hash::siphash hash io endian crypto::math
	else
		gen_srcs hash::siphash siphash.ha +test.ha
		gen_ssa hash::siphash hash io endian crypto::math \
			fmt strio strings
	fi
}

gensrcs_io() {
	gen_srcs -plinux io \
		'arch+$(ARCH).ha' \
		+linux/file.ha \
		+linux/mmap.ha \
		+linux/platform_lock.ha \
		+linux/platform_trunc.ha \
		+linux/vector.ha \
		copy.ha \
		drain.ha \
		empty.ha \
		handle.ha \
		limit.ha \
		lock.ha \
		stream.ha \
		tee.ha \
		trunc.ha \
		types.ha \
		util.ha \
		zero.ha \
		$*
	gen_srcs -pfreebsd io \
		'arch+$(ARCH).ha' \
		+freebsd/file.ha \
		+freebsd/mmap.ha \
		+freebsd/platform_lock.ha \
		+freebsd/platform_trunc.ha \
		+freebsd/vector.ha \
		copy.ha \
		drain.ha \
		empty.ha \
		handle.ha \
		limit.ha \
		lock.ha \
		stream.ha \
		tee.ha \
		trunc.ha \
		types.ha \
		util.ha \
		zero.ha \
		$*
}

io() {
	if [ $testing -eq 0 ]
	then
		gensrcs_io
	else
		gensrcs_io \
			+test/limit.ha \
			+test/stream.ha
	fi
	gen_ssa -plinux io strings errors bytes rt
	gen_ssa -pfreebsd io strings errors bytes rt
}

linux() {
	gen_srcs -plinux linux \
		start.ha \
		env.ha
	gen_ssa -plinux linux format::elf rt
}

linux_keyctl() {
	gen_srcs -plinux linux::keyctl \
		keyctl.ha \
		types.ha
	gen_ssa -plinux linux::keyctl rt errors bytes types::c
}

linux_timerfd() {
	gen_srcs -plinux linux::timerfd \
		timerfd.ha
	gen_ssa -plinux linux::timerfd errors rt time io endian
}

linux_vdso() {
	gen_srcs -plinux linux::vdso \
		vdso.ha
	gen_ssa -plinux linux::vdso linux format::elf types::c
}

log() {
	gen_srcs -plinux log logger.ha global.ha funcs.ha silent.ha
	gen_ssa -plinux log datetime fmt io os
	gen_srcs -pfreebsd log logger.ha global.ha funcs.ha silent.ha
	gen_ssa -pfreebsd log datetime fmt io os
}

gensrcs_math() {
	gen_srcs math \
		math.ha \
		fenv_func.ha \
		'fenv+$(ARCH).ha' \
		floats.ha  \
		ints.ha \
		uints.ha \
		trig.ha \
		$*
}

math() {
	if [ $testing -eq 0 ]; then
		gensrcs_math
	else
		gensrcs_math \
			+test/data.ha \
			+test/math.ha \
			+test/floats.ha \
			+test/trig.ha
	fi
	gen_ssa math types rt
}

mime() {
	# This module is not built by default because gen-stdlib does not do a good
	# job of resolving @init dependency ordering issues
	gen_srcs mime \
		database.ha \
		lookup.ha \
		parse.ha \
		system.ha
	gen_ssa mime ascii errors strings hash::fnv encoding::utf8 bufio \
		fs io os fmt
}

net() {
	gen_srcs -plinux net \
		+linux.ha \
		errors.ha \
		msg.ha
	gen_ssa -plinux net io errors rt fmt slices

	gen_srcs -pfreebsd net \
		+freebsd.ha \
		errors.ha \
		msg.ha
	gen_ssa -pfreebsd net io errors rt fmt slices
}

net_dial() {
	gen_srcs net::dial \
		registry.ha \
		dial.ha \
		ip.ha \
		resolve.ha
	gen_ssa net::dial net net::ip net::tcp net::udp net::dns net::uri \
		crypto::random strconv strings unix::hosts
}

net_dns() {
	gen_srcs net::dns \
		decode.ha \
		error.ha \
		encode.ha \
		query.ha \
		strdomain.ha \
		types.ha
	gen_ssa net::dns ascii endian net net::udp net::ip fmt strings \
		unix::resolvconf unix::poll time errors
}

gensrcs_net_ip() {
	gen_srcs -plinux net::ip \
		+linux.ha \
		ip.ha \
		$*
	gen_srcs -pfreebsd net::ip \
		+freebsd.ha \
		ip.ha \
		$*
}

net_ip() {
	if [ $testing -eq 0 ]
	then
		gensrcs_net_ip
	else
		gensrcs_net_ip \
			+test.ha
	fi
	gen_ssa -plinux net::ip bytes endian io strconv strings strio fmt
	gen_ssa -pfreebsd net::ip bytes endian io strconv strings strio fmt
}

net_tcp() {
	gen_srcs -plinux net::tcp \
		+linux.ha \
		listener.ha \
		options.ha
	gen_ssa -plinux net::tcp errors io net net::ip os rt

	gen_srcs -pfreebsd net::tcp \
		+freebsd.ha \
		listener.ha \
		options.ha
	gen_ssa -pfreebsd net::tcp errors io net net::ip os rt
}

net_udp() {
	gen_srcs -plinux net::udp \
		+linux.ha \
		options.ha
	gen_ssa -plinux net::udp errors net net::ip errors rt os io

	gen_srcs -pfreebsd net::udp \
		+freebsd.ha \
		options.ha
	gen_ssa -pfreebsd net::udp errors net net::ip errors rt os io
}

net_unix() {
	gen_srcs -plinux net::unix \
		+linux.ha \
		addr.ha \
		cmsg.ha \
		dial.ha \
		listener.ha \
		options.ha \
		socketpair.ha
	gen_ssa -plinux net::unix net errors os io strings types fmt \
		net::dial rt

	gen_srcs -pfreebsd net::unix \
		+freebsd.ha \
		addr.ha \
		cmsg.ha \
		dial.ha \
		listener.ha \
		options.ha \
		socketpair.ha
	gen_ssa -pfreebsd net::unix net errors os io strings types fmt \
		net::dial rt
}

gensrcs_net_uri() {
	gen_srcs net::uri \
		fmt.ha \
		parse.ha \
		query.ha \
		uri.ha \
		$*
}

net_uri() {
	if [ $testing -eq 0 ]
	then
		gensrcs_net_uri
	else
		gensrcs_net_uri \
			+test.ha
	fi
	gen_ssa net::uri \
		ascii encoding::utf8 fmt io net::ip strconv strings strio
}

gensrcs_math_complex() {
	gen_srcs math::complex \
		complex.ha \
		$*
}

math_complex() {
	if [ $testing -eq 0 ]
	then
		gensrcs_math_complex
	else
		gensrcs_math_complex \
			+test.ha
	fi
	gen_ssa math::complex math
}

math_random() {
	gen_srcs math::random \
		random.ha
	gen_ssa math::random
}

os() {
	if [ $testing -eq 0 ]
	then
		exit=exit.ha
	else
		exit=exit+test.ha
	fi

	gen_srcs -plinux os \
		+linux/dirfdfs.ha \
		+linux/environ.ha \
		+linux/$exit \
		+linux/fs.ha \
		+linux/memory.ha \
		+linux/stdfd.ha \
		os.ha
	gen_ssa -plinux os io strings fs encoding::utf8 bytes bufio \
		errors math types::c

	gen_srcs -pfreebsd os \
		+freebsd/environ.ha \
		+freebsd/$exit \
		+freebsd/dirfdfs.ha \
		+freebsd/stdfd.ha \
		+freebsd/fs.ha \
		os.ha
	gen_ssa -pfreebsd os io strings fs encoding::utf8 bytes bufio \
		errors types::c
}

os_exec() {
	gen_srcs -plinux os::exec \
		exec+linux.ha \
		process+linux.ha \
		types.ha \
		cmd.ha
	gen_ssa -plinux os::exec os strings fmt errors unix rt io ascii \
		unix::signal types::c

	gen_srcs -pfreebsd os::exec \
		exec+freebsd.ha \
		process+freebsd.ha \
		types.ha \
		cmd.ha
	gen_ssa -pfreebsd os::exec os strings fmt errors unix rt io ascii \
		types::c
}

path() {
	gen_srcs path \
		'+$(PLATFORM).ha' \
		buffer.ha \
		error.ha \
		stack.ha \
		ext_stack.ha \
		posix.ha \
		prefix.ha \
		iter.ha
	gen_ssa path strings bytes errors
}

regex() {
	if [ $testing -eq 0 ]; then
		gen_srcs regex regex.ha
		gen_ssa regex ascii bufio encoding::utf8 errors io strconv \
			strings bufio
	else
		gen_srcs regex regex.ha +test.ha
		gen_ssa regex encoding::utf8 errors strconv strings fmt io os bufio
	fi
}

gensrcs_strconv() {
	gen_srcs strconv \
		types.ha \
		itos.ha \
		utos.ha \
		stou.ha \
		stoi.ha \
		numeric.ha \
		ftos.ha \
		stof.ha \
		stof_data.ha \
		$*
}

gensrcs_shlex() {
	gen_srcs shlex \
		escape.ha \
		split.ha \
		$*
}

shlex() {
	if [ $testing -eq 0 ]
	then
		gensrcs_shlex
	else
		gensrcs_shlex \
			+test.ha
	fi
	gen_ssa shlex ascii encoding::utf8 io strings strio
}

slices() {
	gen_srcs slices \
		cap.ha \
		reverse.ha \
		trunc.ha \
		void.ha
	gen_ssa slices types rt
}

gensrcs_sort() {
	gen_srcs sort \
		bisect.ha \
		search.ha \
		sort.ha \
		types.ha \
		$*
}

sort() {
	if [ $testing -eq 0 ]
	then
		gensrcs_sort
	else
		gensrcs_sort \
			+test.ha
	fi
	gen_ssa sort strings types
}

strconv() {
	if [ $testing -eq 0 ]
	then
		gensrcs_strconv
	else
		gensrcs_strconv \
			+test/stou.ha \
			+test/stoi.ha
	fi
	gen_ssa strconv types strings ascii math bytes encoding::utf8
}

strings() {
	gen_srcs strings \
		cap.ha \
		concat.ha \
		contains.ha \
		dup.ha \
		iter.ha \
		runes.ha \
		sub.ha \
		suffix.ha \
		tokenize.ha \
		utf8.ha \
		index.ha \
		trim.ha \
		compare.ha \
		pad.ha \
		replace.ha
	gen_ssa strings bytes encoding::utf8 types
}

strings_template() {
	gen_srcs strings::template \
		template.ha
	gen_ssa strings::template ascii errors fmt io strings strio
}

strio() {
	gen_srcs strio \
		stream.ha \
		ops.ha
	gen_ssa strio errors io strings slices encoding::utf8
}

temp() {
	gen_srcs -plinux temp +linux.ha
	gen_ssa -plinux temp \
		crypto::random encoding::hex errors fs io os path strio fmt

	gen_srcs -pfreebsd temp +freebsd.ha
	gen_ssa -pfreebsd temp \
		crypto::random encoding::hex errors fs io os path strio fmt
}

time() {
	gen_srcs -plinux time \
		+linux/functions.ha \
		+linux/+'$(ARCH)'.ha \
		arithm.ha \
		conv.ha \
		types.ha
	gen_ssa -plinux time \
		linux::vdso math
	gen_srcs -pfreebsd time \
		+freebsd/functions.ha \
		arithm.ha \
		conv.ha \
		types.ha
	gen_ssa -pfreebsd time \
		math
}

time_chrono() {
	gen_srcs -plinux time::chrono \
		arithmetic.ha \
		+linux.ha \
		chronology.ha \
		error.ha \
		leapsec.ha \
		timescale.ha \
		timezone.ha \
		tzdb.ha
	gen_ssa -plinux time::chrono \
		bufio bytes encoding::utf8 endian errors fmt fs io os strconv strings time path
	gen_srcs -pfreebsd time::chrono \
		arithmetic.ha \
		+freebsd.ha \
		chronology.ha \
		error.ha \
		leapsec.ha \
		timescale.ha \
		timezone.ha \
		tzdb.ha
	gen_ssa -pfreebsd time::chrono \
		bufio bytes encoding::utf8 endian errors fmt fs io os strconv strings time path
}

types() {
	gen_srcs types \
		limits.ha \
		classes.ha \
		'arch+$(ARCH).ha'
	gen_ssa types
}

types_c() {
	if [ $testing -eq 1 ]
	then
		gen_srcs types::c +test.ha strings.ha types.ha 'arch+$(ARCH).ha'
	else
		gen_srcs types::c strings.ha types.ha 'arch+$(ARCH).ha'
	fi
	gen_ssa types::c encoding::utf8 types
}

unix() {
	gen_srcs -plinux unix \
		+linux/nice.ha \
		+linux/pipe.ha \
		+linux/umask.ha \
		+linux/getuid.ha \
		+linux/setuid.ha \
		+linux/groups.ha
	gen_ssa -plinux unix errors fs io

	gen_srcs -pfreebsd unix \
		+freebsd/nice.ha \
		+freebsd/pipe.ha \
		+freebsd/umask.ha \
		+freebsd/getuid.ha \
		+freebsd/setuid.ha \
		+freebsd/groups.ha
	gen_ssa -pfreebsd unix errors fs io
}

unix_hosts() {
	gen_srcs -plinux unix::hosts \
		+linux.ha \
		lookup.ha
	gen_ssa -plinux unix::hosts os io bufio net::ip strings

	gen_srcs -pfreebsd unix::hosts \
		+freebsd.ha \
		lookup.ha
	gen_ssa -pfreebsd unix::hosts os io bufio net::ip strings
}

unix_passwd() {
	gen_srcs unix::passwd \
		group.ha \
		passwd.ha \
		types.ha
	gen_ssa unix::passwd bufio io os strconv strings
}

unix_poll() {
	gen_srcs -plinux unix::poll +linux.ha types.ha
	gen_ssa -plinux unix::poll rt errors time io

	gen_srcs -pfreebsd unix::poll +freebsd.ha types.ha
	gen_ssa -pfreebsd unix::poll rt errors time io
}

unix_resolvconf() {
	gen_srcs -plinux unix::resolvconf \
		+linux.ha \
		load.ha
	gen_ssa -plinux unix::resolvconf os io bufio net::ip strings

	gen_srcs -pfreebsd unix::resolvconf \
		+freebsd.ha \
		load.ha
	gen_ssa -pfreebsd unix::resolvconf os io bufio net::ip strings
}

unix_signal() {
	gen_srcs -plinux unix::signal \
		types.ha \
		+linux.ha
	gen_ssa -plinux unix::signal io errors rt

	gen_srcs -pfreebsd unix::signal \
		types.ha \
		+freebsd.ha
	gen_ssa -pfreebsd unix::signal io errors rt
}

unix_tty() {
	gen_srcs -plinux unix::tty \
		types.ha \
		pty_common.ha \
		+linux/isatty.ha \
		+linux/open.ha \
		+linux/pty.ha \
		+linux/termios.ha \
		+linux/winsize.ha
	gen_ssa -plinux unix::tty bufio errors fmt fs io os rt strings

	gen_srcs -pfreebsd unix::tty \
		types.ha \
		pty_common.ha \
		+freebsd/isatty.ha \
		+freebsd/open.ha \
		+freebsd/pty.ha \
		+freebsd/winsize.ha
	gen_ssa -pfreebsd unix::tty bufio errors fmt fs io os rt strings \
		types::c
}

uuid() {
	gen_srcs uuid \
		uuid.ha
	gen_ssa uuid crypto::random strio fmt endian io bytes bufio strings strconv
}

# List of modules and their supported platforms. Place a tab between the module
# and its platform list, and spaces between each supported platform. Omitting
# the platform list implies all platforms are supported.
modules="ascii
bufio
bytes
crypto
crypto::aes
crypto::aes::xts
crypto::argon2
crypto::bcrypt
crypto::blake2b
crypto::blowfish
crypto::bigint
crypto::chacha
crypto::cipher
crypto::hkdf
crypto::hmac
crypto::mac
crypto::math
crypto::random	linux freebsd
crypto::rsa
crypto::poly1305
crypto::salsa
crypto::sha1
crypto::sha256
crypto::sha512
crypto::curve25519
crypto::ed25519
crypto::x25519
datetime	linux freebsd
dirs
encoding::base64
encoding::base32
encoding::hex
encoding::pem
encoding::utf8
endian
errors
fmt
fnmatch
format::elf
format::ini
format::tar
fs
getopt
glob
hare::ast
hare::lex
hare::module
hare::parse
hare::types
hare::unit
hare::unparse
hash
hash::adler32
hash::crc16
hash::crc32
hash::crc64
hash::fnv
hash::siphash
io			linux freebsd
linux			linux
linux::keyctl		linux
linux::timerfd	linux
linux::vdso		linux
log	linux freebsd
math
math::complex
math::random
net			linux freebsd
net::dial
net::dns
net::ip			linux freebsd
net::tcp		linux freebsd
net::udp		linux freebsd
net::unix		linux freebsd
net::uri
os			linux freebsd
os::exec		linux freebsd
path
regex
shlex
slices
sort
strconv
strings
strings::template
strio
temp			linux freebsd
test
time			linux freebsd
time::chrono	linux freebsd
types
types::c
unix			linux freebsd
unix::hosts	linux freebsd
unix::passwd
unix::poll		linux freebsd
unix::resolvconf	linux freebsd
unix::signal		linux freebsd
unix::tty		linux freebsd
uuid"
stdlib() {
	rt
	IFS="
"
	for module in $modules; do
		unset IFS
		if [ -z "$(echo "$module" | cut -sf1)" ]
		then
			gen_lib "$module"
		else
			platforms="$(echo "$module" | cut -sf2-)"
			module="$(echo "$module" | cut -sf1)"
			for platform in $platforms
			do
				gen_lib -p "$platform" "$module"
			done
		fi
		IFS="
"
	done
	IFS="
"
	for module in $modules; do
		unset IFS
		if [ -n "$(echo "$module" | cut -sf1)" ]
		then
			module="$(echo "$module" | cut -sf1)"
		fi
		"$(mod_file "$module")"
		IFS="
"
	done
	unset IFS
}

if [ ${DOCS:-0} -ne 1 ]
then
	printf '# This file is generated by the gen-stdlib script, do not edit it by hand\n\n'
	genrules
	genrules test
fi
diff --git a/scripts/gen-stdlib.sh b/scripts/gen-stdlib.sh
deleted file mode 100644
index 7909d9ca..00000000
--- a/scripts/gen-stdlib.sh
@@ -1,138 +0,0 @@
mod_path() {
	printf '%s\n' "$1" | tr -s '::' '/'
}
mod_file() {
	printf '%s\n' "$1" | tr -s '::' '_'
}
mod_var() {
	printf '%s_%s_%s\n' "$stdlib" "$1" "$2" | tr -s '::' '_'
}

gen_srcs() {
	platform=any
	OPTIND=1
	while getopts p: name
	do
		case $name in
		p)
			platform="$OPTARG"
			;;
		?)
			printf 'Invalid use of gen_srcs' >&2
			exit 1
			;;
		esac
	done
	shift $(($OPTIND - 1))

	mod="$1"
	shift

	path="$(mod_path "$mod")"
	var="$(mod_var "$mod" "$platform")"

	printf '# %s (+%s)\n' "$mod" "$platform"
	printf '%s_srcs = \\\n' "$var"
	while [ $# -ne 0 ]
	do
		if [ $# -eq 1 ]
		then
			printf '\t$(STDLIB)/%s/%s\n\n' "$path" "$1"
		else
			printf '\t$(STDLIB)/%s/%s \\\n' "$path" "$1"
		fi
		shift
	done
}

gen_ssa() {
	platform=any
	OPTIND=1
	while getopts p: name
	do
		case $name in
		p)
			platform="$OPTARG"
			;;
		?)
			printf 'Invalid use of gen_ssa' >&2
			exit 1
			;;
		esac
	done
	shift $(($OPTIND - 1))

	mod="$1"
	shift

	path=$(mod_path "$mod")
	file=$(mod_file "$mod")
	var=$(mod_var "$mod" "$platform")

	printf "\$($cache)/$path/$file-$platform.ssa: \$(${var}_srcs) \$(${stdlib}_rt)"
	for dep in $*
	do
		printf ' $(%s)' "$(mod_var "$dep" \$"(PLATFORM)")"
	done
	printf '\n'

	cat <<EOF
	@printf 'HAREC \t\$@\n'
	@mkdir -p \$($cache)/$path
	@\$(${stdlib}_env) \$(HAREC) \$($flags) -o \$@ -N$mod \\
		-t\$($cache)/$path/$file.td \$(${var}_srcs)

EOF
}

gen_lib() {
	platform=any
	OPTIND=1
	while getopts p: name
	do
		case $name in
		p)
			platform="$OPTARG"
			;;
		?)
			printf 'Invalid use of gen_lib' >&2
			exit 1
			;;
		esac
	done
	shift $(($OPTIND - 1))

	printf "# gen_lib $1 ($platform)\n"

	mod="$1"
	path=$(mod_path "$mod")
	file=$(mod_file "$mod")
	var=$(mod_var "$mod" "$platform")
	printf "%s = \$(%s)/%s/%s-%s.o\n" "$var" "$cache" "$path" "$file" "$platform"
	printf "%s_env += HARE_TD_%s=\$(%s)/%s/%s.td\n" "$stdlib" "$mod" "$cache" "$path" "$file"
	printf '%s_deps_%s += $(%s)\n' "$stdlib" "$platform" "$var"
	if [ "$platform" = "any" ]
	then
		for p in $all_platforms
		do
			printf '%s = $(%s)\n' "$(mod_var "$mod" "$p")" "$var"
		done
	fi
	printf '\n'
}

genrules() {
	if [ $# -gt 0 ] && [ "$1" = "test" ]
	then
		cache=TESTCACHE
		flags=TESTHAREFLAGS
		testing=1
		stdlib=testlib
	else
		cache=HARECACHE
		flags=HAREFLAGS
		testing=0
		stdlib=stdlib
	fi
	stdlib
}
diff --git a/scripts/install-mods b/scripts/install-mods
deleted file mode 100755
index 5f9f5756..00000000
--- a/scripts/install-mods
@@ -1,47 +0,0 @@
#!/bin/sh
modules="ascii
bufio
bytes
crypto
datetime
dirs
encoding
endian
errors
fmt
fnmatch
format
fs
getopt
glob
hare
hash
io
linux
log
math
mime
net
os
path
regex
rt
shlex
slices
sort
strconv
strings
strio
temp
test
time
types
unix
uuid"
IFS="
"
for mod in $modules
do
	printf 'install %s\n' "$mod"
	cp -R $mod $1
done
diff --git a/scripts/modules b/scripts/modules
deleted file mode 100755
index d0e80ee9..00000000
--- a/scripts/modules
@@ -1,27 +0,0 @@
#!/bin/sh
set -e

lookup() {
	for i in "$1"/*
	do
		i="${i#./}"
		[ -d "$i" ] || continue
		case "$i" in
			.*|*+*|cmd|contrib|docs|scripts)
				continue
				;;
			*)
				for j in "$i"/*.ha
				do
					[ -e "$j" ] || break
					i="$(printf '%s\n' "${i%/}" | sed 's|/|::|g')"
					printf 'use %s;\n' "$i"
					break
				done
				lookup "$i"
				;;
		esac
	done
}

lookup .
diff --git a/stdlib.mk b/stdlib.mk
deleted file mode 100644
index 9ee5cb08..00000000
--- a/stdlib.mk
@@ -1,4849 +0,0 @@
# This file is generated by the gen-stdlib script, do not edit it by hand

rtscript = $(STDLIB)/rt/hare.sc
# rt (+linux)
stdlib_rt_linux_srcs = \
	$(STDLIB)/rt/+linux/platform_abort.ha \
	$(STDLIB)/rt/+linux/env.ha \
	$(STDLIB)/rt/+linux/errno.ha \
	$(STDLIB)/rt/+linux/types.ha \
	$(STDLIB)/rt/+linux/segmalloc.ha \
	$(STDLIB)/rt/+linux/platformstart.ha \
	$(STDLIB)/rt/+linux/prctl.ha \
	$(STDLIB)/rt/+linux/+$(ARCH).ha \
	$(STDLIB)/rt/+linux/syscallno+$(ARCH).ha \
	$(STDLIB)/rt/+linux/syscalls.ha \
	$(STDLIB)/rt/+linux/syscallsarch+$(ARCH).ha \
	$(STDLIB)/rt/+linux/signal.ha \
	$(STDLIB)/rt/+linux/stat.ha \
	$(STDLIB)/rt/+linux/socket.ha \
	$(STDLIB)/rt/+$(ARCH)/jmp.ha \
	$(STDLIB)/rt/+$(ARCH)/backtrace.ha \
	$(STDLIB)/rt/fenv_defs.ha \
	$(STDLIB)/rt/+$(ARCH)/cpuid.ha \
	$(STDLIB)/rt/ensure.ha \
	$(STDLIB)/rt/jmp.ha \
	$(STDLIB)/rt/malloc.ha \
	$(STDLIB)/rt/memcpy.ha \
	$(STDLIB)/rt/memmove.ha \
	$(STDLIB)/rt/memset.ha \
	$(STDLIB)/rt/strcmp.ha \
	$(STDLIB)/rt/abort.ha \
	$(STDLIB)/rt/start.ha

# rt (+freebsd)
stdlib_rt_freebsd_srcs = \
	$(STDLIB)/rt/+freebsd/platform_abort.ha \
	$(STDLIB)/rt/+freebsd/env.ha \
	$(STDLIB)/rt/+freebsd/errno.ha \
	$(STDLIB)/rt/+freebsd/platformstart.ha \
	$(STDLIB)/rt/+freebsd/segmalloc.ha \
	$(STDLIB)/rt/+freebsd/signal.ha \
	$(STDLIB)/rt/+freebsd/socket.ha \
	$(STDLIB)/rt/+freebsd/+$(ARCH).ha \
	$(STDLIB)/rt/+freebsd/syscallno.ha \
	$(STDLIB)/rt/+freebsd/syscalls.ha \
	$(STDLIB)/rt/+freebsd/types.ha \
	$(STDLIB)/rt/+$(ARCH)/jmp.ha \
	$(STDLIB)/rt/+$(ARCH)/backtrace.ha \
	$(STDLIB)/rt/fenv_defs.ha \
	$(STDLIB)/rt/+$(ARCH)/cpuid.ha \
	$(STDLIB)/rt/ensure.ha \
	$(STDLIB)/rt/jmp.ha \
	$(STDLIB)/rt/malloc.ha \
	$(STDLIB)/rt/memcpy.ha \
	$(STDLIB)/rt/memmove.ha \
	$(STDLIB)/rt/memset.ha \
	$(STDLIB)/rt/strcmp.ha \
	$(STDLIB)/rt/abort.ha \
	$(STDLIB)/rt/start.ha

$(HARECACHE)/rt/rt-linux.ssa: $(stdlib_rt_linux_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/rt
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nrt \
		-t$(HARECACHE)/rt/rt.td $(stdlib_rt_linux_srcs)

$(HARECACHE)/rt/rt-freebsd.ssa: $(stdlib_rt_freebsd_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/rt
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nrt \
		-t$(HARECACHE)/rt/rt.td $(stdlib_rt_freebsd_srcs)

$(HARECACHE)/rt/start.o: $(STDLIB)/rt/+$(PLATFORM)/start+$(ARCH)-libc.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(PLATFORM)/start+$(ARCH)-libc.s

stdlib_asm = $(HARECACHE)/rt/syscall.o \
	$(HARECACHE)/rt/setjmp.o \
	$(HARECACHE)/rt/longjmp.o \
	$(HARECACHE)/rt/restore.o \
	$(HARECACHE)/rt/getfp.o \
	$(HARECACHE)/rt/fenv.o \
	$(HARECACHE)/rt/start.o \
	$(HARECACHE)/rt/cpuid_native.o

$(HARECACHE)/rt/syscall.o: $(STDLIB)/rt/+$(PLATFORM)/syscall+$(ARCH).s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(PLATFORM)/syscall+$(ARCH).s

$(HARECACHE)/rt/setjmp.o: $(STDLIB)/rt/+$(ARCH)/setjmp.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/setjmp.s

$(HARECACHE)/rt/longjmp.o: $(STDLIB)/rt/+$(ARCH)/longjmp.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/longjmp.s

$(HARECACHE)/rt/restore.o: $(STDLIB)/rt/+$(ARCH)/restore.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/restore.s

$(HARECACHE)/rt/fenv.o: $(STDLIB)/rt/+$(ARCH)/fenv.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/fenv.s

$(HARECACHE)/rt/getfp.o: $(STDLIB)/rt/+$(ARCH)/getfp.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/getfp.s

$(HARECACHE)/rt/cpuid_native.o: $(STDLIB)/rt/+$(ARCH)/cpuid_native.s
	@printf 'AS \t%s\n' "$@"
	@mkdir -p $(HARECACHE)/rt
	@$(AS) -o $@ $(STDLIB)/rt/+$(ARCH)/cpuid_native.s

$(HARECACHE)/rt/rt-linux.a: $(HARECACHE)/rt/rt-linux.o $(stdlib_asm)
	@printf 'AR \t%s\n' "$@"
	@$(AR) -csr $@ $(HARECACHE)/rt/rt-linux.o $(stdlib_asm)

$(HARECACHE)/rt/rt-freebsd.a: $(HARECACHE)/rt/rt-freebsd.o $(stdlib_asm)
	@printf 'AR \t%s\n' "$@"
	@$(AR) -csr $@ $(HARECACHE)/rt/rt-freebsd.o $(stdlib_asm)

stdlib_rt = $(HARECACHE)/rt/rt-$(PLATFORM).a
stdlib_env += HARE_TD_rt=$(HARECACHE)/rt/rt.td
stdlib_deps_linux += $(stdlib_rt)
stdlib_deps_freebsd += $(stdlib_rt)
stdlib_deps_any += $(stdlib_rt)

# gen_lib ascii (any)
stdlib_ascii_any = $(HARECACHE)/ascii/ascii-any.o
stdlib_env += HARE_TD_ascii=$(HARECACHE)/ascii/ascii.td
stdlib_deps_any += $(stdlib_ascii_any)
stdlib_ascii_linux = $(stdlib_ascii_any)
stdlib_ascii_freebsd = $(stdlib_ascii_any)

# gen_lib bufio (any)
stdlib_bufio_any = $(HARECACHE)/bufio/bufio-any.o
stdlib_env += HARE_TD_bufio=$(HARECACHE)/bufio/bufio.td
stdlib_deps_any += $(stdlib_bufio_any)
stdlib_bufio_linux = $(stdlib_bufio_any)
stdlib_bufio_freebsd = $(stdlib_bufio_any)

# gen_lib bytes (any)
stdlib_bytes_any = $(HARECACHE)/bytes/bytes-any.o
stdlib_env += HARE_TD_bytes=$(HARECACHE)/bytes/bytes.td
stdlib_deps_any += $(stdlib_bytes_any)
stdlib_bytes_linux = $(stdlib_bytes_any)
stdlib_bytes_freebsd = $(stdlib_bytes_any)

# gen_lib crypto (any)
stdlib_crypto_any = $(HARECACHE)/crypto/crypto-any.o
stdlib_env += HARE_TD_crypto=$(HARECACHE)/crypto/crypto.td
stdlib_deps_any += $(stdlib_crypto_any)
stdlib_crypto_linux = $(stdlib_crypto_any)
stdlib_crypto_freebsd = $(stdlib_crypto_any)

# gen_lib crypto::aes (any)
stdlib_crypto_aes_any = $(HARECACHE)/crypto/aes/crypto_aes-any.o
stdlib_env += HARE_TD_crypto::aes=$(HARECACHE)/crypto/aes/crypto_aes.td
stdlib_deps_any += $(stdlib_crypto_aes_any)
stdlib_crypto_aes_linux = $(stdlib_crypto_aes_any)
stdlib_crypto_aes_freebsd = $(stdlib_crypto_aes_any)

# gen_lib crypto::aes::xts (any)
stdlib_crypto_aes_xts_any = $(HARECACHE)/crypto/aes/xts/crypto_aes_xts-any.o
stdlib_env += HARE_TD_crypto::aes::xts=$(HARECACHE)/crypto/aes/xts/crypto_aes_xts.td
stdlib_deps_any += $(stdlib_crypto_aes_xts_any)
stdlib_crypto_aes_xts_linux = $(stdlib_crypto_aes_xts_any)
stdlib_crypto_aes_xts_freebsd = $(stdlib_crypto_aes_xts_any)

# gen_lib crypto::argon2 (any)
stdlib_crypto_argon2_any = $(HARECACHE)/crypto/argon2/crypto_argon2-any.o
stdlib_env += HARE_TD_crypto::argon2=$(HARECACHE)/crypto/argon2/crypto_argon2.td
stdlib_deps_any += $(stdlib_crypto_argon2_any)
stdlib_crypto_argon2_linux = $(stdlib_crypto_argon2_any)
stdlib_crypto_argon2_freebsd = $(stdlib_crypto_argon2_any)

# gen_lib crypto::bcrypt (any)
stdlib_crypto_bcrypt_any = $(HARECACHE)/crypto/bcrypt/crypto_bcrypt-any.o
stdlib_env += HARE_TD_crypto::bcrypt=$(HARECACHE)/crypto/bcrypt/crypto_bcrypt.td
stdlib_deps_any += $(stdlib_crypto_bcrypt_any)
stdlib_crypto_bcrypt_linux = $(stdlib_crypto_bcrypt_any)
stdlib_crypto_bcrypt_freebsd = $(stdlib_crypto_bcrypt_any)

# gen_lib crypto::blake2b (any)
stdlib_crypto_blake2b_any = $(HARECACHE)/crypto/blake2b/crypto_blake2b-any.o
stdlib_env += HARE_TD_crypto::blake2b=$(HARECACHE)/crypto/blake2b/crypto_blake2b.td
stdlib_deps_any += $(stdlib_crypto_blake2b_any)
stdlib_crypto_blake2b_linux = $(stdlib_crypto_blake2b_any)
stdlib_crypto_blake2b_freebsd = $(stdlib_crypto_blake2b_any)

# gen_lib crypto::blowfish (any)
stdlib_crypto_blowfish_any = $(HARECACHE)/crypto/blowfish/crypto_blowfish-any.o
stdlib_env += HARE_TD_crypto::blowfish=$(HARECACHE)/crypto/blowfish/crypto_blowfish.td
stdlib_deps_any += $(stdlib_crypto_blowfish_any)
stdlib_crypto_blowfish_linux = $(stdlib_crypto_blowfish_any)
stdlib_crypto_blowfish_freebsd = $(stdlib_crypto_blowfish_any)

# gen_lib crypto::bigint (any)
stdlib_crypto_bigint_any = $(HARECACHE)/crypto/bigint/crypto_bigint-any.o
stdlib_env += HARE_TD_crypto::bigint=$(HARECACHE)/crypto/bigint/crypto_bigint.td
stdlib_deps_any += $(stdlib_crypto_bigint_any)
stdlib_crypto_bigint_linux = $(stdlib_crypto_bigint_any)
stdlib_crypto_bigint_freebsd = $(stdlib_crypto_bigint_any)

# gen_lib crypto::chacha (any)
stdlib_crypto_chacha_any = $(HARECACHE)/crypto/chacha/crypto_chacha-any.o
stdlib_env += HARE_TD_crypto::chacha=$(HARECACHE)/crypto/chacha/crypto_chacha.td
stdlib_deps_any += $(stdlib_crypto_chacha_any)
stdlib_crypto_chacha_linux = $(stdlib_crypto_chacha_any)
stdlib_crypto_chacha_freebsd = $(stdlib_crypto_chacha_any)

# gen_lib crypto::cipher (any)
stdlib_crypto_cipher_any = $(HARECACHE)/crypto/cipher/crypto_cipher-any.o
stdlib_env += HARE_TD_crypto::cipher=$(HARECACHE)/crypto/cipher/crypto_cipher.td
stdlib_deps_any += $(stdlib_crypto_cipher_any)
stdlib_crypto_cipher_linux = $(stdlib_crypto_cipher_any)
stdlib_crypto_cipher_freebsd = $(stdlib_crypto_cipher_any)

# gen_lib crypto::hkdf (any)
stdlib_crypto_hkdf_any = $(HARECACHE)/crypto/hkdf/crypto_hkdf-any.o
stdlib_env += HARE_TD_crypto::hkdf=$(HARECACHE)/crypto/hkdf/crypto_hkdf.td
stdlib_deps_any += $(stdlib_crypto_hkdf_any)
stdlib_crypto_hkdf_linux = $(stdlib_crypto_hkdf_any)
stdlib_crypto_hkdf_freebsd = $(stdlib_crypto_hkdf_any)

# gen_lib crypto::hmac (any)
stdlib_crypto_hmac_any = $(HARECACHE)/crypto/hmac/crypto_hmac-any.o
stdlib_env += HARE_TD_crypto::hmac=$(HARECACHE)/crypto/hmac/crypto_hmac.td
stdlib_deps_any += $(stdlib_crypto_hmac_any)
stdlib_crypto_hmac_linux = $(stdlib_crypto_hmac_any)
stdlib_crypto_hmac_freebsd = $(stdlib_crypto_hmac_any)

# gen_lib crypto::mac (any)
stdlib_crypto_mac_any = $(HARECACHE)/crypto/mac/crypto_mac-any.o
stdlib_env += HARE_TD_crypto::mac=$(HARECACHE)/crypto/mac/crypto_mac.td
stdlib_deps_any += $(stdlib_crypto_mac_any)
stdlib_crypto_mac_linux = $(stdlib_crypto_mac_any)
stdlib_crypto_mac_freebsd = $(stdlib_crypto_mac_any)

# gen_lib crypto::math (any)
stdlib_crypto_math_any = $(HARECACHE)/crypto/math/crypto_math-any.o
stdlib_env += HARE_TD_crypto::math=$(HARECACHE)/crypto/math/crypto_math.td
stdlib_deps_any += $(stdlib_crypto_math_any)
stdlib_crypto_math_linux = $(stdlib_crypto_math_any)
stdlib_crypto_math_freebsd = $(stdlib_crypto_math_any)

# gen_lib crypto::random (linux)
stdlib_crypto_random_linux = $(HARECACHE)/crypto/random/crypto_random-linux.o
stdlib_env += HARE_TD_crypto::random=$(HARECACHE)/crypto/random/crypto_random.td
stdlib_deps_linux += $(stdlib_crypto_random_linux)

# gen_lib crypto::random (freebsd)
stdlib_crypto_random_freebsd = $(HARECACHE)/crypto/random/crypto_random-freebsd.o
stdlib_env += HARE_TD_crypto::random=$(HARECACHE)/crypto/random/crypto_random.td
stdlib_deps_freebsd += $(stdlib_crypto_random_freebsd)

# gen_lib crypto::rsa (any)
stdlib_crypto_rsa_any = $(HARECACHE)/crypto/rsa/crypto_rsa-any.o
stdlib_env += HARE_TD_crypto::rsa=$(HARECACHE)/crypto/rsa/crypto_rsa.td
stdlib_deps_any += $(stdlib_crypto_rsa_any)
stdlib_crypto_rsa_linux = $(stdlib_crypto_rsa_any)
stdlib_crypto_rsa_freebsd = $(stdlib_crypto_rsa_any)

# gen_lib crypto::poly1305 (any)
stdlib_crypto_poly1305_any = $(HARECACHE)/crypto/poly1305/crypto_poly1305-any.o
stdlib_env += HARE_TD_crypto::poly1305=$(HARECACHE)/crypto/poly1305/crypto_poly1305.td
stdlib_deps_any += $(stdlib_crypto_poly1305_any)
stdlib_crypto_poly1305_linux = $(stdlib_crypto_poly1305_any)
stdlib_crypto_poly1305_freebsd = $(stdlib_crypto_poly1305_any)

# gen_lib crypto::salsa (any)
stdlib_crypto_salsa_any = $(HARECACHE)/crypto/salsa/crypto_salsa-any.o
stdlib_env += HARE_TD_crypto::salsa=$(HARECACHE)/crypto/salsa/crypto_salsa.td
stdlib_deps_any += $(stdlib_crypto_salsa_any)
stdlib_crypto_salsa_linux = $(stdlib_crypto_salsa_any)
stdlib_crypto_salsa_freebsd = $(stdlib_crypto_salsa_any)

# gen_lib crypto::sha1 (any)
stdlib_crypto_sha1_any = $(HARECACHE)/crypto/sha1/crypto_sha1-any.o
stdlib_env += HARE_TD_crypto::sha1=$(HARECACHE)/crypto/sha1/crypto_sha1.td
stdlib_deps_any += $(stdlib_crypto_sha1_any)
stdlib_crypto_sha1_linux = $(stdlib_crypto_sha1_any)
stdlib_crypto_sha1_freebsd = $(stdlib_crypto_sha1_any)

# gen_lib crypto::sha256 (any)
stdlib_crypto_sha256_any = $(HARECACHE)/crypto/sha256/crypto_sha256-any.o
stdlib_env += HARE_TD_crypto::sha256=$(HARECACHE)/crypto/sha256/crypto_sha256.td
stdlib_deps_any += $(stdlib_crypto_sha256_any)
stdlib_crypto_sha256_linux = $(stdlib_crypto_sha256_any)
stdlib_crypto_sha256_freebsd = $(stdlib_crypto_sha256_any)

# gen_lib crypto::sha512 (any)
stdlib_crypto_sha512_any = $(HARECACHE)/crypto/sha512/crypto_sha512-any.o
stdlib_env += HARE_TD_crypto::sha512=$(HARECACHE)/crypto/sha512/crypto_sha512.td
stdlib_deps_any += $(stdlib_crypto_sha512_any)
stdlib_crypto_sha512_linux = $(stdlib_crypto_sha512_any)
stdlib_crypto_sha512_freebsd = $(stdlib_crypto_sha512_any)

# gen_lib crypto::curve25519 (any)
stdlib_crypto_curve25519_any = $(HARECACHE)/crypto/curve25519/crypto_curve25519-any.o
stdlib_env += HARE_TD_crypto::curve25519=$(HARECACHE)/crypto/curve25519/crypto_curve25519.td
stdlib_deps_any += $(stdlib_crypto_curve25519_any)
stdlib_crypto_curve25519_linux = $(stdlib_crypto_curve25519_any)
stdlib_crypto_curve25519_freebsd = $(stdlib_crypto_curve25519_any)

# gen_lib crypto::ed25519 (any)
stdlib_crypto_ed25519_any = $(HARECACHE)/crypto/ed25519/crypto_ed25519-any.o
stdlib_env += HARE_TD_crypto::ed25519=$(HARECACHE)/crypto/ed25519/crypto_ed25519.td
stdlib_deps_any += $(stdlib_crypto_ed25519_any)
stdlib_crypto_ed25519_linux = $(stdlib_crypto_ed25519_any)
stdlib_crypto_ed25519_freebsd = $(stdlib_crypto_ed25519_any)

# gen_lib crypto::x25519 (any)
stdlib_crypto_x25519_any = $(HARECACHE)/crypto/x25519/crypto_x25519-any.o
stdlib_env += HARE_TD_crypto::x25519=$(HARECACHE)/crypto/x25519/crypto_x25519.td
stdlib_deps_any += $(stdlib_crypto_x25519_any)
stdlib_crypto_x25519_linux = $(stdlib_crypto_x25519_any)
stdlib_crypto_x25519_freebsd = $(stdlib_crypto_x25519_any)

# gen_lib datetime (linux)
stdlib_datetime_linux = $(HARECACHE)/datetime/datetime-linux.o
stdlib_env += HARE_TD_datetime=$(HARECACHE)/datetime/datetime.td
stdlib_deps_linux += $(stdlib_datetime_linux)

# gen_lib datetime (freebsd)
stdlib_datetime_freebsd = $(HARECACHE)/datetime/datetime-freebsd.o
stdlib_env += HARE_TD_datetime=$(HARECACHE)/datetime/datetime.td
stdlib_deps_freebsd += $(stdlib_datetime_freebsd)

# gen_lib dirs (any)
stdlib_dirs_any = $(HARECACHE)/dirs/dirs-any.o
stdlib_env += HARE_TD_dirs=$(HARECACHE)/dirs/dirs.td
stdlib_deps_any += $(stdlib_dirs_any)
stdlib_dirs_linux = $(stdlib_dirs_any)
stdlib_dirs_freebsd = $(stdlib_dirs_any)

# gen_lib encoding::base64 (any)
stdlib_encoding_base64_any = $(HARECACHE)/encoding/base64/encoding_base64-any.o
stdlib_env += HARE_TD_encoding::base64=$(HARECACHE)/encoding/base64/encoding_base64.td
stdlib_deps_any += $(stdlib_encoding_base64_any)
stdlib_encoding_base64_linux = $(stdlib_encoding_base64_any)
stdlib_encoding_base64_freebsd = $(stdlib_encoding_base64_any)

# gen_lib encoding::base32 (any)
stdlib_encoding_base32_any = $(HARECACHE)/encoding/base32/encoding_base32-any.o
stdlib_env += HARE_TD_encoding::base32=$(HARECACHE)/encoding/base32/encoding_base32.td
stdlib_deps_any += $(stdlib_encoding_base32_any)
stdlib_encoding_base32_linux = $(stdlib_encoding_base32_any)
stdlib_encoding_base32_freebsd = $(stdlib_encoding_base32_any)

# gen_lib encoding::hex (any)
stdlib_encoding_hex_any = $(HARECACHE)/encoding/hex/encoding_hex-any.o
stdlib_env += HARE_TD_encoding::hex=$(HARECACHE)/encoding/hex/encoding_hex.td
stdlib_deps_any += $(stdlib_encoding_hex_any)
stdlib_encoding_hex_linux = $(stdlib_encoding_hex_any)
stdlib_encoding_hex_freebsd = $(stdlib_encoding_hex_any)

# gen_lib encoding::pem (any)
stdlib_encoding_pem_any = $(HARECACHE)/encoding/pem/encoding_pem-any.o
stdlib_env += HARE_TD_encoding::pem=$(HARECACHE)/encoding/pem/encoding_pem.td
stdlib_deps_any += $(stdlib_encoding_pem_any)
stdlib_encoding_pem_linux = $(stdlib_encoding_pem_any)
stdlib_encoding_pem_freebsd = $(stdlib_encoding_pem_any)

# gen_lib encoding::utf8 (any)
stdlib_encoding_utf8_any = $(HARECACHE)/encoding/utf8/encoding_utf8-any.o
stdlib_env += HARE_TD_encoding::utf8=$(HARECACHE)/encoding/utf8/encoding_utf8.td
stdlib_deps_any += $(stdlib_encoding_utf8_any)
stdlib_encoding_utf8_linux = $(stdlib_encoding_utf8_any)
stdlib_encoding_utf8_freebsd = $(stdlib_encoding_utf8_any)

# gen_lib endian (any)
stdlib_endian_any = $(HARECACHE)/endian/endian-any.o
stdlib_env += HARE_TD_endian=$(HARECACHE)/endian/endian.td
stdlib_deps_any += $(stdlib_endian_any)
stdlib_endian_linux = $(stdlib_endian_any)
stdlib_endian_freebsd = $(stdlib_endian_any)

# gen_lib errors (any)
stdlib_errors_any = $(HARECACHE)/errors/errors-any.o
stdlib_env += HARE_TD_errors=$(HARECACHE)/errors/errors.td
stdlib_deps_any += $(stdlib_errors_any)
stdlib_errors_linux = $(stdlib_errors_any)
stdlib_errors_freebsd = $(stdlib_errors_any)

# gen_lib fmt (any)
stdlib_fmt_any = $(HARECACHE)/fmt/fmt-any.o
stdlib_env += HARE_TD_fmt=$(HARECACHE)/fmt/fmt.td
stdlib_deps_any += $(stdlib_fmt_any)
stdlib_fmt_linux = $(stdlib_fmt_any)
stdlib_fmt_freebsd = $(stdlib_fmt_any)

# gen_lib fnmatch (any)
stdlib_fnmatch_any = $(HARECACHE)/fnmatch/fnmatch-any.o
stdlib_env += HARE_TD_fnmatch=$(HARECACHE)/fnmatch/fnmatch.td
stdlib_deps_any += $(stdlib_fnmatch_any)
stdlib_fnmatch_linux = $(stdlib_fnmatch_any)
stdlib_fnmatch_freebsd = $(stdlib_fnmatch_any)

# gen_lib format::elf (any)
stdlib_format_elf_any = $(HARECACHE)/format/elf/format_elf-any.o
stdlib_env += HARE_TD_format::elf=$(HARECACHE)/format/elf/format_elf.td
stdlib_deps_any += $(stdlib_format_elf_any)
stdlib_format_elf_linux = $(stdlib_format_elf_any)
stdlib_format_elf_freebsd = $(stdlib_format_elf_any)

# gen_lib format::ini (any)
stdlib_format_ini_any = $(HARECACHE)/format/ini/format_ini-any.o
stdlib_env += HARE_TD_format::ini=$(HARECACHE)/format/ini/format_ini.td
stdlib_deps_any += $(stdlib_format_ini_any)
stdlib_format_ini_linux = $(stdlib_format_ini_any)
stdlib_format_ini_freebsd = $(stdlib_format_ini_any)

# gen_lib format::tar (any)
stdlib_format_tar_any = $(HARECACHE)/format/tar/format_tar-any.o
stdlib_env += HARE_TD_format::tar=$(HARECACHE)/format/tar/format_tar.td
stdlib_deps_any += $(stdlib_format_tar_any)
stdlib_format_tar_linux = $(stdlib_format_tar_any)
stdlib_format_tar_freebsd = $(stdlib_format_tar_any)

# gen_lib fs (any)
stdlib_fs_any = $(HARECACHE)/fs/fs-any.o
stdlib_env += HARE_TD_fs=$(HARECACHE)/fs/fs.td
stdlib_deps_any += $(stdlib_fs_any)
stdlib_fs_linux = $(stdlib_fs_any)
stdlib_fs_freebsd = $(stdlib_fs_any)

# gen_lib getopt (any)
stdlib_getopt_any = $(HARECACHE)/getopt/getopt-any.o
stdlib_env += HARE_TD_getopt=$(HARECACHE)/getopt/getopt.td
stdlib_deps_any += $(stdlib_getopt_any)
stdlib_getopt_linux = $(stdlib_getopt_any)
stdlib_getopt_freebsd = $(stdlib_getopt_any)

# gen_lib glob (any)
stdlib_glob_any = $(HARECACHE)/glob/glob-any.o
stdlib_env += HARE_TD_glob=$(HARECACHE)/glob/glob.td
stdlib_deps_any += $(stdlib_glob_any)
stdlib_glob_linux = $(stdlib_glob_any)
stdlib_glob_freebsd = $(stdlib_glob_any)

# gen_lib hare::ast (any)
stdlib_hare_ast_any = $(HARECACHE)/hare/ast/hare_ast-any.o
stdlib_env += HARE_TD_hare::ast=$(HARECACHE)/hare/ast/hare_ast.td
stdlib_deps_any += $(stdlib_hare_ast_any)
stdlib_hare_ast_linux = $(stdlib_hare_ast_any)
stdlib_hare_ast_freebsd = $(stdlib_hare_ast_any)

# gen_lib hare::lex (any)
stdlib_hare_lex_any = $(HARECACHE)/hare/lex/hare_lex-any.o
stdlib_env += HARE_TD_hare::lex=$(HARECACHE)/hare/lex/hare_lex.td
stdlib_deps_any += $(stdlib_hare_lex_any)
stdlib_hare_lex_linux = $(stdlib_hare_lex_any)
stdlib_hare_lex_freebsd = $(stdlib_hare_lex_any)

# gen_lib hare::module (any)
stdlib_hare_module_any = $(HARECACHE)/hare/module/hare_module-any.o
stdlib_env += HARE_TD_hare::module=$(HARECACHE)/hare/module/hare_module.td
stdlib_deps_any += $(stdlib_hare_module_any)
stdlib_hare_module_linux = $(stdlib_hare_module_any)
stdlib_hare_module_freebsd = $(stdlib_hare_module_any)

# gen_lib hare::parse (any)
stdlib_hare_parse_any = $(HARECACHE)/hare/parse/hare_parse-any.o
stdlib_env += HARE_TD_hare::parse=$(HARECACHE)/hare/parse/hare_parse.td
stdlib_deps_any += $(stdlib_hare_parse_any)
stdlib_hare_parse_linux = $(stdlib_hare_parse_any)
stdlib_hare_parse_freebsd = $(stdlib_hare_parse_any)

# gen_lib hare::types (any)
stdlib_hare_types_any = $(HARECACHE)/hare/types/hare_types-any.o
stdlib_env += HARE_TD_hare::types=$(HARECACHE)/hare/types/hare_types.td
stdlib_deps_any += $(stdlib_hare_types_any)
stdlib_hare_types_linux = $(stdlib_hare_types_any)
stdlib_hare_types_freebsd = $(stdlib_hare_types_any)

# gen_lib hare::unit (any)
stdlib_hare_unit_any = $(HARECACHE)/hare/unit/hare_unit-any.o
stdlib_env += HARE_TD_hare::unit=$(HARECACHE)/hare/unit/hare_unit.td
stdlib_deps_any += $(stdlib_hare_unit_any)
stdlib_hare_unit_linux = $(stdlib_hare_unit_any)
stdlib_hare_unit_freebsd = $(stdlib_hare_unit_any)

# gen_lib hare::unparse (any)
stdlib_hare_unparse_any = $(HARECACHE)/hare/unparse/hare_unparse-any.o
stdlib_env += HARE_TD_hare::unparse=$(HARECACHE)/hare/unparse/hare_unparse.td
stdlib_deps_any += $(stdlib_hare_unparse_any)
stdlib_hare_unparse_linux = $(stdlib_hare_unparse_any)
stdlib_hare_unparse_freebsd = $(stdlib_hare_unparse_any)

# gen_lib hash (any)
stdlib_hash_any = $(HARECACHE)/hash/hash-any.o
stdlib_env += HARE_TD_hash=$(HARECACHE)/hash/hash.td
stdlib_deps_any += $(stdlib_hash_any)
stdlib_hash_linux = $(stdlib_hash_any)
stdlib_hash_freebsd = $(stdlib_hash_any)

# gen_lib hash::adler32 (any)
stdlib_hash_adler32_any = $(HARECACHE)/hash/adler32/hash_adler32-any.o
stdlib_env += HARE_TD_hash::adler32=$(HARECACHE)/hash/adler32/hash_adler32.td
stdlib_deps_any += $(stdlib_hash_adler32_any)
stdlib_hash_adler32_linux = $(stdlib_hash_adler32_any)
stdlib_hash_adler32_freebsd = $(stdlib_hash_adler32_any)

# gen_lib hash::crc16 (any)
stdlib_hash_crc16_any = $(HARECACHE)/hash/crc16/hash_crc16-any.o
stdlib_env += HARE_TD_hash::crc16=$(HARECACHE)/hash/crc16/hash_crc16.td
stdlib_deps_any += $(stdlib_hash_crc16_any)
stdlib_hash_crc16_linux = $(stdlib_hash_crc16_any)
stdlib_hash_crc16_freebsd = $(stdlib_hash_crc16_any)

# gen_lib hash::crc32 (any)
stdlib_hash_crc32_any = $(HARECACHE)/hash/crc32/hash_crc32-any.o
stdlib_env += HARE_TD_hash::crc32=$(HARECACHE)/hash/crc32/hash_crc32.td
stdlib_deps_any += $(stdlib_hash_crc32_any)
stdlib_hash_crc32_linux = $(stdlib_hash_crc32_any)
stdlib_hash_crc32_freebsd = $(stdlib_hash_crc32_any)

# gen_lib hash::crc64 (any)
stdlib_hash_crc64_any = $(HARECACHE)/hash/crc64/hash_crc64-any.o
stdlib_env += HARE_TD_hash::crc64=$(HARECACHE)/hash/crc64/hash_crc64.td
stdlib_deps_any += $(stdlib_hash_crc64_any)
stdlib_hash_crc64_linux = $(stdlib_hash_crc64_any)
stdlib_hash_crc64_freebsd = $(stdlib_hash_crc64_any)

# gen_lib hash::fnv (any)
stdlib_hash_fnv_any = $(HARECACHE)/hash/fnv/hash_fnv-any.o
stdlib_env += HARE_TD_hash::fnv=$(HARECACHE)/hash/fnv/hash_fnv.td
stdlib_deps_any += $(stdlib_hash_fnv_any)
stdlib_hash_fnv_linux = $(stdlib_hash_fnv_any)
stdlib_hash_fnv_freebsd = $(stdlib_hash_fnv_any)

# gen_lib hash::siphash (any)
stdlib_hash_siphash_any = $(HARECACHE)/hash/siphash/hash_siphash-any.o
stdlib_env += HARE_TD_hash::siphash=$(HARECACHE)/hash/siphash/hash_siphash.td
stdlib_deps_any += $(stdlib_hash_siphash_any)
stdlib_hash_siphash_linux = $(stdlib_hash_siphash_any)
stdlib_hash_siphash_freebsd = $(stdlib_hash_siphash_any)

# gen_lib io (linux)
stdlib_io_linux = $(HARECACHE)/io/io-linux.o
stdlib_env += HARE_TD_io=$(HARECACHE)/io/io.td
stdlib_deps_linux += $(stdlib_io_linux)

# gen_lib io (freebsd)
stdlib_io_freebsd = $(HARECACHE)/io/io-freebsd.o
stdlib_env += HARE_TD_io=$(HARECACHE)/io/io.td
stdlib_deps_freebsd += $(stdlib_io_freebsd)

# gen_lib linux (linux)
stdlib_linux_linux = $(HARECACHE)/linux/linux-linux.o
stdlib_env += HARE_TD_linux=$(HARECACHE)/linux/linux.td
stdlib_deps_linux += $(stdlib_linux_linux)

# gen_lib linux::keyctl (linux)
stdlib_linux_keyctl_linux = $(HARECACHE)/linux/keyctl/linux_keyctl-linux.o
stdlib_env += HARE_TD_linux::keyctl=$(HARECACHE)/linux/keyctl/linux_keyctl.td
stdlib_deps_linux += $(stdlib_linux_keyctl_linux)

# gen_lib linux::timerfd (linux)
stdlib_linux_timerfd_linux = $(HARECACHE)/linux/timerfd/linux_timerfd-linux.o
stdlib_env += HARE_TD_linux::timerfd=$(HARECACHE)/linux/timerfd/linux_timerfd.td
stdlib_deps_linux += $(stdlib_linux_timerfd_linux)

# gen_lib linux::vdso (linux)
stdlib_linux_vdso_linux = $(HARECACHE)/linux/vdso/linux_vdso-linux.o
stdlib_env += HARE_TD_linux::vdso=$(HARECACHE)/linux/vdso/linux_vdso.td
stdlib_deps_linux += $(stdlib_linux_vdso_linux)

# gen_lib log (linux)
stdlib_log_linux = $(HARECACHE)/log/log-linux.o
stdlib_env += HARE_TD_log=$(HARECACHE)/log/log.td
stdlib_deps_linux += $(stdlib_log_linux)

# gen_lib log (freebsd)
stdlib_log_freebsd = $(HARECACHE)/log/log-freebsd.o
stdlib_env += HARE_TD_log=$(HARECACHE)/log/log.td
stdlib_deps_freebsd += $(stdlib_log_freebsd)

# gen_lib math (any)
stdlib_math_any = $(HARECACHE)/math/math-any.o
stdlib_env += HARE_TD_math=$(HARECACHE)/math/math.td
stdlib_deps_any += $(stdlib_math_any)
stdlib_math_linux = $(stdlib_math_any)
stdlib_math_freebsd = $(stdlib_math_any)

# gen_lib math::complex (any)
stdlib_math_complex_any = $(HARECACHE)/math/complex/math_complex-any.o
stdlib_env += HARE_TD_math::complex=$(HARECACHE)/math/complex/math_complex.td
stdlib_deps_any += $(stdlib_math_complex_any)
stdlib_math_complex_linux = $(stdlib_math_complex_any)
stdlib_math_complex_freebsd = $(stdlib_math_complex_any)

# gen_lib math::random (any)
stdlib_math_random_any = $(HARECACHE)/math/random/math_random-any.o
stdlib_env += HARE_TD_math::random=$(HARECACHE)/math/random/math_random.td
stdlib_deps_any += $(stdlib_math_random_any)
stdlib_math_random_linux = $(stdlib_math_random_any)
stdlib_math_random_freebsd = $(stdlib_math_random_any)

# gen_lib net (linux)
stdlib_net_linux = $(HARECACHE)/net/net-linux.o
stdlib_env += HARE_TD_net=$(HARECACHE)/net/net.td
stdlib_deps_linux += $(stdlib_net_linux)

# gen_lib net (freebsd)
stdlib_net_freebsd = $(HARECACHE)/net/net-freebsd.o
stdlib_env += HARE_TD_net=$(HARECACHE)/net/net.td
stdlib_deps_freebsd += $(stdlib_net_freebsd)

# gen_lib net::dial (any)
stdlib_net_dial_any = $(HARECACHE)/net/dial/net_dial-any.o
stdlib_env += HARE_TD_net::dial=$(HARECACHE)/net/dial/net_dial.td
stdlib_deps_any += $(stdlib_net_dial_any)
stdlib_net_dial_linux = $(stdlib_net_dial_any)
stdlib_net_dial_freebsd = $(stdlib_net_dial_any)

# gen_lib net::dns (any)
stdlib_net_dns_any = $(HARECACHE)/net/dns/net_dns-any.o
stdlib_env += HARE_TD_net::dns=$(HARECACHE)/net/dns/net_dns.td
stdlib_deps_any += $(stdlib_net_dns_any)
stdlib_net_dns_linux = $(stdlib_net_dns_any)
stdlib_net_dns_freebsd = $(stdlib_net_dns_any)

# gen_lib net::ip (linux)
stdlib_net_ip_linux = $(HARECACHE)/net/ip/net_ip-linux.o
stdlib_env += HARE_TD_net::ip=$(HARECACHE)/net/ip/net_ip.td
stdlib_deps_linux += $(stdlib_net_ip_linux)

# gen_lib net::ip (freebsd)
stdlib_net_ip_freebsd = $(HARECACHE)/net/ip/net_ip-freebsd.o
stdlib_env += HARE_TD_net::ip=$(HARECACHE)/net/ip/net_ip.td
stdlib_deps_freebsd += $(stdlib_net_ip_freebsd)

# gen_lib net::tcp (linux)
stdlib_net_tcp_linux = $(HARECACHE)/net/tcp/net_tcp-linux.o
stdlib_env += HARE_TD_net::tcp=$(HARECACHE)/net/tcp/net_tcp.td
stdlib_deps_linux += $(stdlib_net_tcp_linux)

# gen_lib net::tcp (freebsd)
stdlib_net_tcp_freebsd = $(HARECACHE)/net/tcp/net_tcp-freebsd.o
stdlib_env += HARE_TD_net::tcp=$(HARECACHE)/net/tcp/net_tcp.td
stdlib_deps_freebsd += $(stdlib_net_tcp_freebsd)

# gen_lib net::udp (linux)
stdlib_net_udp_linux = $(HARECACHE)/net/udp/net_udp-linux.o
stdlib_env += HARE_TD_net::udp=$(HARECACHE)/net/udp/net_udp.td
stdlib_deps_linux += $(stdlib_net_udp_linux)

# gen_lib net::udp (freebsd)
stdlib_net_udp_freebsd = $(HARECACHE)/net/udp/net_udp-freebsd.o
stdlib_env += HARE_TD_net::udp=$(HARECACHE)/net/udp/net_udp.td
stdlib_deps_freebsd += $(stdlib_net_udp_freebsd)

# gen_lib net::unix (linux)
stdlib_net_unix_linux = $(HARECACHE)/net/unix/net_unix-linux.o
stdlib_env += HARE_TD_net::unix=$(HARECACHE)/net/unix/net_unix.td
stdlib_deps_linux += $(stdlib_net_unix_linux)

# gen_lib net::unix (freebsd)
stdlib_net_unix_freebsd = $(HARECACHE)/net/unix/net_unix-freebsd.o
stdlib_env += HARE_TD_net::unix=$(HARECACHE)/net/unix/net_unix.td
stdlib_deps_freebsd += $(stdlib_net_unix_freebsd)

# gen_lib net::uri (any)
stdlib_net_uri_any = $(HARECACHE)/net/uri/net_uri-any.o
stdlib_env += HARE_TD_net::uri=$(HARECACHE)/net/uri/net_uri.td
stdlib_deps_any += $(stdlib_net_uri_any)
stdlib_net_uri_linux = $(stdlib_net_uri_any)
stdlib_net_uri_freebsd = $(stdlib_net_uri_any)

# gen_lib os (linux)
stdlib_os_linux = $(HARECACHE)/os/os-linux.o
stdlib_env += HARE_TD_os=$(HARECACHE)/os/os.td
stdlib_deps_linux += $(stdlib_os_linux)

# gen_lib os (freebsd)
stdlib_os_freebsd = $(HARECACHE)/os/os-freebsd.o
stdlib_env += HARE_TD_os=$(HARECACHE)/os/os.td
stdlib_deps_freebsd += $(stdlib_os_freebsd)

# gen_lib os::exec (linux)
stdlib_os_exec_linux = $(HARECACHE)/os/exec/os_exec-linux.o
stdlib_env += HARE_TD_os::exec=$(HARECACHE)/os/exec/os_exec.td
stdlib_deps_linux += $(stdlib_os_exec_linux)

# gen_lib os::exec (freebsd)
stdlib_os_exec_freebsd = $(HARECACHE)/os/exec/os_exec-freebsd.o
stdlib_env += HARE_TD_os::exec=$(HARECACHE)/os/exec/os_exec.td
stdlib_deps_freebsd += $(stdlib_os_exec_freebsd)

# gen_lib path (any)
stdlib_path_any = $(HARECACHE)/path/path-any.o
stdlib_env += HARE_TD_path=$(HARECACHE)/path/path.td
stdlib_deps_any += $(stdlib_path_any)
stdlib_path_linux = $(stdlib_path_any)
stdlib_path_freebsd = $(stdlib_path_any)

# gen_lib regex (any)
stdlib_regex_any = $(HARECACHE)/regex/regex-any.o
stdlib_env += HARE_TD_regex=$(HARECACHE)/regex/regex.td
stdlib_deps_any += $(stdlib_regex_any)
stdlib_regex_linux = $(stdlib_regex_any)
stdlib_regex_freebsd = $(stdlib_regex_any)

# gen_lib shlex (any)
stdlib_shlex_any = $(HARECACHE)/shlex/shlex-any.o
stdlib_env += HARE_TD_shlex=$(HARECACHE)/shlex/shlex.td
stdlib_deps_any += $(stdlib_shlex_any)
stdlib_shlex_linux = $(stdlib_shlex_any)
stdlib_shlex_freebsd = $(stdlib_shlex_any)

# gen_lib slices (any)
stdlib_slices_any = $(HARECACHE)/slices/slices-any.o
stdlib_env += HARE_TD_slices=$(HARECACHE)/slices/slices.td
stdlib_deps_any += $(stdlib_slices_any)
stdlib_slices_linux = $(stdlib_slices_any)
stdlib_slices_freebsd = $(stdlib_slices_any)

# gen_lib sort (any)
stdlib_sort_any = $(HARECACHE)/sort/sort-any.o
stdlib_env += HARE_TD_sort=$(HARECACHE)/sort/sort.td
stdlib_deps_any += $(stdlib_sort_any)
stdlib_sort_linux = $(stdlib_sort_any)
stdlib_sort_freebsd = $(stdlib_sort_any)

# gen_lib strconv (any)
stdlib_strconv_any = $(HARECACHE)/strconv/strconv-any.o
stdlib_env += HARE_TD_strconv=$(HARECACHE)/strconv/strconv.td
stdlib_deps_any += $(stdlib_strconv_any)
stdlib_strconv_linux = $(stdlib_strconv_any)
stdlib_strconv_freebsd = $(stdlib_strconv_any)

# gen_lib strings (any)
stdlib_strings_any = $(HARECACHE)/strings/strings-any.o
stdlib_env += HARE_TD_strings=$(HARECACHE)/strings/strings.td
stdlib_deps_any += $(stdlib_strings_any)
stdlib_strings_linux = $(stdlib_strings_any)
stdlib_strings_freebsd = $(stdlib_strings_any)

# gen_lib strings::template (any)
stdlib_strings_template_any = $(HARECACHE)/strings/template/strings_template-any.o
stdlib_env += HARE_TD_strings::template=$(HARECACHE)/strings/template/strings_template.td
stdlib_deps_any += $(stdlib_strings_template_any)
stdlib_strings_template_linux = $(stdlib_strings_template_any)
stdlib_strings_template_freebsd = $(stdlib_strings_template_any)

# gen_lib strio (any)
stdlib_strio_any = $(HARECACHE)/strio/strio-any.o
stdlib_env += HARE_TD_strio=$(HARECACHE)/strio/strio.td
stdlib_deps_any += $(stdlib_strio_any)
stdlib_strio_linux = $(stdlib_strio_any)
stdlib_strio_freebsd = $(stdlib_strio_any)

# gen_lib temp (linux)
stdlib_temp_linux = $(HARECACHE)/temp/temp-linux.o
stdlib_env += HARE_TD_temp=$(HARECACHE)/temp/temp.td
stdlib_deps_linux += $(stdlib_temp_linux)

# gen_lib temp (freebsd)
stdlib_temp_freebsd = $(HARECACHE)/temp/temp-freebsd.o
stdlib_env += HARE_TD_temp=$(HARECACHE)/temp/temp.td
stdlib_deps_freebsd += $(stdlib_temp_freebsd)

# gen_lib test (any)
stdlib_test_any = $(HARECACHE)/test/test-any.o
stdlib_env += HARE_TD_test=$(HARECACHE)/test/test.td
stdlib_deps_any += $(stdlib_test_any)
stdlib_test_linux = $(stdlib_test_any)
stdlib_test_freebsd = $(stdlib_test_any)

# gen_lib time (linux)
stdlib_time_linux = $(HARECACHE)/time/time-linux.o
stdlib_env += HARE_TD_time=$(HARECACHE)/time/time.td
stdlib_deps_linux += $(stdlib_time_linux)

# gen_lib time (freebsd)
stdlib_time_freebsd = $(HARECACHE)/time/time-freebsd.o
stdlib_env += HARE_TD_time=$(HARECACHE)/time/time.td
stdlib_deps_freebsd += $(stdlib_time_freebsd)

# gen_lib time::chrono (linux)
stdlib_time_chrono_linux = $(HARECACHE)/time/chrono/time_chrono-linux.o
stdlib_env += HARE_TD_time::chrono=$(HARECACHE)/time/chrono/time_chrono.td
stdlib_deps_linux += $(stdlib_time_chrono_linux)

# gen_lib time::chrono (freebsd)
stdlib_time_chrono_freebsd = $(HARECACHE)/time/chrono/time_chrono-freebsd.o
stdlib_env += HARE_TD_time::chrono=$(HARECACHE)/time/chrono/time_chrono.td
stdlib_deps_freebsd += $(stdlib_time_chrono_freebsd)

# gen_lib types (any)
stdlib_types_any = $(HARECACHE)/types/types-any.o
stdlib_env += HARE_TD_types=$(HARECACHE)/types/types.td
stdlib_deps_any += $(stdlib_types_any)
stdlib_types_linux = $(stdlib_types_any)
stdlib_types_freebsd = $(stdlib_types_any)

# gen_lib types::c (any)
stdlib_types_c_any = $(HARECACHE)/types/c/types_c-any.o
stdlib_env += HARE_TD_types::c=$(HARECACHE)/types/c/types_c.td
stdlib_deps_any += $(stdlib_types_c_any)
stdlib_types_c_linux = $(stdlib_types_c_any)
stdlib_types_c_freebsd = $(stdlib_types_c_any)

# gen_lib unix (linux)
stdlib_unix_linux = $(HARECACHE)/unix/unix-linux.o
stdlib_env += HARE_TD_unix=$(HARECACHE)/unix/unix.td
stdlib_deps_linux += $(stdlib_unix_linux)

# gen_lib unix (freebsd)
stdlib_unix_freebsd = $(HARECACHE)/unix/unix-freebsd.o
stdlib_env += HARE_TD_unix=$(HARECACHE)/unix/unix.td
stdlib_deps_freebsd += $(stdlib_unix_freebsd)

# gen_lib unix::hosts (linux)
stdlib_unix_hosts_linux = $(HARECACHE)/unix/hosts/unix_hosts-linux.o
stdlib_env += HARE_TD_unix::hosts=$(HARECACHE)/unix/hosts/unix_hosts.td
stdlib_deps_linux += $(stdlib_unix_hosts_linux)

# gen_lib unix::hosts (freebsd)
stdlib_unix_hosts_freebsd = $(HARECACHE)/unix/hosts/unix_hosts-freebsd.o
stdlib_env += HARE_TD_unix::hosts=$(HARECACHE)/unix/hosts/unix_hosts.td
stdlib_deps_freebsd += $(stdlib_unix_hosts_freebsd)

# gen_lib unix::passwd (any)
stdlib_unix_passwd_any = $(HARECACHE)/unix/passwd/unix_passwd-any.o
stdlib_env += HARE_TD_unix::passwd=$(HARECACHE)/unix/passwd/unix_passwd.td
stdlib_deps_any += $(stdlib_unix_passwd_any)
stdlib_unix_passwd_linux = $(stdlib_unix_passwd_any)
stdlib_unix_passwd_freebsd = $(stdlib_unix_passwd_any)

# gen_lib unix::poll (linux)
stdlib_unix_poll_linux = $(HARECACHE)/unix/poll/unix_poll-linux.o
stdlib_env += HARE_TD_unix::poll=$(HARECACHE)/unix/poll/unix_poll.td
stdlib_deps_linux += $(stdlib_unix_poll_linux)

# gen_lib unix::poll (freebsd)
stdlib_unix_poll_freebsd = $(HARECACHE)/unix/poll/unix_poll-freebsd.o
stdlib_env += HARE_TD_unix::poll=$(HARECACHE)/unix/poll/unix_poll.td
stdlib_deps_freebsd += $(stdlib_unix_poll_freebsd)

# gen_lib unix::resolvconf (linux)
stdlib_unix_resolvconf_linux = $(HARECACHE)/unix/resolvconf/unix_resolvconf-linux.o
stdlib_env += HARE_TD_unix::resolvconf=$(HARECACHE)/unix/resolvconf/unix_resolvconf.td
stdlib_deps_linux += $(stdlib_unix_resolvconf_linux)

# gen_lib unix::resolvconf (freebsd)
stdlib_unix_resolvconf_freebsd = $(HARECACHE)/unix/resolvconf/unix_resolvconf-freebsd.o
stdlib_env += HARE_TD_unix::resolvconf=$(HARECACHE)/unix/resolvconf/unix_resolvconf.td
stdlib_deps_freebsd += $(stdlib_unix_resolvconf_freebsd)

# gen_lib unix::signal (linux)
stdlib_unix_signal_linux = $(HARECACHE)/unix/signal/unix_signal-linux.o
stdlib_env += HARE_TD_unix::signal=$(HARECACHE)/unix/signal/unix_signal.td
stdlib_deps_linux += $(stdlib_unix_signal_linux)

# gen_lib unix::signal (freebsd)
stdlib_unix_signal_freebsd = $(HARECACHE)/unix/signal/unix_signal-freebsd.o
stdlib_env += HARE_TD_unix::signal=$(HARECACHE)/unix/signal/unix_signal.td
stdlib_deps_freebsd += $(stdlib_unix_signal_freebsd)

# gen_lib unix::tty (linux)
stdlib_unix_tty_linux = $(HARECACHE)/unix/tty/unix_tty-linux.o
stdlib_env += HARE_TD_unix::tty=$(HARECACHE)/unix/tty/unix_tty.td
stdlib_deps_linux += $(stdlib_unix_tty_linux)

# gen_lib unix::tty (freebsd)
stdlib_unix_tty_freebsd = $(HARECACHE)/unix/tty/unix_tty-freebsd.o
stdlib_env += HARE_TD_unix::tty=$(HARECACHE)/unix/tty/unix_tty.td
stdlib_deps_freebsd += $(stdlib_unix_tty_freebsd)

# gen_lib uuid (any)
stdlib_uuid_any = $(HARECACHE)/uuid/uuid-any.o
stdlib_env += HARE_TD_uuid=$(HARECACHE)/uuid/uuid.td
stdlib_deps_any += $(stdlib_uuid_any)
stdlib_uuid_linux = $(stdlib_uuid_any)
stdlib_uuid_freebsd = $(stdlib_uuid_any)

# ascii (+any)
stdlib_ascii_any_srcs = \
	$(STDLIB)/ascii/ctype.ha \
	$(STDLIB)/ascii/string.ha \
	$(STDLIB)/ascii/valid.ha

$(HARECACHE)/ascii/ascii-any.ssa: $(stdlib_ascii_any_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/ascii
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nascii \
		-t$(HARECACHE)/ascii/ascii.td $(stdlib_ascii_any_srcs)

# bufio (+any)
stdlib_bufio_any_srcs = \
	$(STDLIB)/bufio/buffered.ha \
	$(STDLIB)/bufio/memstream.ha \
	$(STDLIB)/bufio/scanner.ha

$(HARECACHE)/bufio/bufio-any.ssa: $(stdlib_bufio_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/bufio
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nbufio \
		-t$(HARECACHE)/bufio/bufio.td $(stdlib_bufio_any_srcs)

# bytes (+any)
stdlib_bytes_any_srcs = \
	$(STDLIB)/bytes/contains.ha \
	$(STDLIB)/bytes/equal.ha \
	$(STDLIB)/bytes/index.ha \
	$(STDLIB)/bytes/reverse.ha \
	$(STDLIB)/bytes/tokenize.ha \
	$(STDLIB)/bytes/trim.ha \
	$(STDLIB)/bytes/two_way.ha \
	$(STDLIB)/bytes/zero.ha

$(HARECACHE)/bytes/bytes-any.ssa: $(stdlib_bytes_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/bytes
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nbytes \
		-t$(HARECACHE)/bytes/bytes.td $(stdlib_bytes_any_srcs)

# crypto (+any)
stdlib_crypto_any_srcs = \
	$(STDLIB)/crypto/authenc.ha \
	$(STDLIB)/crypto/keyderiv.ha

$(HARECACHE)/crypto/crypto-any.ssa: $(stdlib_crypto_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_argon2_$(PLATFORM)) $(stdlib_crypto_chacha_$(PLATFORM)) $(stdlib_crypto_cihper_$(PLATFORM)) $(stdlib_crypto_poly1305_$(PLATFORM)) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto \
		-t$(HARECACHE)/crypto/crypto.td $(stdlib_crypto_any_srcs)

# crypto::aes (+any)
stdlib_crypto_aes_any_srcs = \
	$(STDLIB)/crypto/aes/aes.ha \
	$(STDLIB)/crypto/aes/aes_ct64.ha \
	$(STDLIB)/crypto/aes/block.ha

$(HARECACHE)/crypto/aes/crypto_aes-any.ssa: $(stdlib_crypto_aes_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/aes
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::aes \
		-t$(HARECACHE)/crypto/aes/crypto_aes.td $(stdlib_crypto_aes_any_srcs)

# crypto::aes::xts (+any)
stdlib_crypto_aes_xts_any_srcs = \
	$(STDLIB)/crypto/aes/xts/xts.ha

$(HARECACHE)/crypto/aes/xts/crypto_aes_xts-any.ssa: $(stdlib_crypto_aes_xts_any_srcs) $(stdlib_rt) $(stdlib_crypto_aes_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/aes/xts
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::aes::xts \
		-t$(HARECACHE)/crypto/aes/xts/crypto_aes_xts.td $(stdlib_crypto_aes_xts_any_srcs)

# crypto::argon2 (+any)
stdlib_crypto_argon2_any_srcs = \
	$(STDLIB)/crypto/argon2/argon2.ha

$(HARECACHE)/crypto/argon2/crypto_argon2-any.ssa: $(stdlib_crypto_argon2_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_blake2b_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/argon2
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::argon2 \
		-t$(HARECACHE)/crypto/argon2/crypto_argon2.td $(stdlib_crypto_argon2_any_srcs)

# crypto::bcrypt (+any)
stdlib_crypto_bcrypt_any_srcs = \
	$(STDLIB)/crypto/bcrypt/bcrypt.ha \
	$(STDLIB)/crypto/bcrypt/base64.ha

$(HARECACHE)/crypto/bcrypt/crypto_bcrypt-any.ssa: $(stdlib_crypto_bcrypt_any_srcs) $(stdlib_rt) $(stdlib_crypto_blowfish_$(PLATFORM)) $(stdlib_encoding_base64_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_crypto_$(PLATFORM)) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/bcrypt
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::bcrypt \
		-t$(HARECACHE)/crypto/bcrypt/crypto_bcrypt.td $(stdlib_crypto_bcrypt_any_srcs)

# crypto::blake2b (+any)
stdlib_crypto_blake2b_any_srcs = \
	$(STDLIB)/crypto/blake2b/blake2b.ha

$(HARECACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(stdlib_crypto_blake2b_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/blake2b
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::blake2b \
		-t$(HARECACHE)/crypto/blake2b/crypto_blake2b.td $(stdlib_crypto_blake2b_any_srcs)

# crypto::blowfish (+any)
stdlib_crypto_blowfish_any_srcs = \
	$(STDLIB)/crypto/blowfish/blowfish.ha \
	$(STDLIB)/crypto/blowfish/const.ha

$(HARECACHE)/crypto/blowfish/crypto_blowfish-any.ssa: $(stdlib_crypto_blowfish_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_endian_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/blowfish
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::blowfish \
		-t$(HARECACHE)/crypto/blowfish/crypto_blowfish.td $(stdlib_crypto_blowfish_any_srcs)

# crypto::bigint (+any)
stdlib_crypto_bigint_any_srcs = \
	$(STDLIB)/crypto/bigint/arithm.ha \
	$(STDLIB)/crypto/bigint/encoding.ha \
	$(STDLIB)/crypto/bigint/monty.ha \
	$(STDLIB)/crypto/bigint/types.ha \
	$(STDLIB)/crypto/bigint/util.ha

$(HARECACHE)/crypto/bigint/crypto_bigint-any.ssa: $(stdlib_crypto_bigint_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/bigint
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::bigint \
		-t$(HARECACHE)/crypto/bigint/crypto_bigint.td $(stdlib_crypto_bigint_any_srcs)

# crypto::chacha (+any)
stdlib_crypto_chacha_any_srcs = \
	$(STDLIB)/crypto/chacha/chacha20.ha

$(HARECACHE)/crypto/chacha/crypto_chacha-any.ssa: $(stdlib_crypto_chacha_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/chacha
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::chacha \
		-t$(HARECACHE)/crypto/chacha/crypto_chacha.td $(stdlib_crypto_chacha_any_srcs)

# crypto::cipher (+any)
stdlib_crypto_cipher_any_srcs = \
	$(STDLIB)/crypto/cipher/cipher.ha \
	$(STDLIB)/crypto/cipher/block.ha \
	$(STDLIB)/crypto/cipher/cbc.ha \
	$(STDLIB)/crypto/cipher/ctr.ha \
	$(STDLIB)/crypto/cipher/stream.ha \
	$(STDLIB)/crypto/cipher/gcm.ha \
	$(STDLIB)/crypto/cipher/ghash.ha

$(HARECACHE)/crypto/cipher/crypto_cipher-any.ssa: $(stdlib_crypto_cipher_any_srcs) $(stdlib_rt) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/cipher
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::cipher \
		-t$(HARECACHE)/crypto/cipher/crypto_cipher.td $(stdlib_crypto_cipher_any_srcs)

# crypto::hkdf (+any)
stdlib_crypto_hkdf_any_srcs = \
	$(STDLIB)/crypto/hkdf/hkdf.ha

$(HARECACHE)/crypto/hkdf/crypto_hkdf-any.ssa: $(stdlib_crypto_hkdf_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_hmac_$(PLATFORM)) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_hash_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/hkdf
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::hkdf \
		-t$(HARECACHE)/crypto/hkdf/crypto_hkdf.td $(stdlib_crypto_hkdf_any_srcs)

# crypto::hmac (+any)
stdlib_crypto_hmac_any_srcs = \
	$(STDLIB)/crypto/hmac/hmac.ha \
	$(STDLIB)/crypto/hmac/sha1.ha \
	$(STDLIB)/crypto/hmac/sha256.ha

$(HARECACHE)/crypto/hmac/crypto_hmac-any.ssa: $(stdlib_crypto_hmac_any_srcs) $(stdlib_rt) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_crypto_sha1_$(PLATFORM)) $(stdlib_crypto_sha256_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/hmac
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::hmac \
		-t$(HARECACHE)/crypto/hmac/crypto_hmac.td $(stdlib_crypto_hmac_any_srcs)

# crypto::mac (+any)
stdlib_crypto_mac_any_srcs = \
	$(STDLIB)/crypto/mac/mac.ha

$(HARECACHE)/crypto/mac/crypto_mac-any.ssa: $(stdlib_crypto_mac_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/mac
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::mac \
		-t$(HARECACHE)/crypto/mac/crypto_mac.td $(stdlib_crypto_mac_any_srcs)

# crypto::math (+any)
stdlib_crypto_math_any_srcs = \
	$(STDLIB)/crypto/math/arithm.ha \
	$(STDLIB)/crypto/math/bits.ha

$(HARECACHE)/crypto/math/crypto_math-any.ssa: $(stdlib_crypto_math_any_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/math
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::math \
		-t$(HARECACHE)/crypto/math/crypto_math.td $(stdlib_crypto_math_any_srcs)

# crypto::random (+linux)
stdlib_crypto_random_linux_srcs = \
	$(STDLIB)/crypto/random/+linux.ha \
	$(STDLIB)/crypto/random/random.ha

$(HARECACHE)/crypto/random/crypto_random-linux.ssa: $(stdlib_crypto_random_linux_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/random
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::random \
		-t$(HARECACHE)/crypto/random/crypto_random.td $(stdlib_crypto_random_linux_srcs)

# crypto::random (+freebsd)
stdlib_crypto_random_freebsd_srcs = \
	$(STDLIB)/crypto/random/+freebsd.ha \
	$(STDLIB)/crypto/random/random.ha

$(HARECACHE)/crypto/random/crypto_random-freebsd.ssa: $(stdlib_crypto_random_freebsd_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/random
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::random \
		-t$(HARECACHE)/crypto/random/crypto_random.td $(stdlib_crypto_random_freebsd_srcs)

# crypto::rsa (+any)
stdlib_crypto_rsa_any_srcs = \
	$(STDLIB)/crypto/rsa/core.ha \
	$(STDLIB)/crypto/rsa/errors.ha \
	$(STDLIB)/crypto/rsa/keys.ha \
	$(STDLIB)/crypto/rsa/pkcs1.ha

$(HARECACHE)/crypto/rsa/crypto_rsa-any.ssa: $(stdlib_crypto_rsa_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_bigint_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_crypto_sha1_$(PLATFORM)) $(stdlib_crypto_sha256_$(PLATFORM)) $(stdlib_crypto_sha512_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/rsa
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::rsa \
		-t$(HARECACHE)/crypto/rsa/crypto_rsa.td $(stdlib_crypto_rsa_any_srcs)

# crypto::poly1305 (+any)
stdlib_crypto_poly1305_any_srcs = \
	$(STDLIB)/crypto/poly1305/poly1305.ha

$(HARECACHE)/crypto/poly1305/crypto_poly1305-any.ssa: $(stdlib_crypto_poly1305_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/poly1305
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::poly1305 \
		-t$(HARECACHE)/crypto/poly1305/crypto_poly1305.td $(stdlib_crypto_poly1305_any_srcs)

# crypto::salsa (+any)
stdlib_crypto_salsa_any_srcs = \
	$(STDLIB)/crypto/salsa/salsa20.ha

$(HARECACHE)/crypto/salsa/crypto_salsa-any.ssa: $(stdlib_crypto_salsa_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_cipher_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_io_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/salsa
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::salsa \
		-t$(HARECACHE)/crypto/salsa/crypto_salsa.td $(stdlib_crypto_salsa_any_srcs)

# crypto::sha1 (+any)
stdlib_crypto_sha1_any_srcs = \
	$(STDLIB)/crypto/sha1/sha1.ha

$(HARECACHE)/crypto/sha1/crypto_sha1-any.ssa: $(stdlib_crypto_sha1_any_srcs) $(stdlib_rt) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/sha1
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha1 \
		-t$(HARECACHE)/crypto/sha1/crypto_sha1.td $(stdlib_crypto_sha1_any_srcs)

# crypto::sha256 (+any)
stdlib_crypto_sha256_any_srcs = \
	$(STDLIB)/crypto/sha256/sha256.ha

$(HARECACHE)/crypto/sha256/crypto_sha256-any.ssa: $(stdlib_crypto_sha256_any_srcs) $(stdlib_rt) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/sha256
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha256 \
		-t$(HARECACHE)/crypto/sha256/crypto_sha256.td $(stdlib_crypto_sha256_any_srcs)

# crypto::sha512 (+any)
stdlib_crypto_sha512_any_srcs = \
	$(STDLIB)/crypto/sha512/sha512.ha

$(HARECACHE)/crypto/sha512/crypto_sha512-any.ssa: $(stdlib_crypto_sha512_any_srcs) $(stdlib_rt) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/sha512
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha512 \
		-t$(HARECACHE)/crypto/sha512/crypto_sha512.td $(stdlib_crypto_sha512_any_srcs)

# crypto::curve25519 (+any)
stdlib_crypto_curve25519_any_srcs = \
	$(STDLIB)/crypto/curve25519/curve25519.ha

$(HARECACHE)/crypto/curve25519/crypto_curve25519-any.ssa: $(stdlib_crypto_curve25519_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/curve25519
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::curve25519 \
		-t$(HARECACHE)/crypto/curve25519/crypto_curve25519.td $(stdlib_crypto_curve25519_any_srcs)

# crypto::ed25519 (+any)
stdlib_crypto_ed25519_any_srcs = \
	$(STDLIB)/crypto/ed25519/ed25519.ha \
	$(STDLIB)/crypto/ed25519/edwards25519.ha

$(HARECACHE)/crypto/ed25519/crypto_ed25519-any.ssa: $(stdlib_crypto_ed25519_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_crypto_sha512_$(PLATFORM)) $(stdlib_hash_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/ed25519
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::ed25519 \
		-t$(HARECACHE)/crypto/ed25519/crypto_ed25519.td $(stdlib_crypto_ed25519_any_srcs)

# crypto::x25519 (+any)
stdlib_crypto_x25519_any_srcs = \
	$(STDLIB)/crypto/x25519/x25519.ha

$(HARECACHE)/crypto/x25519/crypto_x25519-any.ssa: $(stdlib_crypto_x25519_any_srcs) $(stdlib_rt) $(stdlib_crypto_curve25519_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/crypto/x25519
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::x25519 \
		-t$(HARECACHE)/crypto/x25519/crypto_x25519.td $(stdlib_crypto_x25519_any_srcs)

# datetime (+linux)
stdlib_datetime_linux_srcs = \
	$(STDLIB)/datetime/arithmetic.ha \
	$(STDLIB)/datetime/chronology.ha \
	$(STDLIB)/datetime/errors.ha \
	$(STDLIB)/datetime/date.ha \
	$(STDLIB)/datetime/datetime.ha \
	$(STDLIB)/datetime/duration.ha \
	$(STDLIB)/datetime/format.ha \
	$(STDLIB)/datetime/parse.ha \
	$(STDLIB)/datetime/period.ha \
	$(STDLIB)/datetime/reckon.ha \
	$(STDLIB)/datetime/time.ha \
	$(STDLIB)/datetime/timezone.ha \
	$(STDLIB)/datetime/virtual.ha

$(HARECACHE)/datetime/datetime-linux.ssa: $(stdlib_datetime_linux_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_time_chrono_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/datetime
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ndatetime \
		-t$(HARECACHE)/datetime/datetime.td $(stdlib_datetime_linux_srcs)

# datetime (+freebsd)
stdlib_datetime_freebsd_srcs = \
	$(STDLIB)/datetime/arithmetic.ha \
	$(STDLIB)/datetime/chronology.ha \
	$(STDLIB)/datetime/errors.ha \
	$(STDLIB)/datetime/date.ha \
	$(STDLIB)/datetime/datetime.ha \
	$(STDLIB)/datetime/duration.ha \
	$(STDLIB)/datetime/format.ha \
	$(STDLIB)/datetime/parse.ha \
	$(STDLIB)/datetime/period.ha \
	$(STDLIB)/datetime/reckon.ha \
	$(STDLIB)/datetime/time.ha \
	$(STDLIB)/datetime/timezone.ha \
	$(STDLIB)/datetime/virtual.ha

$(HARECACHE)/datetime/datetime-freebsd.ssa: $(stdlib_datetime_freebsd_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_time_chrono_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/datetime
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ndatetime \
		-t$(HARECACHE)/datetime/datetime.td $(stdlib_datetime_freebsd_srcs)

# dirs (+any)
stdlib_dirs_any_srcs = \
	$(STDLIB)/dirs/xdg.ha

$(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_unix_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/dirs
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ndirs \
		-t$(HARECACHE)/dirs/dirs.td $(stdlib_dirs_any_srcs)

# encoding::base64 (+any)
stdlib_encoding_base64_any_srcs = \
	$(STDLIB)/encoding/base64/base64.ha

$(HARECACHE)/encoding/base64/encoding_base64-any.ssa: $(stdlib_encoding_base64_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/encoding/base64
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::base64 \
		-t$(HARECACHE)/encoding/base64/encoding_base64.td $(stdlib_encoding_base64_any_srcs)

# encoding::base32 (+any)
stdlib_encoding_base32_any_srcs = \
	$(STDLIB)/encoding/base32/base32.ha

$(HARECACHE)/encoding/base32/encoding_base32-any.ssa: $(stdlib_encoding_base32_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_os_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/encoding/base32
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::base32 \
		-t$(HARECACHE)/encoding/base32/encoding_base32.td $(stdlib_encoding_base32_any_srcs)

# encoding::hex (+any)
stdlib_encoding_hex_any_srcs = \
	$(STDLIB)/encoding/hex/hex.ha

$(HARECACHE)/encoding/hex/encoding_hex-any.ssa: $(stdlib_encoding_hex_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/encoding/hex
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::hex \
		-t$(HARECACHE)/encoding/hex/encoding_hex.td $(stdlib_encoding_hex_any_srcs)

# encoding::pem (+any)
stdlib_encoding_pem_any_srcs = \
	$(STDLIB)/encoding/pem/pem.ha

$(HARECACHE)/encoding/pem/encoding_pem-any.ssa: $(stdlib_encoding_pem_any_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_encoding_base64_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/encoding/pem
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::pem \
		-t$(HARECACHE)/encoding/pem/encoding_pem.td $(stdlib_encoding_pem_any_srcs)

# encoding::utf8 (+any)
stdlib_encoding_utf8_any_srcs = \
	$(STDLIB)/encoding/utf8/decode.ha \
	$(STDLIB)/encoding/utf8/decodetable.ha \
	$(STDLIB)/encoding/utf8/encode.ha \
	$(STDLIB)/encoding/utf8/rune.ha

$(HARECACHE)/encoding/utf8/encoding_utf8-any.ssa: $(stdlib_encoding_utf8_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/encoding/utf8
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::utf8 \
		-t$(HARECACHE)/encoding/utf8/encoding_utf8.td $(stdlib_encoding_utf8_any_srcs)

# endian (+any)
stdlib_endian_any_srcs = \
	$(STDLIB)/endian/big.ha \
	$(STDLIB)/endian/network.ha \
	$(STDLIB)/endian/little.ha \
	$(STDLIB)/endian/endian.ha \
	$(STDLIB)/endian/host+$(ARCH).ha

$(HARECACHE)/endian/endian-any.ssa: $(stdlib_endian_any_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/endian
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nendian \
		-t$(HARECACHE)/endian/endian.td $(stdlib_endian_any_srcs)

# errors (+any)
stdlib_errors_any_srcs = \
	$(STDLIB)/errors/common.ha \
	$(STDLIB)/errors/opaque.ha \
	$(STDLIB)/errors/string.ha \
	$(STDLIB)/errors/rt.ha

$(HARECACHE)/errors/errors-any.ssa: $(stdlib_errors_any_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/errors
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nerrors \
		-t$(HARECACHE)/errors/errors.td $(stdlib_errors_any_srcs)

# fmt (+any)
stdlib_fmt_any_srcs = \
	$(STDLIB)/fmt/fmt.ha

$(HARECACHE)/fmt/fmt-any.ssa: $(stdlib_fmt_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/fmt
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nfmt \
		-t$(HARECACHE)/fmt/fmt.td $(stdlib_fmt_any_srcs)

# fnmatch (+any)
stdlib_fnmatch_any_srcs = \
	$(STDLIB)/fnmatch/fnmatch.ha

$(HARECACHE)/fnmatch/fnmatch-any.ssa: $(stdlib_fnmatch_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_sort_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/fnmatch
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nfnmatch \
		-t$(HARECACHE)/fnmatch/fnmatch.td $(stdlib_fnmatch_any_srcs)

# format::elf (+any)
stdlib_format_elf_any_srcs = \
	$(STDLIB)/format/elf/arch+$(ARCH).ha \
	$(STDLIB)/format/elf/platform+$(PLATFORM).ha \
	$(STDLIB)/format/elf/types.ha

$(HARECACHE)/format/elf/format_elf-any.ssa: $(stdlib_format_elf_any_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/format/elf
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nformat::elf \
		-t$(HARECACHE)/format/elf/format_elf.td $(stdlib_format_elf_any_srcs)

# format::ini (+any)
stdlib_format_ini_any_srcs = \
	$(STDLIB)/format/ini/scan.ha \
	$(STDLIB)/format/ini/types.ha

$(HARECACHE)/format/ini/format_ini-any.ssa: $(stdlib_format_ini_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/format/ini
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nformat::ini \
		-t$(HARECACHE)/format/ini/format_ini.td $(stdlib_format_ini_any_srcs)

# format::tar (+any)
stdlib_format_tar_any_srcs = \
	$(STDLIB)/format/tar/types.ha \
	$(STDLIB)/format/tar/reader.ha

$(HARECACHE)/format/tar/format_tar-any.ssa: $(stdlib_format_tar_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_types_c_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/format/tar
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nformat::tar \
		-t$(HARECACHE)/format/tar/format_tar.td $(stdlib_format_tar_any_srcs)

# fs (+any)
stdlib_fs_any_srcs = \
	$(STDLIB)/fs/types.ha \
	$(STDLIB)/fs/fs.ha \
	$(STDLIB)/fs/util.ha

$(HARECACHE)/fs/fs-any.ssa: $(stdlib_fs_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_errors_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/fs
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nfs \
		-t$(HARECACHE)/fs/fs.td $(stdlib_fs_any_srcs)

# getopt (+any)
stdlib_getopt_any_srcs = \
	$(STDLIB)/getopt/getopts.ha

$(HARECACHE)/getopt/getopt-any.ssa: $(stdlib_getopt_any_srcs) $(stdlib_rt) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/getopt
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Ngetopt \
		-t$(HARECACHE)/getopt/getopt.td $(stdlib_getopt_any_srcs)

# glob (+any)
stdlib_glob_any_srcs = \
	$(STDLIB)/glob/glob.ha

$(HARECACHE)/glob/glob-any.ssa: $(stdlib_glob_any_srcs) $(stdlib_rt) $(stdlib_fnmatch_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/glob
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nglob \
		-t$(HARECACHE)/glob/glob.td $(stdlib_glob_any_srcs)

# hare::ast (+any)
stdlib_hare_ast_any_srcs = \
	$(STDLIB)/hare/ast/decl.ha \
	$(STDLIB)/hare/ast/expr.ha \
	$(STDLIB)/hare/ast/ident.ha \
	$(STDLIB)/hare/ast/import.ha \
	$(STDLIB)/hare/ast/type.ha \
	$(STDLIB)/hare/ast/unit.ha

$(HARECACHE)/hare/ast/hare_ast-any.ssa: $(stdlib_hare_ast_any_srcs) $(stdlib_rt) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/ast
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::ast \
		-t$(HARECACHE)/hare/ast/hare_ast.td $(stdlib_hare_ast_any_srcs)

# hare::lex (+any)
stdlib_hare_lex_any_srcs = \
	$(STDLIB)/hare/lex/token.ha \
	$(STDLIB)/hare/lex/lex.ha

$(HARECACHE)/hare/lex/hare_lex-any.ssa: $(stdlib_hare_lex_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_path_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/lex
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::lex \
		-t$(HARECACHE)/hare/lex/hare_lex.td $(stdlib_hare_lex_any_srcs)

# hare::module (+any)
stdlib_hare_module_any_srcs = \
	$(STDLIB)/hare/module/types.ha \
	$(STDLIB)/hare/module/context.ha \
	$(STDLIB)/hare/module/scan.ha \
	$(STDLIB)/hare/module/manifest.ha \
	$(STDLIB)/hare/module/walk.ha

$(HARECACHE)/hare/module/hare_module-any.ssa: $(stdlib_hare_module_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_hare_parse_$(PLATFORM)) $(stdlib_hare_unparse_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_crypto_sha256_$(PLATFORM)) $(stdlib_dirs_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_hex_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_temp_$(PLATFORM)) $(stdlib_path_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/module
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::module \
		-t$(HARECACHE)/hare/module/hare_module.td $(stdlib_hare_module_any_srcs)

# hare::parse (+any)
stdlib_hare_parse_any_srcs = \
	$(STDLIB)/hare/parse/decl.ha \
	$(STDLIB)/hare/parse/expr.ha \
	$(STDLIB)/hare/parse/ident.ha \
	$(STDLIB)/hare/parse/import.ha \
	$(STDLIB)/hare/parse/parse.ha \
	$(STDLIB)/hare/parse/type.ha \
	$(STDLIB)/hare/parse/unit.ha

$(HARECACHE)/hare/parse/hare_parse-any.ssa: $(stdlib_hare_parse_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_math_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/parse
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::parse \
		-t$(HARECACHE)/hare/parse/hare_parse.td $(stdlib_hare_parse_any_srcs)

# hare::types (+any)
stdlib_hare_types_any_srcs = \
	$(STDLIB)/hare/types/+$(ARCH)/writesize.ha \
	$(STDLIB)/hare/types/arch.ha \
	$(STDLIB)/hare/types/builtins.ha \
	$(STDLIB)/hare/types/class.ha \
	$(STDLIB)/hare/types/hash.ha \
	$(STDLIB)/hare/types/lookup.ha \
	$(STDLIB)/hare/types/store.ha \
	$(STDLIB)/hare/types/types.ha

$(HARECACHE)/hare/types/hare_types-any.ssa: $(stdlib_hare_types_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/types
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::types \
		-t$(HARECACHE)/hare/types/hare_types.td $(stdlib_hare_types_any_srcs)

# hare::unit (+any)
stdlib_hare_unit_any_srcs = \
	$(STDLIB)/hare/unit/check.ha \
	$(STDLIB)/hare/unit/context.ha \
	$(STDLIB)/hare/unit/errors.ha \
	$(STDLIB)/hare/unit/expr.ha \
	$(STDLIB)/hare/unit/process.ha \
	$(STDLIB)/hare/unit/scan.ha \
	$(STDLIB)/hare/unit/scope.ha \
	$(STDLIB)/hare/unit/unit.ha

$(HARECACHE)/hare/unit/hare_unit-any.ssa: $(stdlib_hare_unit_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_types_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/unit
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::unit \
		-t$(HARECACHE)/hare/unit/hare_unit.td $(stdlib_hare_unit_any_srcs)

# hare::unparse (+any)
stdlib_hare_unparse_any_srcs = \
	$(STDLIB)/hare/unparse/expr.ha \
	$(STDLIB)/hare/unparse/decl.ha \
	$(STDLIB)/hare/unparse/ident.ha \
	$(STDLIB)/hare/unparse/import.ha \
	$(STDLIB)/hare/unparse/type.ha \
	$(STDLIB)/hare/unparse/unit.ha \
	$(STDLIB)/hare/unparse/util.ha

$(HARECACHE)/hare/unparse/hare_unparse-any.ssa: $(stdlib_hare_unparse_any_srcs) $(stdlib_rt) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hare/unparse
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::unparse \
		-t$(HARECACHE)/hare/unparse/hare_unparse.td $(stdlib_hare_unparse_any_srcs)

# hash (+any)
stdlib_hash_any_srcs = \
	$(STDLIB)/hash/hash.ha

$(HARECACHE)/hash/hash-any.ssa: $(stdlib_hash_any_srcs) $(stdlib_rt) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash \
		-t$(HARECACHE)/hash/hash.td $(stdlib_hash_any_srcs)

# hash::adler32 (+any)
stdlib_hash_adler32_any_srcs = \
	$(STDLIB)/hash/adler32/adler32.ha

$(HARECACHE)/hash/adler32/hash_adler32-any.ssa: $(stdlib_hash_adler32_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/adler32
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::adler32 \
		-t$(HARECACHE)/hash/adler32/hash_adler32.td $(stdlib_hash_adler32_any_srcs)

# hash::crc16 (+any)
stdlib_hash_crc16_any_srcs = \
	$(STDLIB)/hash/crc16/crc16.ha

$(HARECACHE)/hash/crc16/hash_crc16-any.ssa: $(stdlib_hash_crc16_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/crc16
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc16 \
		-t$(HARECACHE)/hash/crc16/hash_crc16.td $(stdlib_hash_crc16_any_srcs)

# hash::crc32 (+any)
stdlib_hash_crc32_any_srcs = \
	$(STDLIB)/hash/crc32/crc32.ha

$(HARECACHE)/hash/crc32/hash_crc32-any.ssa: $(stdlib_hash_crc32_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/crc32
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc32 \
		-t$(HARECACHE)/hash/crc32/hash_crc32.td $(stdlib_hash_crc32_any_srcs)

# hash::crc64 (+any)
stdlib_hash_crc64_any_srcs = \
	$(STDLIB)/hash/crc64/crc64.ha

$(HARECACHE)/hash/crc64/hash_crc64-any.ssa: $(stdlib_hash_crc64_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/crc64
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc64 \
		-t$(HARECACHE)/hash/crc64/hash_crc64.td $(stdlib_hash_crc64_any_srcs)

# hash::fnv (+any)
stdlib_hash_fnv_any_srcs = \
	$(STDLIB)/hash/fnv/+$(ARCH).ha \
	$(STDLIB)/hash/fnv/fnv.ha

$(HARECACHE)/hash/fnv/hash_fnv-any.ssa: $(stdlib_hash_fnv_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/fnv
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::fnv \
		-t$(HARECACHE)/hash/fnv/hash_fnv.td $(stdlib_hash_fnv_any_srcs)

# hash::siphash (+any)
stdlib_hash_siphash_any_srcs = \
	$(STDLIB)/hash/siphash/siphash.ha

$(HARECACHE)/hash/siphash/hash_siphash-any.ssa: $(stdlib_hash_siphash_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/hash/siphash
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::siphash \
		-t$(HARECACHE)/hash/siphash/hash_siphash.td $(stdlib_hash_siphash_any_srcs)

# io (+linux)
stdlib_io_linux_srcs = \
	$(STDLIB)/io/arch+$(ARCH).ha \
	$(STDLIB)/io/+linux/file.ha \
	$(STDLIB)/io/+linux/mmap.ha \
	$(STDLIB)/io/+linux/platform_lock.ha \
	$(STDLIB)/io/+linux/platform_trunc.ha \
	$(STDLIB)/io/+linux/vector.ha \
	$(STDLIB)/io/copy.ha \
	$(STDLIB)/io/drain.ha \
	$(STDLIB)/io/empty.ha \
	$(STDLIB)/io/handle.ha \
	$(STDLIB)/io/limit.ha \
	$(STDLIB)/io/lock.ha \
	$(STDLIB)/io/stream.ha \
	$(STDLIB)/io/tee.ha \
	$(STDLIB)/io/trunc.ha \
	$(STDLIB)/io/types.ha \
	$(STDLIB)/io/util.ha \
	$(STDLIB)/io/zero.ha

# io (+freebsd)
stdlib_io_freebsd_srcs = \
	$(STDLIB)/io/arch+$(ARCH).ha \
	$(STDLIB)/io/+freebsd/file.ha \
	$(STDLIB)/io/+freebsd/mmap.ha \
	$(STDLIB)/io/+freebsd/platform_lock.ha \
	$(STDLIB)/io/+freebsd/platform_trunc.ha \
	$(STDLIB)/io/+freebsd/vector.ha \
	$(STDLIB)/io/copy.ha \
	$(STDLIB)/io/drain.ha \
	$(STDLIB)/io/empty.ha \
	$(STDLIB)/io/handle.ha \
	$(STDLIB)/io/limit.ha \
	$(STDLIB)/io/lock.ha \
	$(STDLIB)/io/stream.ha \
	$(STDLIB)/io/tee.ha \
	$(STDLIB)/io/trunc.ha \
	$(STDLIB)/io/types.ha \
	$(STDLIB)/io/util.ha \
	$(STDLIB)/io/zero.ha

$(HARECACHE)/io/io-linux.ssa: $(stdlib_io_linux_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_rt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/io
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nio \
		-t$(HARECACHE)/io/io.td $(stdlib_io_linux_srcs)

$(HARECACHE)/io/io-freebsd.ssa: $(stdlib_io_freebsd_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_rt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/io
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nio \
		-t$(HARECACHE)/io/io.td $(stdlib_io_freebsd_srcs)

# linux (+linux)
stdlib_linux_linux_srcs = \
	$(STDLIB)/linux/start.ha \
	$(STDLIB)/linux/env.ha

$(HARECACHE)/linux/linux-linux.ssa: $(stdlib_linux_linux_srcs) $(stdlib_rt) $(stdlib_format_elf_$(PLATFORM)) $(stdlib_rt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/linux
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux \
		-t$(HARECACHE)/linux/linux.td $(stdlib_linux_linux_srcs)

# linux::keyctl (+linux)
stdlib_linux_keyctl_linux_srcs = \
	$(STDLIB)/linux/keyctl/keyctl.ha \
	$(STDLIB)/linux/keyctl/types.ha

$(HARECACHE)/linux/keyctl/linux_keyctl-linux.ssa: $(stdlib_linux_keyctl_linux_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_types_c_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/linux/keyctl
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::keyctl \
		-t$(HARECACHE)/linux/keyctl/linux_keyctl.td $(stdlib_linux_keyctl_linux_srcs)

# linux::timerfd (+linux)
stdlib_linux_timerfd_linux_srcs = \
	$(STDLIB)/linux/timerfd/timerfd.ha

$(HARECACHE)/linux/timerfd/linux_timerfd-linux.ssa: $(stdlib_linux_timerfd_linux_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/linux/timerfd
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::timerfd \
		-t$(HARECACHE)/linux/timerfd/linux_timerfd.td $(stdlib_linux_timerfd_linux_srcs)

# linux::vdso (+linux)
stdlib_linux_vdso_linux_srcs = \
	$(STDLIB)/linux/vdso/vdso.ha

$(HARECACHE)/linux/vdso/linux_vdso-linux.ssa: $(stdlib_linux_vdso_linux_srcs) $(stdlib_rt) $(stdlib_linux_$(PLATFORM)) $(stdlib_format_elf_$(PLATFORM)) $(stdlib_types_c_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/linux/vdso
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::vdso \
		-t$(HARECACHE)/linux/vdso/linux_vdso.td $(stdlib_linux_vdso_linux_srcs)

# log (+linux)
stdlib_log_linux_srcs = \
	$(STDLIB)/log/logger.ha \
	$(STDLIB)/log/global.ha \
	$(STDLIB)/log/funcs.ha \
	$(STDLIB)/log/silent.ha

$(HARECACHE)/log/log-linux.ssa: $(stdlib_log_linux_srcs) $(stdlib_rt) $(stdlib_datetime_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/log
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlog \
		-t$(HARECACHE)/log/log.td $(stdlib_log_linux_srcs)

# log (+freebsd)
stdlib_log_freebsd_srcs = \
	$(STDLIB)/log/logger.ha \
	$(STDLIB)/log/global.ha \
	$(STDLIB)/log/funcs.ha \
	$(STDLIB)/log/silent.ha

$(HARECACHE)/log/log-freebsd.ssa: $(stdlib_log_freebsd_srcs) $(stdlib_rt) $(stdlib_datetime_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/log
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nlog \
		-t$(HARECACHE)/log/log.td $(stdlib_log_freebsd_srcs)

# math (+any)
stdlib_math_any_srcs = \
	$(STDLIB)/math/math.ha \
	$(STDLIB)/math/fenv_func.ha \
	$(STDLIB)/math/fenv+$(ARCH).ha \
	$(STDLIB)/math/floats.ha \
	$(STDLIB)/math/ints.ha \
	$(STDLIB)/math/uints.ha \
	$(STDLIB)/math/trig.ha

$(HARECACHE)/math/math-any.ssa: $(stdlib_math_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) $(stdlib_rt_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/math
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nmath \
		-t$(HARECACHE)/math/math.td $(stdlib_math_any_srcs)

# math::complex (+any)
stdlib_math_complex_any_srcs = \
	$(STDLIB)/math/complex/complex.ha

$(HARECACHE)/math/complex/math_complex-any.ssa: $(stdlib_math_complex_any_srcs) $(stdlib_rt) $(stdlib_math_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/math/complex
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nmath::complex \
		-t$(HARECACHE)/math/complex/math_complex.td $(stdlib_math_complex_any_srcs)

# math::random (+any)
stdlib_math_random_any_srcs = \
	$(STDLIB)/math/random/random.ha

$(HARECACHE)/math/random/math_random-any.ssa: $(stdlib_math_random_any_srcs) $(stdlib_rt)
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/math/random
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nmath::random \
		-t$(HARECACHE)/math/random/math_random.td $(stdlib_math_random_any_srcs)

# net (+linux)
stdlib_net_linux_srcs = \
	$(STDLIB)/net/+linux.ha \
	$(STDLIB)/net/errors.ha \
	$(STDLIB)/net/msg.ha

$(HARECACHE)/net/net-linux.ssa: $(stdlib_net_linux_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_slices_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/net
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nnet \
		-t$(HARECACHE)/net/net.td $(stdlib_net_linux_srcs)

# net (+freebsd)
stdlib_net_freebsd_srcs = \
	$(STDLIB)/net/+freebsd.ha \
	$(STDLIB)/net/errors.ha \
	$(STDLIB)/net/msg.ha

$(HARECACHE)/net/net-freebsd.ssa: $(stdlib_net_freebsd_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_slices_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/net
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nnet \
		-t$(HARECACHE)/net/net.td $(stdlib_net_freebsd_srcs)

# net::dial (+any)
stdlib_net_dial_any_srcs = \
	$(STDLIB)/net/dial/registry.ha \
	$(STDLIB)/net/dial/dial.ha \
	$(STDLIB)/net/dial/ip.ha \
	$(STDLIB)/net/dial/resolve.ha

$(HARECACHE)/net/dial/net_dial-any.ssa: $(stdlib_net_dial_any_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_net_tcp_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_dns_$(PLATFORM)) $(stdlib_net_uri_$(PLATFORM)) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_hosts_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/net/dial
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dial \
		-t$(HARECACHE)/net/dial/net_dial.td $(stdlib_net_dial_any_srcs)

# net::dns (+any)
stdlib_net_dns_any_srcs = \
	$(STDLIB)/net/dns/decode.ha \
	$(STDLIB)/net/dns/error.ha \
	$(STDLIB)/net/dns/encode.ha \
	$(STDLIB)/net/dns/query.ha \
	$(STDLIB)/net/dns/strdomain.ha \
	$(STDLIB)/net/dns/types.ha

$(HARECACHE)/net/dns/net_dns-any.ssa: $(stdlib_net_dns_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_resolvconf_$(PLATFORM)) $(stdlib_unix_poll_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_errors_$(PLATFORM))
	@printf 'HAREC \t$@\n'
	@mkdir -p $(HARECACHE)/net/dns
	@$(stdlib_env) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dns \
		-t$(HARECACHE)/net/dns/net_dns.td $(stdlib_net_dns_any_srcs)

# net::ip (+linux)
stdlib_net_ip_linux_srcs = \
	$(STDLIB)/net/ip/+linux.ha \
	$(STDLIB)/net/ip/ip.ha

# net::ip (+freebsd)
stdlib_net_ip_freebsd_srcs = \
	$(STDLIB)/net/ip/+freebsd.ha \