commit ea45859a32376e801c7e190174a210a690b02f15
parent dc9fe59959430deab97fae62ec77299607a5b639
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 4 Feb 2021 13:50:11 -0500
Rig up stdlib tests in `make check`
Diffstat:
M | .gitignore | | | 1 | + |
M | Makefile | | | 25 | +++++++++++++++++++------ |
M | gen-stdlib | | | 55 | ++++++++++++++++++++++++++++++++++--------------------- |
M | mk/gen-stdlib.sh | | | 31 | +++++++++++++++++++++++-------- |
M | mk/stdlib.mk | | | 296 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
5 files changed, 314 insertions(+), 94 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
cache
config.mk
hare
+hare-tests
diff --git a/Makefile b/Makefile
@@ -1,7 +1,8 @@
.POSIX:
.SUFFIXES:
include config.mk
-HAREC:=HARECACHE=$(HARECACHE) $(HAREC)
+TESTCACHE=$(HARECACHE)/+test
+TESTHAREFLAGS=$(HAREFLAGS) -T +test
hare:
@@ -21,17 +22,29 @@ hare_srcs=\
$(HARECACHE)/hare.ssa: $(hare_srcs)
@printf 'HAREC\t$@\n'
- @$(HAREC) -o $@ $(hare_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ $(hare_srcs)
-hare: $(stdlib_start) $(hare_deps) $(HARECACHE)/hare.o
+$(TESTCACHE)/hare.ssa: $(hare_srcs)
+ @printf 'HAREC\t$@\n'
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ $(hare_srcs)
+
+hare: $(stdlib_start) $(hare_stdlib_deps) $(HARECACHE)/hare.o
+ @printf 'LD\t$@\n'
+ @$(LD) -T $(rtscript) -o $@ \
+ $(stdlib_start) $(HARECACHE)/hare.o $(hare_stdlib_deps)
+
+hare-tests: $(testlib_start) $(hare_testlib_deps) $(TESTCACHE)/hare.o
@printf 'LD\t$@\n'
@$(LD) -T $(rtscript) -o $@ \
- $(stdlib_start) $(HARECACHE)/hare.o $(hare_deps)
+ $(testlib_start) $(TESTCACHE)/hare.o $(hare_testlib_deps)
clean:
@rm -rf cache
- @rm -f hare
+ @rm -f hare hare-tests
+
+check: hare-tests
+ @./hare-tests
all: hare
-.PHONY: all clean
+.PHONY: all clean check
diff --git a/gen-stdlib b/gen-stdlib
@@ -15,12 +15,8 @@
srcdir="$(dirname "$0")"
eval ". $srcdir/mk/gen-stdlib.sh"
-cache=HARECACHE
-rt() {
- # This one is complicated, don't use it as a reference for other modules
- printf '# rt\n'
- printf '%s\n' 'rtscript=$(STDLIB)/rt/hare.sc'
+gensrcs_rt() {
gen_srcs rt \
'$(PLATFORM)/abort.ha' \
'$(PLATFORM)/env.ha' \
@@ -33,12 +29,24 @@ rt() {
memcpy.ha \
memset.ha \
strcmp.ha \
- start-test.ha
+ $*
+}
+
+rt() {
+ # This one is complicated, don't use it as a reference for other modules
+ printf '# rt\n'
+ if [ $testing -eq 0 ]
+ then
+ printf '%s\n' 'rtscript=$(STDLIB)/rt/hare.sc'
+ gensrcs_rt start-test.ha
+ else
+ gensrcs_rt +test/start.ha
+ fi
gen_ssa rt
cat <<EOF
\$($cache)/rt/syscall.o: \$(STDLIB)/rt/\$(PLATFORM)/syscall\$(ARCH).s
@printf 'AS \t\$@\n'
- @mkdir -p \$(HARECACHE)/rt
+ @mkdir -p \$($cache)/rt
@as -o \$@ \$<
\$($cache)/rt/start.o: \$(STDLIB)/rt/\$(PLATFORM)/start.s
@@ -50,9 +58,9 @@ rt() {
@printf 'AR\t\$@\n'
@\$(AR) -csr \$@ \$($cache)/rt/rt.o \$($cache)/rt/syscall.o
-stdlib_rt=\$($cache)/rt/rt.a
-stdlib_start=\$($cache)/rt/start.o
-hare_deps+=\$(stdlib_rt)
+${stdlib}_rt=\$($cache)/rt/rt.a
+${stdlib}_start=\$($cache)/rt/start.o
+hare_${stdlib}_deps+=\$(${stdlib}_rt)
EOF
}
@@ -156,14 +164,19 @@ fmt() {
printf '# This file is generated by the gen-stdlib script, do not edit it by hand\n\n'
-# Keep me ordered with respect to dependencies
-rt
-ascii
-bytes
-types
-strconv
-io
-encoding_utf8
-strings
-os
-fmt
+stdlib() {
+ # Keep me ordered with respect to dependencies
+ rt
+ ascii
+ bytes
+ types
+ strconv
+ io
+ encoding_utf8
+ strings
+ os
+ fmt
+}
+
+genrules
+genrules test
diff --git a/mk/gen-stdlib.sh b/mk/gen-stdlib.sh
@@ -5,7 +5,7 @@ mod_file() {
printf '%s\n' "$1" | tr -s '::' '.'
}
mod_var() {
- printf '%s\n' "$1" | tr -s '::' '_'
+ printf '%s_%s\n' "$stdlib" "$1" | tr -s '::' '_'
}
gen_srcs() {
@@ -13,7 +13,7 @@ gen_srcs() {
path="$(mod_path "$mod")"
var="$(mod_var "$mod")"
shift
- printf 'lib%s_srcs= \\\n' "$var"
+ printf '%s_srcs= \\\n' "$var"
while [ $# -ne 0 ]
do
if [ $# -eq 1 ]
@@ -33,18 +33,18 @@ gen_ssa() {
var=$(mod_var "$mod")
shift
- printf "\$($cache)/$path/$file.ssa: \$(lib${var}_srcs) \$(stdlib_rt)"
+ printf "\$($cache)/$path/$file.ssa: \$(${var}_srcs) \$(${stdlib}_rt)"
for dep in $*
do
- printf ' $(stdlib_%s)' "$(mod_var "$dep")"
+ printf ' $(%s_%s)' "$stdlib" "$(mod_var "$dep")"
done
printf '\n'
cat <<EOF
@printf 'HAREC \t\$@\n'
@mkdir -p \$($cache)/$path
- @\$(HAREC) \$(HAREFLAGS) -o \$@ -N$mod \\
- -t\$($cache)/$path/$file.td \$(lib${var}_srcs)
+ @HARECACHE=\$($cache) \$(HAREC) \$($flags) -o \$@ -N$mod \\
+ -t\$($cache)/$path/$file.td \$(${var}_srcs)
EOF
}
@@ -54,7 +54,22 @@ gen_lib() {
path=$(mod_path "$mod")
file=$(mod_file "$mod")
var=$(mod_var "$mod")
- printf "stdlib_$var=\$($cache)/$path/$file.o\n"
- printf 'hare_deps+=$(stdlib_%s)\n\n' "$var"
+ printf "${stdlib}_$var=\$($cache)/$path/$file.o\n"
+ printf 'hare_%s_deps+=$(%s_%s)\n\n' "$stdlib" "$stdlib" "$var"
}
+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/mk/stdlib.mk b/mk/stdlib.mk
@@ -2,7 +2,7 @@
# rt
rtscript=$(STDLIB)/rt/hare.sc
-librt_srcs= \
+stdlib_rt_srcs= \
$(STDLIB)/rt/$(PLATFORM)/abort.ha \
$(STDLIB)/rt/$(PLATFORM)/env.ha \
$(STDLIB)/rt/$(PLATFORM)/errno.ha \
@@ -16,11 +16,11 @@ librt_srcs= \
$(STDLIB)/rt/strcmp.ha \
$(STDLIB)/rt/start-test.ha
-$(HARECACHE)/rt/rt.ssa: $(librt_srcs) $(stdlib_rt)
+$(HARECACHE)/rt/rt.ssa: $(stdlib_rt_srcs) $(stdlib_rt)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/rt
- @$(HAREC) $(HAREFLAGS) -o $@ -Nrt \
- -t$(HARECACHE)/rt/rt.td $(librt_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nrt \
+ -t$(HARECACHE)/rt/rt.td $(stdlib_rt_srcs)
$(HARECACHE)/rt/syscall.o: $(STDLIB)/rt/$(PLATFORM)/syscall$(ARCH).s
@printf 'AS \t$@\n'
@@ -38,116 +38,116 @@ $(HARECACHE)/rt/rt.a: $(HARECACHE)/rt/rt.o $(HARECACHE)/rt/syscall.o
stdlib_rt=$(HARECACHE)/rt/rt.a
stdlib_start=$(HARECACHE)/rt/start.o
-hare_deps+=$(stdlib_rt)
+hare_stdlib_deps+=$(stdlib_rt)
# ascii
-libascii_srcs= \
+stdlib_ascii_srcs= \
$(STDLIB)/ascii/ctype.ha
-$(HARECACHE)/ascii/ascii.ssa: $(libascii_srcs) $(stdlib_rt)
+$(HARECACHE)/ascii/ascii.ssa: $(stdlib_ascii_srcs) $(stdlib_rt)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/ascii
- @$(HAREC) $(HAREFLAGS) -o $@ -Nascii \
- -t$(HARECACHE)/ascii/ascii.td $(libascii_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nascii \
+ -t$(HARECACHE)/ascii/ascii.td $(stdlib_ascii_srcs)
-stdlib_ascii=$(HARECACHE)/ascii/ascii.o
-hare_deps+=$(stdlib_ascii)
+stdlib_stdlib_ascii=$(HARECACHE)/ascii/ascii.o
+hare_stdlib_deps+=$(stdlib_stdlib_ascii)
# bytes
-libbytes_srcs= \
+stdlib_bytes_srcs= \
$(STDLIB)/bytes/copy.ha \
$(STDLIB)/bytes/equal.ha \
$(STDLIB)/bytes/index.ha \
$(STDLIB)/bytes/reverse.ha
-$(HARECACHE)/bytes/bytes.ssa: $(libbytes_srcs) $(stdlib_rt)
+$(HARECACHE)/bytes/bytes.ssa: $(stdlib_bytes_srcs) $(stdlib_rt)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/bytes
- @$(HAREC) $(HAREFLAGS) -o $@ -Nbytes \
- -t$(HARECACHE)/bytes/bytes.td $(libbytes_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nbytes \
+ -t$(HARECACHE)/bytes/bytes.td $(stdlib_bytes_srcs)
-stdlib_bytes=$(HARECACHE)/bytes/bytes.o
-hare_deps+=$(stdlib_bytes)
+stdlib_stdlib_bytes=$(HARECACHE)/bytes/bytes.o
+hare_stdlib_deps+=$(stdlib_stdlib_bytes)
# types
-libtypes_srcs= \
+stdlib_types_srcs= \
$(STDLIB)/types/limits.ha \
$(STDLIB)/types/classes.ha \
$(STDLIB)/types/arch$(ARCH).ha
-$(HARECACHE)/types/types.ssa: $(libtypes_srcs) $(stdlib_rt)
+$(HARECACHE)/types/types.ssa: $(stdlib_types_srcs) $(stdlib_rt)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/types
- @$(HAREC) $(HAREFLAGS) -o $@ -Ntypes \
- -t$(HARECACHE)/types/types.td $(libtypes_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntypes \
+ -t$(HARECACHE)/types/types.td $(stdlib_types_srcs)
-stdlib_types=$(HARECACHE)/types/types.o
-hare_deps+=$(stdlib_types)
+stdlib_stdlib_types=$(HARECACHE)/types/types.o
+hare_stdlib_deps+=$(stdlib_stdlib_types)
# strconv
-libstrconv_srcs= \
+stdlib_strconv_srcs= \
$(STDLIB)/strconv/itos.ha \
$(STDLIB)/strconv/utos.ha \
$(STDLIB)/strconv/numeric.ha
-$(HARECACHE)/strconv/strconv.ssa: $(libstrconv_srcs) $(stdlib_rt) $(stdlib_types)
+$(HARECACHE)/strconv/strconv.ssa: $(stdlib_strconv_srcs) $(stdlib_rt) $(stdlib_stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/strconv
- @$(HAREC) $(HAREFLAGS) -o $@ -Nstrconv \
- -t$(HARECACHE)/strconv/strconv.td $(libstrconv_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nstrconv \
+ -t$(HARECACHE)/strconv/strconv.td $(stdlib_strconv_srcs)
-stdlib_strconv=$(HARECACHE)/strconv/strconv.o
-hare_deps+=$(stdlib_strconv)
+stdlib_stdlib_strconv=$(HARECACHE)/strconv/strconv.o
+hare_stdlib_deps+=$(stdlib_stdlib_strconv)
# io
-libio_srcs= \
+stdlib_io_srcs= \
$(STDLIB)/io/types.ha \
$(STDLIB)/io/copy.ha \
$(STDLIB)/io/println.ha \
$(STDLIB)/io/stream.ha
-$(HARECACHE)/io/io.ssa: $(libio_srcs) $(stdlib_rt)
+$(HARECACHE)/io/io.ssa: $(stdlib_io_srcs) $(stdlib_rt)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/io
- @$(HAREC) $(HAREFLAGS) -o $@ -Nio \
- -t$(HARECACHE)/io/io.td $(libio_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nio \
+ -t$(HARECACHE)/io/io.td $(stdlib_io_srcs)
-stdlib_io=$(HARECACHE)/io/io.o
-hare_deps+=$(stdlib_io)
+stdlib_stdlib_io=$(HARECACHE)/io/io.o
+hare_stdlib_deps+=$(stdlib_stdlib_io)
# encoding::utf8
-libencoding_utf8_srcs= \
+stdlib_encoding_utf8_srcs= \
$(STDLIB)/encoding/utf8/rune.ha \
$(STDLIB)/encoding/utf8/decode.ha \
$(STDLIB)/encoding/utf8/encode.ha
-$(HARECACHE)/encoding/utf8/encoding.utf8.ssa: $(libencoding_utf8_srcs) $(stdlib_rt) $(stdlib_types)
+$(HARECACHE)/encoding/utf8/encoding.utf8.ssa: $(stdlib_encoding_utf8_srcs) $(stdlib_rt) $(stdlib_stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/encoding/utf8
- @$(HAREC) $(HAREFLAGS) -o $@ -Nencoding::utf8 \
- -t$(HARECACHE)/encoding/utf8/encoding.utf8.td $(libencoding_utf8_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::utf8 \
+ -t$(HARECACHE)/encoding/utf8/encoding.utf8.td $(stdlib_encoding_utf8_srcs)
-stdlib_encoding_utf8=$(HARECACHE)/encoding/utf8/encoding.utf8.o
-hare_deps+=$(stdlib_encoding_utf8)
+stdlib_stdlib_encoding_utf8=$(HARECACHE)/encoding/utf8/encoding.utf8.o
+hare_stdlib_deps+=$(stdlib_stdlib_encoding_utf8)
# strings
-libstrings_srcs= \
+stdlib_strings_srcs= \
$(STDLIB)/strings/cstrings.ha \
$(STDLIB)/strings/dup.ha \
$(STDLIB)/strings/iter.ha \
$(STDLIB)/strings/utf8.ha
-$(HARECACHE)/strings/strings.ssa: $(libstrings_srcs) $(stdlib_rt) $(stdlib_encoding_utf8) $(stdlib_types)
+$(HARECACHE)/strings/strings.ssa: $(stdlib_strings_srcs) $(stdlib_rt) $(stdlib_stdlib_encoding_utf8) $(stdlib_stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/strings
- @$(HAREC) $(HAREFLAGS) -o $@ -Nstrings \
- -t$(HARECACHE)/strings/strings.td $(libstrings_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nstrings \
+ -t$(HARECACHE)/strings/strings.td $(stdlib_strings_srcs)
-stdlib_strings=$(HARECACHE)/strings/strings.o
-hare_deps+=$(stdlib_strings)
+stdlib_stdlib_strings=$(HARECACHE)/strings/strings.o
+hare_stdlib_deps+=$(stdlib_stdlib_strings)
# os
-libos_srcs= \
+stdlib_os_srcs= \
$(STDLIB)/os/$(PLATFORM)/environ.ha \
$(STDLIB)/os/$(PLATFORM)/errors.ha \
$(STDLIB)/os/$(PLATFORM)/exit.ha \
@@ -157,25 +157,203 @@ libos_srcs= \
$(STDLIB)/os/environ.ha \
$(STDLIB)/os/stdfd.ha
-$(HARECACHE)/os/os.ssa: $(libos_srcs) $(stdlib_rt) $(stdlib_strings) $(stdlib_types)
+$(HARECACHE)/os/os.ssa: $(stdlib_os_srcs) $(stdlib_rt) $(stdlib_stdlib_strings) $(stdlib_stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/os
- @$(HAREC) $(HAREFLAGS) -o $@ -Nos \
- -t$(HARECACHE)/os/os.td $(libos_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nos \
+ -t$(HARECACHE)/os/os.td $(stdlib_os_srcs)
-stdlib_os=$(HARECACHE)/os/os.o
-hare_deps+=$(stdlib_os)
+stdlib_stdlib_os=$(HARECACHE)/os/os.o
+hare_stdlib_deps+=$(stdlib_stdlib_os)
# fmt
-libfmt_srcs= \
+stdlib_fmt_srcs= \
$(STDLIB)/fmt/fmt.ha
-$(HARECACHE)/fmt/fmt.ssa: $(libfmt_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_os) $(stdlib_strconv) $(stdlib_strings) $(stdlib_types)
+$(HARECACHE)/fmt/fmt.ssa: $(stdlib_fmt_srcs) $(stdlib_rt) $(stdlib_stdlib_io) $(stdlib_stdlib_os) $(stdlib_stdlib_strconv) $(stdlib_stdlib_strings) $(stdlib_stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/fmt
- @$(HAREC) $(HAREFLAGS) -o $@ -Nfmt \
- -t$(HARECACHE)/fmt/fmt.td $(libfmt_srcs)
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nfmt \
+ -t$(HARECACHE)/fmt/fmt.td $(stdlib_fmt_srcs)
-stdlib_fmt=$(HARECACHE)/fmt/fmt.o
-hare_deps+=$(stdlib_fmt)
+stdlib_stdlib_fmt=$(HARECACHE)/fmt/fmt.o
+hare_stdlib_deps+=$(stdlib_stdlib_fmt)
+
+# rt
+testlib_rt_srcs= \
+ $(STDLIB)/rt/$(PLATFORM)/abort.ha \
+ $(STDLIB)/rt/$(PLATFORM)/env.ha \
+ $(STDLIB)/rt/$(PLATFORM)/errno.ha \
+ $(STDLIB)/rt/$(PLATFORM)/start.ha \
+ $(STDLIB)/rt/$(PLATFORM)/syscallno$(ARCH).ha \
+ $(STDLIB)/rt/$(PLATFORM)/syscalls.ha \
+ $(STDLIB)/rt/$(PLATFORM)/segmalloc.ha \
+ $(STDLIB)/rt/malloc.ha \
+ $(STDLIB)/rt/memcpy.ha \
+ $(STDLIB)/rt/memset.ha \
+ $(STDLIB)/rt/strcmp.ha \
+ $(STDLIB)/rt/+test/start.ha
+
+$(TESTCACHE)/rt/rt.ssa: $(testlib_rt_srcs) $(testlib_rt)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/rt
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nrt \
+ -t$(TESTCACHE)/rt/rt.td $(testlib_rt_srcs)
+
+$(TESTCACHE)/rt/syscall.o: $(STDLIB)/rt/$(PLATFORM)/syscall$(ARCH).s
+ @printf 'AS \t$@\n'
+ @mkdir -p $(TESTCACHE)/rt
+ @as -o $@ $<
+
+$(TESTCACHE)/rt/start.o: $(STDLIB)/rt/$(PLATFORM)/start.s
+ @printf 'AS \t$@\n'
+ @mkdir -p $(TESTCACHE)/rt
+ @as -o $@ $<
+
+$(TESTCACHE)/rt/rt.a: $(TESTCACHE)/rt/rt.o $(TESTCACHE)/rt/syscall.o
+ @printf 'AR\t$@\n'
+ @$(AR) -csr $@ $(TESTCACHE)/rt/rt.o $(TESTCACHE)/rt/syscall.o
+
+testlib_rt=$(TESTCACHE)/rt/rt.a
+testlib_start=$(TESTCACHE)/rt/start.o
+hare_testlib_deps+=$(testlib_rt)
+
+# ascii
+testlib_ascii_srcs= \
+ $(STDLIB)/ascii/ctype.ha
+
+$(TESTCACHE)/ascii/ascii.ssa: $(testlib_ascii_srcs) $(testlib_rt)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/ascii
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nascii \
+ -t$(TESTCACHE)/ascii/ascii.td $(testlib_ascii_srcs)
+
+testlib_testlib_ascii=$(TESTCACHE)/ascii/ascii.o
+hare_testlib_deps+=$(testlib_testlib_ascii)
+
+# bytes
+testlib_bytes_srcs= \
+ $(STDLIB)/bytes/copy.ha \
+ $(STDLIB)/bytes/equal.ha \
+ $(STDLIB)/bytes/index.ha \
+ $(STDLIB)/bytes/reverse.ha
+
+$(TESTCACHE)/bytes/bytes.ssa: $(testlib_bytes_srcs) $(testlib_rt)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/bytes
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nbytes \
+ -t$(TESTCACHE)/bytes/bytes.td $(testlib_bytes_srcs)
+
+testlib_testlib_bytes=$(TESTCACHE)/bytes/bytes.o
+hare_testlib_deps+=$(testlib_testlib_bytes)
+
+# types
+testlib_types_srcs= \
+ $(STDLIB)/types/limits.ha \
+ $(STDLIB)/types/classes.ha \
+ $(STDLIB)/types/arch$(ARCH).ha
+
+$(TESTCACHE)/types/types.ssa: $(testlib_types_srcs) $(testlib_rt)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/types
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntypes \
+ -t$(TESTCACHE)/types/types.td $(testlib_types_srcs)
+
+testlib_testlib_types=$(TESTCACHE)/types/types.o
+hare_testlib_deps+=$(testlib_testlib_types)
+
+# strconv
+testlib_strconv_srcs= \
+ $(STDLIB)/strconv/itos.ha \
+ $(STDLIB)/strconv/utos.ha \
+ $(STDLIB)/strconv/numeric.ha
+
+$(TESTCACHE)/strconv/strconv.ssa: $(testlib_strconv_srcs) $(testlib_rt) $(testlib_testlib_types)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/strconv
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nstrconv \
+ -t$(TESTCACHE)/strconv/strconv.td $(testlib_strconv_srcs)
+
+testlib_testlib_strconv=$(TESTCACHE)/strconv/strconv.o
+hare_testlib_deps+=$(testlib_testlib_strconv)
+
+# io
+testlib_io_srcs= \
+ $(STDLIB)/io/types.ha \
+ $(STDLIB)/io/copy.ha \
+ $(STDLIB)/io/println.ha \
+ $(STDLIB)/io/stream.ha
+
+$(TESTCACHE)/io/io.ssa: $(testlib_io_srcs) $(testlib_rt)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/io
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nio \
+ -t$(TESTCACHE)/io/io.td $(testlib_io_srcs)
+
+testlib_testlib_io=$(TESTCACHE)/io/io.o
+hare_testlib_deps+=$(testlib_testlib_io)
+
+# encoding::utf8
+testlib_encoding_utf8_srcs= \
+ $(STDLIB)/encoding/utf8/rune.ha \
+ $(STDLIB)/encoding/utf8/decode.ha \
+ $(STDLIB)/encoding/utf8/encode.ha
+
+$(TESTCACHE)/encoding/utf8/encoding.utf8.ssa: $(testlib_encoding_utf8_srcs) $(testlib_rt) $(testlib_testlib_types)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/encoding/utf8
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::utf8 \
+ -t$(TESTCACHE)/encoding/utf8/encoding.utf8.td $(testlib_encoding_utf8_srcs)
+
+testlib_testlib_encoding_utf8=$(TESTCACHE)/encoding/utf8/encoding.utf8.o
+hare_testlib_deps+=$(testlib_testlib_encoding_utf8)
+
+# strings
+testlib_strings_srcs= \
+ $(STDLIB)/strings/cstrings.ha \
+ $(STDLIB)/strings/dup.ha \
+ $(STDLIB)/strings/iter.ha \
+ $(STDLIB)/strings/utf8.ha
+
+$(TESTCACHE)/strings/strings.ssa: $(testlib_strings_srcs) $(testlib_rt) $(testlib_testlib_encoding_utf8) $(testlib_testlib_types)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/strings
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nstrings \
+ -t$(TESTCACHE)/strings/strings.td $(testlib_strings_srcs)
+
+testlib_testlib_strings=$(TESTCACHE)/strings/strings.o
+hare_testlib_deps+=$(testlib_testlib_strings)
+
+# os
+testlib_os_srcs= \
+ $(STDLIB)/os/$(PLATFORM)/environ.ha \
+ $(STDLIB)/os/$(PLATFORM)/errors.ha \
+ $(STDLIB)/os/$(PLATFORM)/exit.ha \
+ $(STDLIB)/os/$(PLATFORM)/fdstream.ha \
+ $(STDLIB)/os/$(PLATFORM)/open.ha \
+ $(STDLIB)/os/$(PLATFORM)/stdfd.ha \
+ $(STDLIB)/os/environ.ha \
+ $(STDLIB)/os/stdfd.ha
+
+$(TESTCACHE)/os/os.ssa: $(testlib_os_srcs) $(testlib_rt) $(testlib_testlib_strings) $(testlib_testlib_types)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/os
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nos \
+ -t$(TESTCACHE)/os/os.td $(testlib_os_srcs)
+
+testlib_testlib_os=$(TESTCACHE)/os/os.o
+hare_testlib_deps+=$(testlib_testlib_os)
+
+# fmt
+testlib_fmt_srcs= \
+ $(STDLIB)/fmt/fmt.ha
+
+$(TESTCACHE)/fmt/fmt.ssa: $(testlib_fmt_srcs) $(testlib_rt) $(testlib_testlib_io) $(testlib_testlib_os) $(testlib_testlib_strconv) $(testlib_testlib_strings) $(testlib_testlib_types)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/fmt
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nfmt \
+ -t$(TESTCACHE)/fmt/fmt.td $(testlib_fmt_srcs)
+
+testlib_testlib_fmt=$(TESTCACHE)/fmt/fmt.o
+hare_testlib_deps+=$(testlib_testlib_fmt)