-include config.mk BUILD ?= build/linux VERSION ?= $(shell tr -d '\r\n' < VERSION) PACKAGE_ARCH ?= $(shell uname -m) PACKAGE_STAGE ?= $(CURDIR)/$(BUILD)/package-root PACKAGE_DIR ?= $(CURDIR)/dist/linux-$(PACKAGE_ARCH) PREFIX ?= /usr/local DPIDIR ?= $(PREFIX)/lib/dillo/dpi/dat DAT_SCHEME_DIR ?= $(PREFIX)/share/datgpt/scheme DESTDIR ?= CC ?= cc AR ?= ar RANLIB ?= ranlib OBJCOPY ?= objcopy INSTALL ?= install CFLAGS ?= -O2 -std=c99 -Wall -Wextra -Wpedantic HOST_OS := $(shell uname -s 2>/dev/null) ifneq (,$(findstring CYGWIN,$(HOST_OS))) TEST_LDFLAGS += -Wl,--stack,8388608 endif CPPFLAGS ?= LDFLAGS ?= SODIUM_LIBS ?= -lsodium CURL_CFLAGS ?= $(shell pkg-config --cflags libcurl 2>/dev/null) CURL_LIBS ?= $(shell pkg-config --libs libcurl 2>/dev/null || echo -lcurl) ENABLE_SDL2 ?= 0 FFMPEG_MEDIA_AVAILABLE := $(shell pkg-config --exists 'libavcodec >= 59' 'libavformat >= 59' 'libavutil >= 57' 'libswresample >= 4' 'libswscale >= 6' 2>/dev/null && echo 1 || echo 0) ENABLE_CABLE_MEDIA ?= 0 ifeq ($(ENABLE_CABLE_MEDIA),1) ifneq ($(FFMPEG_MEDIA_AVAILABLE),1) $(error Cable media needs FFmpeg 5.0+ development files: libavcodec>=59, libavformat>=59, libavutil>=57, libswresample>=4, libswscale>=6) endif CABLE_MEDIA_CFLAGS = -DCABLE_HAVE_FFMPEG $(shell pkg-config --cflags libavcodec libavformat libavutil libswresample libswscale) CABLE_MEDIA_LIBS = $(shell pkg-config --libs libavformat libavcodec libavutil libswresample libswscale) endif # Node and Cabal modules are used only by optional interoperability tests. NODE ?= node CABAL_JS_MODULE ?= cabal-core CABAL_CLIENT_MODULE ?= cabal-client CPPFLAGS += -I. -Iinc -Ilibcess/include -DSLEEP_SALT -DCESSPOOL_HAVE_SODIUM $(CURL_CFLAGS) CPPFLAGS += -DDAT_BUILD_DIR=\"$(BUILD)\" # Root-level NETWORK_PROTOCOL is the Cesspool peer identity and discovery # namespace. Hypercore-compatible protocol identifiers belong in test builds. NETWORK_PROTOCOL := $(shell tr -d '\r\n' < NETWORK_PROTOCOL) CPPFLAGS += -DDAT_NETWORK_PROTOCOL=\"$(NETWORK_PROTOCOL)\" CPPFLAGS += -DCESSPOOL_NETWORK_PROTOCOL=\"$(NETWORK_PROTOCOL)\" CPPFLAGS += -DCESSPOOL_CONFIG_DIRECTORY=\"dat-gpt\" ifeq ($(NETWORK_PROTOCOL),hypercore) CPPFLAGS += -DDAT_LEGACY_HYPERCORE endif LIBS = $(SODIUM_LIBS) $(CURL_LIBS) -lm -ldl LIB_SOURCES = src/base32768.c src/cable.c src/cable_feed.c src/dat.c src/dat_browse.c src/dat_dns.c src/dat_fetch.c src/dat_walk.c src/dat_wire.c src/dat_session.c \ src/sleep.c src/sleep_tree.c src/sleep_bitfield.c \ src/sleep_proto.c src/sleep_crypto.c src/sleep_writer.c \ src/sleep_feed.c src/sleep_proof.c src/sleep_replication.c src/sleep_utp.c LIB_SOURCES += src/dat_s7.c src/dat_scheme.c src/s7.c S7_INSTALL = $(INSTALL) -m 755 $(BUILD)/ddat-scheme "$(DESTDIR)$(PREFIX)/bin/ddat-scheme" S7_SCHEME_INSTALL = $(INSTALL) -d "$(DESTDIR)$(DAT_SCHEME_DIR)" && \ $(INSTALL) -m 644 scheme/dat-init.scm scheme/dat-record.scm scheme/dat-wire.scm scheme/dat-json.scm scheme/cable-room.scm "$(DESTDIR)$(DAT_SCHEME_DIR)/" S7_UNINSTALL = rm -f "$(DESTDIR)$(PREFIX)/bin/ddat-scheme" "$(DESTDIR)$(DAT_SCHEME_DIR)/dat-init.scm" "$(DESTDIR)$(DAT_SCHEME_DIR)/dat-record.scm" "$(DESTDIR)$(DAT_SCHEME_DIR)/dat-wire.scm" "$(DESTDIR)$(DAT_SCHEME_DIR)/dat-json.scm" "$(DESTDIR)$(DAT_SCHEME_DIR)/cable-room.scm" LIB_OBJECTS = $(LIB_SOURCES:src/%.c=$(BUILD)/%.o) $(BUILD)/sleep_verify_lib.o LIBCESS_OBJECTS = $(BUILD)/libcess/cess_net.o $(BUILD)/libcess/cesspool.o $(BUILD)/libcess/cess_identity.o PUBLIC_HEADERS = $(wildcard inc/*.h) TESTS = $(BUILD)/test_tree $(BUILD)/test_bitfield $(BUILD)/test_base32768 $(BUILD)/test_cable $(BUILD)/test_proto $(BUILD)/test_wire \ $(BUILD)/test_archive $(BUILD)/test_session $(BUILD)/test_dns $(BUILD)/test_utp \ $(BUILD)/test_discovery $(BUILD)/test_replication $(BUILD)/test_writer $(BUILD)/test_paths ifeq ($(ENABLE_SDL2),1) GUI_TESTS = $(BUILD)/test_version_bar $(BUILD)/test_gui_p2p CABLE_LIVE_TEST = $(BUILD)/test_cable_thang endif .PHONY: all test install uninstall clean distclean package package-linux .PHONY: test-cabal-interop .PHONY: test-cable-live .PHONY: FORCE all: $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(BUILD)/sleep-verify $(BUILD)/dat $(BUILD)/ddat $(BUILD)/cable $(BUILD)/cesspool-bootstrap $(BUILD)/dat.dpi all: $(BUILD)/ddat-scheme ifeq ($(ENABLE_SDL2),1) all: $(BUILD)/dat-thang $(BUILD)/cable-thang endif $(BUILD): mkdir -p $(BUILD) # A protocol identity changes wire bytes and must never reuse objects built for # another value (including make command-line overrides used for compatibility). $(BUILD)/.network-protocol: FORCE NETWORK_PROTOCOL | $(BUILD) @protocol="$(NETWORK_PROTOCOL)"; \ if test ! -f $@ || test "$$(cat $@)" != "$$protocol"; then \ printf '%s\n' "$$protocol" > $@.tmp; mv $@.tmp $@; \ fi $(BUILD)/%.o: src/%.c NETWORK_PROTOCOL $(BUILD)/.network-protocol | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ $(BUILD)/libcess: mkdir -p $@ $(BUILD)/libcess/%.o: libcess/src/%.c libcess/include/cesspool.h libcess/include/cess_net.h libcess/include/cess_compat.h NETWORK_PROTOCOL $(BUILD)/.network-protocol | $(BUILD)/libcess $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ $(BUILD)/libcess.a: $(LIBCESS_OBJECTS) $(AR) rcs $@ $(LIBCESS_OBJECTS) $(RANLIB) $@ # S7 is an upstream single-file interpreter with noisy legacy diagnostics. # Suppression applies only to that vendored translation unit; our host stays # under the normal project warning flags. $(BUILD)/s7.o: src/s7.c NETWORK_PROTOCOL $(BUILD)/.network-protocol | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) -w -MMD -MP -c $< -o $@ $(BUILD)/sleep_verify_lib.o: src/sleep_verify.c $(BUILD)/.network-protocol | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -DSLEEP_VERIFY_NO_MAIN -c $< -o $@ -include $(LIB_OBJECTS:$(BUILD)/%.o=$(BUILD)/%.d) $(BUILD)/libdatgpt.a: $(LIB_OBJECTS) $(BUILD)/.network-protocol $(AR) rcs $@ $(LIB_OBJECTS) $(RANLIB) $@ # The DPI uses S7's reader for dat.scm, treating archive metadata as data and # never evaluating archive-supplied Scheme forms. DPI_LIB_OBJECTS = $(patsubst $(BUILD)/%.o,$(BUILD)/dpi/%.o,$(filter-out $(BUILD)/dat_s7.o $(BUILD)/dat_scheme.o $(BUILD)/s7.o,$(LIB_OBJECTS))) $(BUILD)/dpi: mkdir -p $@ $(BUILD)/dpi/%.o: src/%.c NETWORK_PROTOCOL $(BUILD)/.network-protocol | $(BUILD)/dpi $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ $(BUILD)/dpi/sleep_verify_lib.o: src/sleep_verify.c NETWORK_PROTOCOL $(BUILD)/.network-protocol | $(BUILD)/dpi $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -DSLEEP_VERIFY_NO_MAIN -c $< -o $@ $(BUILD)/dpi_s7.o: $(BUILD)/s7.o | $(BUILD) $(OBJCOPY) --redefine-sym main=dat_dpi_s7_standalone_main $< $@ -include $(DPI_LIB_OBJECTS:$(BUILD)/dpi/%.o=$(BUILD)/dpi/%.d) $(LIBCESS_OBJECTS:$(BUILD)/libcess/%.o=$(BUILD)/libcess/%.d) $(BUILD)/libdatgpt-dpi.a: $(DPI_LIB_OBJECTS) $(BUILD)/.network-protocol $(AR) rcs $@ $(DPI_LIB_OBJECTS) $(RANLIB) $@ $(BUILD)/sleep-verify: src/sleep_verify.c $(BUILD)/libdatgpt.a $(BUILD)/.network-protocol $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) src/sleep_verify.c $(BUILD)/libdatgpt.a $(LIBS) -o $@ $(BUILD)/dat: src/dat_cli.c NETWORK_PROTOCOL $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(BUILD)/.network-protocol $(CC) $(CPPFLAGS) -DDAT_CLI_NAME=\"dat\" $(CFLAGS) $(LDFLAGS) src/dat_cli.c $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) -o $@ $(BUILD)/ddat: src/dat_cli.c NETWORK_PROTOCOL $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(BUILD)/.network-protocol $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) src/dat_cli.c $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) -o $@ $(BUILD)/cable: src/cable_cli.c $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $< $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) -o $@ $(BUILD)/cesspool-bootstrap: libcess/tools/cesspool-bootstrap.c $(BUILD)/libcess.a $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $< $(BUILD)/libcess.a $(SODIUM_LIBS) -o $@ $(BUILD)/ddat-scheme: src/dat_scheme_cli.c $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(CC) $(CPPFLAGS) -DDAT_SCHEME_DIR=\"$(DAT_SCHEME_DIR)\" $(CFLAGS) $(LDFLAGS) $< $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) -o $@ SDL2_CFLAGS ?= $(shell pkg-config --cflags sdl2) SDL2_LIBS ?= $(shell pkg-config --libs sdl2) SDL2_TTF_CFLAGS ?= $(shell pkg-config --cflags SDL2_ttf) SDL2_TTF_LIBS ?= $(shell pkg-config --libs SDL2_ttf) DAT_FONT_PATH ?= $(PREFIX)/share/datgpt/fonts/MorePerfectDOSVGA.ttf DAT_UNIFONT_PATH ?= $(PREFIX)/share/datgpt/fonts/Unifont-18.0.01.otf DAT_SPEAKER_PATH ?= $(PREFIX)/share/datgpt/icons/datthang-speaker.bmp ifeq ($(ENABLE_SDL2),1) GUI_CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DDAT_FONT_PATH=\"$(DAT_FONT_PATH)\" -DDAT_UNIFONT_PATH=\"$(DAT_UNIFONT_PATH)\" -DDAT_SPEAKER_PATH=\"$(DAT_SPEAKER_PATH)\" GUI_INSTALL = rm -f "$(DESTDIR)$(PREFIX)/bin/ddat-gui" && \ $(INSTALL) -d "$(DESTDIR)$(PREFIX)/share/datgpt/fonts" "$(DESTDIR)$(PREFIX)/share/datgpt/icons" && \ $(INSTALL) -m 644 assets/fonts/MorePerfectDOSVGA.ttf "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/MorePerfectDOSVGA.ttf" && \ $(INSTALL) -m 644 assets/fonts/Unifont-18.0.01.otf "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/Unifont-18.0.01.otf" && \ $(INSTALL) -m 644 assets/fonts/Unifont-OFL-1.1.txt "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/Unifont-OFL-1.1.txt" && \ $(INSTALL) -m 644 assets/datthang-speaker.bmp "$(DESTDIR)$(PREFIX)/share/datgpt/icons/datthang-speaker.bmp" && \ $(INSTALL) -m 755 $(BUILD)/dat-thang "$(DESTDIR)$(PREFIX)/bin/dat-thang" && \ $(INSTALL) -m 644 docs/dat-thang.1 "$(DESTDIR)$(PREFIX)/share/man/man1/dat-thang.1" && \ $(INSTALL) -m 755 $(BUILD)/cable-thang "$(DESTDIR)$(PREFIX)/bin/cable-thang" && \ $(INSTALL) -m 644 docs/cable-thang.1 "$(DESTDIR)$(PREFIX)/share/man/man1/cable-thang.1" && \ $(INSTALL) -m 644 docs/ddat-gui.md "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/ddat-gui.md" else GUI_INSTALL = : endif $(BUILD)/dat-thang: src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a assets/fonts/MorePerfectDOSVGA.ttf assets/datthang-speaker.bmp | $(BUILD) $(CC) $(CPPFLAGS) -DDAT_THANG_VERSION=\"v$(VERSION)\" $(GUI_CPPFLAGS) $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS) $(LDFLAGS) src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) $(SDL2_TTF_LIBS) $(SDL2_LIBS) $(CABLE_MEDIA_LIBS) -lm -o $@ $(BUILD)/cable_media.o: src/cable_media.c inc/cable_media.h | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) $(CABLE_MEDIA_CFLAGS) -MMD -MP -c $< -o $@ $(BUILD)/cable_video.o: src/cable_video.c inc/cable_video.h | $(BUILD) $(CC) $(CPPFLAGS) $(SDL2_CFLAGS) $(CFLAGS) $(CABLE_MEDIA_CFLAGS) -MMD -MP -c $< -o $@ $(BUILD)/cable-thang: src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a assets/fonts/MorePerfectDOSVGA.ttf assets/datthang-speaker.bmp | $(BUILD) $(CC) $(CPPFLAGS) -DDAT_THANG_VERSION=\"v$(VERSION)\" $(GUI_CPPFLAGS) $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS) $(LDFLAGS) src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) $(SDL2_TTF_LIBS) $(SDL2_LIBS) $(CABLE_MEDIA_LIBS) -lm -o $@ .PHONY: gui gui: $(BUILD)/dat-thang # Native Dillo DPI plugin; dpid supplies an authenticated socket on stdin/stdout. $(BUILD)/dat.dpi: src/dat_dpi.c src/dat_dpi_icons.h NETWORK_PROTOCOL $(BUILD)/libdatgpt-dpi.a $(BUILD)/libcess.a $(BUILD)/dpi_s7.o $(BUILD)/.network-protocol $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) src/dat_dpi.c $(BUILD)/libdatgpt-dpi.a $(BUILD)/libcess.a $(BUILD)/dpi_s7.o $(LIBS) -o $@ $(BUILD)/test_%: tests/test_%.c $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(TEST_LDFLAGS) $< $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) -o $@ $(BUILD)/test_dpi_socket: tests/test_dpi_socket.c | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $< -o $@ $(BUILD)/test_gui_p2p: tests/test_gui_p2p.c src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a assets/fonts/MorePerfectDOSVGA.ttf assets/datthang-speaker.bmp $(CC) $(CPPFLAGS) $(GUI_CPPFLAGS) $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS) $(LDFLAGS) $(TEST_LDFLAGS) $< $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) $(SDL2_TTF_LIBS) $(SDL2_LIBS) $(CABLE_MEDIA_LIBS) -lm -o $@ $(BUILD)/test_version_bar: tests/test_version_bar.c src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a assets/fonts/MorePerfectDOSVGA.ttf assets/datthang-speaker.bmp $(CC) $(CPPFLAGS) $(GUI_CPPFLAGS) $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS) $(LDFLAGS) $(TEST_LDFLAGS) $< $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) $(SDL2_TTF_LIBS) $(SDL2_LIBS) $(CABLE_MEDIA_LIBS) -lm -o $@ $(BUILD)/test_cable_thang: tests/test_cable_thang.c src/ddat_gui.c $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a assets/fonts/MorePerfectDOSVGA.ttf assets/datthang-speaker.bmp $(CC) $(CPPFLAGS) $(GUI_CPPFLAGS) $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS) $(LDFLAGS) $(TEST_LDFLAGS) $< $(BUILD)/cable_media.o $(BUILD)/cable_video.o $(BUILD)/libdatgpt.a $(BUILD)/libcess.a $(LIBS) $(SDL2_TTF_LIBS) $(SDL2_LIBS) $(CABLE_MEDIA_LIBS) -lm -o $@ $(TESTS): $(PUBLIC_HEADERS) test: all $(TESTS) $(GUI_TESTS) $(BUILD)/test_dpi_socket @echo "TEST Cable address CLI" @$(BUILD)/cable address cabal://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | grep -q '^cable://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$' @$(BUILD)/cable address hyper://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | grep -q '^cable://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$' @echo "TEST Cabal JS/Cable side-by-side room and user identity" @if command -v "$(NODE)" >/dev/null 2>&1 && CABAL_JS_MODULE="$(CABAL_JS_MODULE)" "$(NODE)" -e 'require(process.env.CABAL_JS_MODULE)' >/dev/null 2>&1; then \ CABAL_JS_MODULE="$(CABAL_JS_MODULE)" CABAL_BIN="$(CURDIR)/$(BUILD)/cable" "$(NODE)" tests/interop/cabal/cabal_cable_side_by_side.js; \ else echo "SKIP Cabal JS/Cable interop (run make test-cabal-interop on a host with Node and cabal-core installed)"; fi @if command -v "$(NODE)" >/dev/null 2>&1 && CABAL_CLIENT_MODULE="$(CABAL_CLIENT_MODULE)" "$(NODE)" -e 'require(process.env.CABAL_CLIENT_MODULE)' >/dev/null 2>&1; then \ CABAL_CLIENT_MODULE="$(CABAL_CLIENT_MODULE)" "$(NODE)" tests/interop/cabal/cabal_cli_features.js; \ else echo "SKIP cabal-cli multi-peer workflows (run make test-cabal-interop on a host with Node and cabal-client installed)"; fi @if test "$(ENABLE_SDL2)" = 1 && command -v "$(NODE)" >/dev/null 2>&1 && CABAL_JS_MODULE="$(CABAL_JS_MODULE)" "$(NODE)" -e 'require(process.env.CABAL_JS_MODULE)' >/dev/null 2>&1; then \ CABAL_JS_MODULE="$(CABAL_JS_MODULE)" CABLE_CABAL_CORE="$(CABAL_JS_MODULE)" "$(NODE)" tests/interop/cabal/cable_js_c_live.js $(BUILD)/test_cable_thang; \ else echo "SKIP C SDL/Cabal JS live test (use make test-cable-live ENABLE_SDL2=1 with Node and cabal-core installed)"; fi @echo "TEST bundled S7 JSON/S-expression adapter" @json_output=$$($(BUILD)/ddat-scheme tests/test-json.scm 2>&1); \ printf '%s\n' "$$json_output"; \ printf '%s\n' "$$json_output" | grep -q '^S7 JSON/S-expression adapter: PASS$$'; \ ! printf '%s\n' "$$json_output" | grep -q '^;' @if command -v "$(NODE)" >/dev/null 2>&1; then "$(NODE)" tests/interop/cabal/cable_sexpr_boundary.js; fi @set -e; for test_program in $(TESTS); do echo "TEST $$test_program"; $$test_program; done @set -e; for test_program in $(GUI_TESTS); do echo "TEST $$test_program"; SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy $$test_program; done @echo "TEST current Dillo DPIP helper protocol" @sh tests/test_dpi.sh $(BUILD)/dat.dpi $(BUILD)/dat $(BUILD)/test_dpi_socket @set -e; cli_root=$$(mktemp -d /tmp/datgpt-cli.XXXXXX); mkdir -p "$$cli_root/home"; \ echo "TEST dat doctor local network primitives"; \ $(BUILD)/ddat doctor | grep -q '^cesspool: UDP socket bound on 127.0.0.1:'; \ $(BUILD)/ddat doctor 0000000000000000000000000000000000000000000000000000000000000000 | grep -q '^address: dat://'; \ $(BUILD)/ddat --help | grep -q '^ddat '; \ echo "TEST dat create/sync/log and dat:// address"; \ HOME="$$cli_root/home" $(BUILD)/dat create "$$cli_root/archive" --title "hello" --description "archive test" > "$$cli_root/url"; \ grep -q '^dat://' "$$cli_root/url"; \ cp "$$cli_root/url" "$$cli_root/original-url"; \ HOME="$$cli_root/home" $(BUILD)/dat dns set archive.example.test "$$cli_root/archive" > "$$cli_root/dns-set"; \ grep -q '^DAT-DNS /.well-known/dat:$$' "$$cli_root/dns-set"; \ HOME="$$cli_root/home" $(BUILD)/dat resolve archive.example.test | grep -q '^dat://'; \ HOME="$$cli_root/home" $(BUILD)/dat dns list | grep -q '^archive.example.test[[:space:]]'; \ HOME="$$cli_root/home" $(BUILD)/dat dns remove archive.example.test; \ mkdir -p "$$cli_root/empty-home"; \ cp "$$cli_root/archive/.dat/metadata.key" "$$cli_root/metadata-key-before-readonly-sync"; \ if HOME="$$cli_root/empty-home" $(BUILD)/dat sync "$$cli_root/archive" >/dev/null 2>&1; then exit 1; fi; \ cmp "$$cli_root/metadata-key-before-readonly-sync" "$$cli_root/archive/.dat/metadata.key"; \ grep -q '(title "hello")' "$$cli_root/archive/dat.scm"; \ grep -q '(description "archive test")' "$$cli_root/archive/dat.scm"; \ grep -q '(url "dat://' "$$cli_root/archive/dat.scm"; \ $(BUILD)/dat log "$$cli_root/archive" | grep -q dat.scm; \ test ! -e "$$cli_root/archive/dat.json"; \ HOME="$$cli_root/home" $(BUILD)/dat create "$$cli_root/empty" --yes > /dev/null; \ test -f "$$cli_root/empty/dat.scm"; \ test ! -e "$$cli_root/empty/dat.json"; \ mkdir -p "$$cli_root/scheme-created"; \ $(BUILD)/ddat-scheme -e "(dat-close (dat-create \"$$cli_root/scheme-created\"))" >/dev/null; \ grep -q '(title "scheme-created")' "$$cli_root/scheme-created/dat.scm"; \ $(BUILD)/dat log "$$cli_root/scheme-created" | grep -q dat.scm; \ echo hello > "$$cli_root/archive/hello.txt"; \ echo hidden > "$$cli_root/archive/.hidden"; \ echo '*.skip' > "$$cli_root/archive/.datignore"; \ echo ignored > "$$cli_root/archive/ignored.skip"; \ HOME="$$cli_root/home" $(BUILD)/dat sync "$$cli_root/archive" > /dev/null; \ $(BUILD)/dat status "$$cli_root/archive" | sed -n 's/^Archive: //p' > "$$cli_root/updated-url"; \ cmp "$$cli_root/original-url" "$$cli_root/updated-url"; \ $(BUILD)/dat status "$$cli_root/archive" | grep -q 'Metadata entries:'; \ $(BUILD)/dat url --compact '' "$$cli_root/archive" | grep -q '^dat://'; \ $(BUILD)/dat files "$$cli_root/archive" | grep -q hello.txt; \ $(BUILD)/dat verify "$$cli_root/archive" >/dev/null; \ $(BUILD)/dat log "$$cli_root/archive" | grep -q hello.txt; \ ! $(BUILD)/dat log "$$cli_root/archive" | grep -qE '\.(hidden|datignore)|ignored\.skip'; \ old_version=$$($(BUILD)/dat log "$$cli_root/archive" | awk '/hello.txt/{print $$1; exit}'); \ echo newer > "$$cli_root/archive/hello.txt"; \ HOME="$$cli_root/home" $(BUILD)/dat sync "$$cli_root/archive" > /dev/null; \ test "$$($(BUILD)/dat cat "$$old_version" /hello.txt "$$cli_root/archive")" = hello; \ $(BUILD)/dat url "$$old_version" /hello.txt "$$cli_root/archive" | \ grep -Eq "^dat://[0-9a-f]{64}\\+$$old_version/hello.txt$$"; \ $(BUILD)/dat checkout "$$old_version" "$$cli_root/snapshot" "$$cli_root/archive"; \ test "$$(cat "$$cli_root/snapshot/hello.txt")" = hello; \ versions_before=$$($(BUILD)/dat log "$$cli_root/archive" | wc -l); \ HOME="$$cli_root/home" $(BUILD)/dat sync "$$cli_root/archive" > /dev/null; \ test "$$($(BUILD)/dat log "$$cli_root/archive" | wc -l)" = "$$versions_before"; \ $(BUILD)/dat files "$$old_version" "$$cli_root/archive" | grep -q hello.txt; \ rm "$$cli_root/archive/hello.txt"; \ HOME="$$cli_root/home" $(BUILD)/dat sync "$$cli_root/archive" > /dev/null; \ $(BUILD)/dat log "$$cli_root/archive" | grep -q 'del .*hello.txt' @echo "TEST historical .dat fixture" @$(BUILD)/sleep-verify .dat @echo "TEST dat/ddat side-by-side archive compatibility" @sh tests/test_cli_parity.sh $(BUILD)/dat $(BUILD)/ddat test-cabal-interop: $(BUILD)/cable CABAL_JS_MODULE="$(CABAL_JS_MODULE)" CABAL_BIN="$(CURDIR)/$(BUILD)/cable" "$(NODE)" tests/interop/cabal/cabal_cable_side_by_side.js CABAL_CLIENT_MODULE="$(CABAL_CLIENT_MODULE)" "$(NODE)" tests/interop/cabal/cabal_cli_features.js CABAL_JS_MODULE="$(CABAL_JS_MODULE)" CABLE_CABAL_CORE="$(CABAL_JS_MODULE)" "$(NODE)" tests/interop/cabal/cabal_core_hyperswarm_live.js ifeq ($(ENABLE_SDL2),1) test-cable-live: $(BUILD)/test_cable_thang CABAL_JS_MODULE="$(CABAL_JS_MODULE)" CABLE_CABAL_CORE="$(CABAL_JS_MODULE)" "$(NODE)" tests/interop/cabal/cable_js_c_live.js $(BUILD)/test_cable_thang else test-cable-live: @echo "test-cable-live requires ENABLE_SDL2=1, SDL2, Node.js, and Cabal Core" >&2 @exit 2 endif install: all $(INSTALL) -d "$(DESTDIR)$(PREFIX)/lib" "$(DESTDIR)$(PREFIX)/include/datgpt" "$(DESTDIR)$(PREFIX)/include/libcess" "$(DESTDIR)$(PREFIX)/bin" "$(DESTDIR)$(PREFIX)/share/man/man1" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt" "$(DESTDIR)$(DPIDIR)" $(INSTALL) -m 644 $(BUILD)/libdatgpt.a "$(DESTDIR)$(PREFIX)/lib/libdatgpt.a" $(INSTALL) -m 644 $(BUILD)/libcess.a "$(DESTDIR)$(PREFIX)/lib/libcess.a" $(INSTALL) -m 644 $(PUBLIC_HEADERS) "$(DESTDIR)$(PREFIX)/include/datgpt/" $(INSTALL) -m 644 libcess/include/cesspool.h libcess/include/cess_net.h libcess/include/cess_compat.h "$(DESTDIR)$(PREFIX)/include/libcess/" $(INSTALL) -m 755 $(BUILD)/sleep-verify "$(DESTDIR)$(PREFIX)/bin/sleep-verify" $(INSTALL) -m 755 $(BUILD)/ddat "$(DESTDIR)$(PREFIX)/bin/ddat" $(INSTALL) -m 755 $(BUILD)/cable "$(DESTDIR)$(PREFIX)/bin/cable" $(INSTALL) -m 755 $(BUILD)/cesspool-bootstrap "$(DESTDIR)$(PREFIX)/bin/cesspool-bootstrap" $(S7_INSTALL) $(GUI_INSTALL) $(S7_SCHEME_INSTALL) $(INSTALL) -m 755 $(BUILD)/dat.dpi "$(DESTDIR)$(DPIDIR)/dat.dpi" $(INSTALL) -m 644 docs/dat.1 "$(DESTDIR)$(PREFIX)/share/man/man1/dat.1" $(INSTALL) -m 644 docs/cable.1 "$(DESTDIR)$(PREFIX)/share/man/man1/cable.1" $(INSTALL) -m 644 docs/cesspool-bootstrap.1 "$(DESTDIR)$(PREFIX)/share/man/man1/cesspool-bootstrap.1" $(INSTALL) -m 644 docs/libcess.md "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/libcess.md" $(INSTALL) -m 644 docs/key-management.md docs/cable-interop.md docs/ddat-gui.md docs/dillo.md "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/" # Build an install-tree archive suitable for Linux distribution and testing. # System libraries remain explicit runtime dependencies; this is not an AppImage. package: package-linux package-linux: all rm -rf "$(PACKAGE_STAGE)" $(MAKE) BUILD="$(BUILD)" DESTDIR="$(PACKAGE_STAGE)" PREFIX=/usr install mkdir -p "$(PACKAGE_DIR)" tar -czf "$(PACKAGE_DIR)/dat-gpt-$(VERSION)-linux-$(PACKAGE_ARCH).tar.gz" -C "$(PACKAGE_STAGE)" . uninstall: rm -f "$(DESTDIR)$(PREFIX)/lib/libdatgpt.a" "$(DESTDIR)$(PREFIX)/lib/libcess.a" "$(DESTDIR)$(PREFIX)/include/libcess/cesspool.h" "$(DESTDIR)$(PREFIX)/include/libcess/cess_net.h" "$(DESTDIR)$(PREFIX)/include/libcess/cess_compat.h" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/libcess.md" "$(DESTDIR)$(PREFIX)/bin/sleep-verify" "$(DESTDIR)$(PREFIX)/bin/ddat" "$(DESTDIR)$(PREFIX)/bin/cable" "$(DESTDIR)$(PREFIX)/bin/cesspool-bootstrap" "$(DESTDIR)$(PREFIX)/bin/ddat-scheme" "$(DESTDIR)$(PREFIX)/bin/ddat-gui" "$(DESTDIR)$(PREFIX)/bin/dat-thang" "$(DESTDIR)$(PREFIX)/bin/cable-thang" "$(DESTDIR)$(DPIDIR)/dat.dpi" "$(DESTDIR)$(PREFIX)/share/datgpt/cable_hyperswarm.js" "$(DESTDIR)$(PREFIX)/share/datgpt/cable_bootstrap.js" "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/MorePerfectDOSVGA.ttf" "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/Unifont-18.0.01.otf" "$(DESTDIR)$(PREFIX)/share/datgpt/fonts/Unifont-OFL-1.1.txt" "$(DESTDIR)$(PREFIX)/share/datgpt/icons/datthang-speaker.bmp" "$(DESTDIR)$(PREFIX)/share/man/man1/dat.1" "$(DESTDIR)$(PREFIX)/share/man/man1/cable.1" "$(DESTDIR)$(PREFIX)/share/man/man1/cesspool-bootstrap.1" "$(DESTDIR)$(PREFIX)/share/man/man1/dat-thang.1" "$(DESTDIR)$(PREFIX)/share/man/man1/cable-thang.1" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/key-management.md" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/cable-interop.md" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/ddat-gui.md" "$(DESTDIR)$(PREFIX)/share/doc/dat-gpt/dillo.md" $(S7_UNINSTALL) @for header in $(notdir $(PUBLIC_HEADERS)); do rm -f "$(DESTDIR)$(PREFIX)/include/datgpt/$$header"; done clean: @if test -d "$(BUILD)"; then find "$(BUILD)" -type f \( -name '*.o' -o -name '*.d' -o -name '*.a' -o -name '*.so' -o -name '*.so.*' -o -name '*.dll' -o -name '*.exe' \) -delete; fi rm -f "$(BUILD)/.network-protocol" "$(BUILD)/.network-protocol.tmp" "$(BUILD)/libdatgpt.a" "$(BUILD)/libdatgpt-dpi.a" "$(BUILD)/libcess.a" "$(BUILD)/dat" "$(BUILD)/ddat" "$(BUILD)/cable" "$(BUILD)/cesspool-bootstrap" "$(BUILD)/sleep-verify" "$(BUILD)/ddat-scheme" "$(BUILD)/dat.dpi" "$(BUILD)/dat-thang" "$(BUILD)/cable-thang" "$(BUILD)/test_"* "$(BUILD)/test-*" rm -rf "$(BUILD)/dpi" "$(BUILD)/libcess" $(MAKE) -C libcess clean distclean: clean rm -f config.mk config.h config.log