# This builds our WASM port of coreutils
include ../build/Makefile-vars
TARGET = ${DIST_WASM}/bin
all: deps \
${TARGET}/basename \
${TARGET}/cat \
${TARGET}/chmod \
${TARGET}/comm \
${TARGET}/csplit \
${TARGET}/cp \
${TARGET}/csplit \
${TARGET}/cut \
${TARGET}/date \
${TARGET}/dirname \
${TARGET}/du \
${TARGET}/env \
${TARGET}/expand \
${TARGET}/expr \
${TARGET}/factor \
${TARGET}/false \
${TARGET}/find \
${TARGET}/fmt \
${TARGET}/fold \
${TARGET}/grep \
${TARGET}/head \
${TARGET}/id \
${TARGET}/join \
${TARGET}/ln \
${TARGET}/logname \
${TARGET}/ls \
${TARGET}/mkdir \
${TARGET}/mktemp \
${TARGET}/mv \
${TARGET}/nl \
${TARGET}/paste \
${TARGET}/pathchk \
${TARGET}/pr \
${TARGET}/readlink \
${TARGET}/realpath \
${TARGET}/rm \
${TARGET}/rmdir \
${TARGET}/seq \
${TARGET}/sleep \
${TARGET}/sort \
${TARGET}/stat \
${TARGET}/tail \
${TARGET}/tee \
${TARGET}/test \
${TARGET}/touch \
${TARGET}/tr \
${TARGET}/tsort \
${TARGET}/tty \
${TARGET}/uname \
${TARGET}/unexpand \
${TARGET}/uniq \
${TARGET}/wc \
${TARGET}/which \
${TARGET}/xargs \
${TARGET}/yes
@# These don't work at all:
@# ${TARGET}/split \
include ../build/Makefile-rules
CC = ${BIN}/cowasm-cc
# Put -g at the end to get debug symbols and much bigger binaries.
CFLAGS = -Oz -fvisibility-main -I$(shell cowasm-package-path @cowasm/posix-wasm) -I${SRC}/compat -I$(shell cowasm-package-path @cowasm/bzip2)/include -I$(shell cowasm-package-path @cowasm/zlib)/include -DWITHOUT_LIBCRYPTO # -g
LDFLAGS = -L$(shell cowasm-package-path @cowasm/bzip2)/lib -lbz2 -L$(shell cowasm-package-path @cowasm/zlib)/lib -lz
# See https://stackoverflow.com/questions/54192234/recursive-search-in-vpath
# and https://stackoverflow.com/questions/231229/how-to-generate-a-makefile-with-source-in-sub-directories-using-just-one-makefil
space :=
space +=
VPATH := $(subst $(space),:,$(shell find ${SRC} -type d))
${BUILD}/%.o: %.c
cd ../build && make zig
mkdir -p ${BUILD} ${TARGET}
${CC} -c $^ ${CFLAGS} -o $@
COMPAT = ${BUILD}/fmt_scaled.o ${BUILD}/recallocarray.o ${BUILD}/getbsize.o ${BUILD}/strmode.o
# This builds any bin executable foo that depends only on foo.o and the compat files.
${TARGET}/%: ${COMPAT} ${BUILD}/%.o
${CC} ${CFLAGS} $^ -o $@
# Explicit rules for bin executables with more complicated dependencies go here:
${TARGET}/cp: ${COMPAT} ${BUILD}/cp.o ${BUILD}/utils.o
${CC} ${CFLAGS} $^ -o $@
test-cp: ${TARGET}/cp
rm -f ${BUILD}/x
${BIN}/cowasm ${TARGET}/cp Makefile ${BUILD}/x
ls ${BUILD}/x
rm ${BUILD}/x
${TARGET}/factor: ${COMPAT} ${BUILD}/factor.o ${BUILD}/pattern.o ${BUILD}/pr_tbl.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/find: ${COMPAT} ${BUILD}/find-function.o ${BUILD}/find-main.o ${BUILD}/find-operator.o ${BUILD}/find.o ${BUILD}/find-ls.o ${BUILD}/find-misc.o ${BUILD}/find-option.o ${BUILD}/find-getdate.tab.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/grep: ${COMPAT} ${BUILD}/grep-file.o ${BUILD}/grep-queue.o ${BUILD}/grep-util.o ${BUILD}/grep.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/ls: ${COMPAT} ${BUILD}/cmp.o ${BUILD}/ls.o ${BUILD}/print.o ${BUILD}/utf8.o ${BUILD}/util.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/mv: ${COMPAT} ${BUILD}/mv.o ${BUILD}/mv-rm.o ${BUILD}/mv-cp.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/pr: ${COMPAT} ${BUILD}/pr.o ${BUILD}/pr-egetopt.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/sort: ${COMPAT} ${BUILD}/bwstring.o ${BUILD}/coll.o ${BUILD}/file.o \
${BUILD}/mem.o ${BUILD}/sort.o ${BUILD}/vsort.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/tail: ${COMPAT} ${BUILD}/forward.o ${BUILD}/misc.o ${BUILD}/read.o ${BUILD}/reverse.o ${BUILD}/tail.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/tr: ${COMPAT} ${BUILD}/tr.o ${BUILD}/tr-str.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/tsort: ${COMPAT} ${BUILD}/tsort.o ${BUILD}/ohash.o
${CC} ${CFLAGS} $^ -o $@
${TARGET}/xargs: ${COMPAT} ${BUILD}/xargs.o ${BUILD}/strnsubst.o
${CC} ${CFLAGS} $^ -o $@
# TESTS -- do something with each bin script
# Be sure to also add these to test: below!
test-basename: ${TARGET}/basename
test "`cowasm ${TARGET}/basename foo/bar`" = "bar"
test-cat: ${TARGET}/cat
${BIN}/cowasm ${TARGET}/cat Makefile |grep crazy-nonsense-but-it-is-here-so-this-works
test-cut: ${TARGET}/cut
test "`echo 'hello world' | ${BIN}/cowasm ${TARGET}/cut -c 1-5`" = "hello"
test "`echo 'hello world' | ${BIN}/cowasm ${TARGET}/cut -c 7-11`" = "world"
test-date: ${TARGET}/date
${BIN}/cowasm ${TARGET}/date | grep 20[2-9][0-9]
test-dirname: ${TARGET}/dirname
test "`${BIN}/cowasm ${TARGET}/dirname foo/bar/stuff`" = "foo/bar"
test-env: ${TARGET}/env
test "`FOO=bar ${BIN}/cowasm dist/wasm/bin/env |grep FOO`" = "FOO=bar"
test-expr: ${TARGET}/expr
test "`${BIN}/cowasm ${TARGET}//expr 2 + 3`" = "5"
test-factor: ${TARGET}/factor
test "`${BIN}/cowasm ${TARGET}/factor 2023`" = "2023: 7 17 17"
test-fmt: ${TARGET}/fmt
echo "foo bar" | cowasm ./dist/wasm/bin/fmt -w 3 | wc -l | grep 2
test-grep: ${TARGET}/grep
# This is a TEST-OF-GREP
# MATCHES
${BIN}/cowasm ${TARGET}/grep TEST-OF-GREP Makefile | grep "TEST-OF-GREP"
# Does not match:
test x"`${BIN}/cowasm ${TARGET}/grep TEST-OF-GREP README.md`" = "x"
test-id: ${TARGET}/id
${BIN}/cowasm ${TARGET}/id |grep uid
${BIN}/cowasm ${TARGET}/id |grep gid
${BIN}/cowasm ${TARGET}/id |grep group
test-ln: ${TARGET}/ln
${BIN}/cowasm ./dist/wasm/bin/ln -sf README.md ${BUILD}/.xyz && ls -l ${BUILD}/.xyz |grep xyz | grep README.md ; rm ${BUILD}/.xyz
test-ls: ${TARGET}/ls
${BIN}/cowasm ${TARGET}/ls ${TARGET} | grep ls
test-mktemp: ${TARGET}/mktemp
# rm would error if file didn't exist...
rm `${BIN}/cowasm ${TARGET}/mktemp abc.XXXXXX`
test-seq: ${TARGET}/seq ${TARGET}/tr
${BIN}/cowasm ${TARGET}/seq 1 3 10 | ${BIN}/cowasm dist/wasm/bin/tr '\n' ' ' |grep "1 4 7 10"
test-sleep: ${TARGET}/sleep
${BIN}/cowasm ${TARGET}/sleep 0.1
test-head: ${TARGET}/head
echo "first line" > ${BUILD}/.test-head
echo "last line" >> ${BUILD}/.test-head
test "`${BIN}/cowasm ${TARGET}/head -n 1 ${BUILD}/.test-head`" = "first line"
rm ${BUILD}/.test-head
test-join: ${TARGET}/join
printf "1 X\n2 Y\n3 Z" > ${BUILD}/a
printf "1 x\n2 y\n3 z" > ${BUILD}/b
test "`cowasm ${TARGET}/join ${BUILD}/a ${BUILD}/b`" = "`printf "1 X x\n2 Y y\n3 Z z"`"
test-mkdir-rmdir: ${TARGET}/mkdir ${TARGET}/rmdir ${TARGET}/test
${BIN}/cowasm ${TARGET}/mkdir xyz-mkdir && ${BIN}/cowasm ${TARGET}/rmdir xyz-mkdir && ${BIN}/cowasm ${TARGET}/test ! -d xyz-mkdir
test-mv: ${TARGET}/mv ${TARGET}/touch ${TARGET}/test ${TARGET}/rm
${BIN}/cowasm ${TARGET}/touch x && ${BIN}/cowasm ${TARGET}/mv x y && ${BIN}/cowasm ${TARGET}/test -f y && ${BIN}/cowasm ${TARGET}/rm y
test-rm: ${TARGET}/rm ${TARGET}/touch
${BIN}/cowasm ${TARGET}/touch xyz-rm && ${BIN}/cowasm ${TARGET}/rm xyz-rm && ${BIN}/cowasm ${TARGET}/test ! -f xyz-rm
test-sort: ${TARGET}/sort
printf "x\na\ny\nhello\n" | ${BIN}/cowasm ${TARGET}/sort | ${BIN}/cowasm ${TARGET}/tr '\n' ' ' | grep "a hello x y"
test-stat: ${TARGET}/stat
${BIN}/cowasm ${TARGET}/stat ${TARGET}/stat |grep ${TARGET}/stat
${BIN}/cowasm ${TARGET}/stat -s ${TARGET}/stat |grep st_mtime
test-tail: ${TARGET}/tail
echo "first line" > ${BUILD}/.test-tail
echo "last line" >> ${BUILD}/.test-tail
test "`${BIN}/cowasm ${TARGET}/tail -n 1 ${BUILD}/.test-tail`" = "last line"
rm ${BUILD}/.test-tail
test-tee: ${TARGET}/tee
echo "Hello" | ${BIN}/cowasm ${TARGET}/tee ${BUILD}/.greetings.txt | grep Hello; grep Hello ${BUILD}/.greetings.txt; rm ${BUILD}/.greetings.txt
test-touch: ${TARGET}/touch
${BIN}/cowasm ${TARGET}/touch ${BUILD}/.foobar; ls ${BUILD}/.foobar |wc -l | grep 1; rm ${BUILD}/.foobar
test-tr: ${TARGET}/tr
echo "Bella" | ${BIN}/cowasm ${TARGET}/tr Bl 81 |grep 8e11a
test-tty: ${TARGET}/tty
# Do not be too precise with output so this works on both mac and linux...
${BIN}/cowasm ${TARGET}/tty | grep /dev
test-uname: ${TARGET}/uname
test "`${BIN}/cowasm ${TARGET}/uname`" = "wasi"
test "`${BIN}/cowasm ${TARGET}/uname -a`" = "wasi (none) 0.0.0 0.0.0 wasm32"
test-uniq: ${TARGET}/uniq
printf "hello\nworld\nworld\nworld\n" | ${BIN}/cowasm ${TARGET}/uniq | wc -l | grep 2
test-wc: ${TARGET}/wc
echo "hello world" | ${BIN}/cowasm ${TARGET}/wc | grep "1 2 12"
test-which: ${TARGET}/which
test "`${BIN}/cowasm ${TARGET}/which which`" = "`which which`"
test-xargs: ${TARGET}/xargs
ls -1 | ${BIN}/cowasm ${TARGET}/xargs |grep Makefile |grep dist
# Our makefile rule '${BUILD}/%.o: %.c' above assumes that .c files in
# subdirs have **unique names**, and this checks that.
test-uniq-sources:
cd ${SRC} && ./uniq-sources.sh
# TODO: this doesn't match cocalc so fix.
# format:
# find src/ -iname *.h -o -iname *.c | xargs clang-format -i --sort-includes=0
# Very basic tests of some things.
# NOTE: "make -j8 test" seems to crash tty on linux host at least.
# TODO/skip -- right now "test-tty" is NOT included below since it causes
# this wasm error on GitHub Actions:
# /home/runner/work/cowasm/cowasm/packages/coreutils/dist/wasm/bin/tty RuntimeError: memory access out of bounds
test: deps test-uniq-sources test-basename test-cat test-dirname test-cp test-cut test-date test-env test-expr test-factor test-fmt test-grep test-head test-id \
test-join test-ls test-mktemp test-mkdir-rmdir test-mv test-rm test-seq test-sleep test-sort test-stat test-tail test-touch test-tr \
test-uname test-uniq test-wc test-which test-xargs
@echo "Success -- all coreutils tests passed"