# The MIT License (MIT) # # Copyright (C) 2026 Scott Duensing # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # DVX GUI -- Top-level Makefile # # Builds the full DVX stack: core library, task switcher, # bootstrap loader, text help library, widgets, shell, and apps. # # Source tree mirrors bin/ layout: # src/libs/kpunch// -> bin/libs/kpunch//.lib # src/widgets/kpunch// -> bin/widgets/kpunch//.wgt # src/apps/kpunch// -> bin/apps/kpunch//.app # src/loader/ -> bin/DVX.EXE # src/tools/ -> bin/host/ # Libraries are discovered, never listed: every src/libs/kpunch// # with a Makefile is one. Run-time load order comes from each library's # .dep file; the build only needs the core libraries first (and the shell # before the task manager, which links against it). LIBS = $(sort $(notdir $(patsubst %/Makefile,%,$(wildcard src/libs/kpunch/*/Makefile)))) CORE_LIBS = libdvx libtasks .PHONY: all clean $(LIBS) loader widgets apps tools deploy-helpsrc compile-help deploy-sdk test test-quick test-asan test-host test-samples coverage all: $(LIBS) loader tools widgets apps deploy-helpsrc compile-help deploy-sdk $(LIBS): $(MAKE) -C src/libs/kpunch/$@ $(filter-out $(CORE_LIBS),$(LIBS)): $(CORE_LIBS) taskmgr: dvxshell loader: libdvx libtasks $(MAKE) -C src/loader # Every .wgt recipe runs bin/host/dvxres, so widgets need the tools. widgets: libdvx libtasks texthelp listhelp tools $(MAKE) -C src/widgets/kpunch tools: $(MAKE) -C src/tools apps: libdvx libtasks dvxshell tools $(MAKE) -C src/apps/kpunch # Copies help sources into the module directories under bin/, so every # module that owns one must be built first. deploy-helpsrc: $(LIBS) widgets apps tools $(MAKE) -C src/tools deploy-helpsrc # Host-side tests. Every suite is native gcc; the GUI suites build # obj/host/libdvx.a, the widget .so files and libdvxtest.a themselves # (sanitizers on by default, SAN=1). # make test -- everything: BASIC harnesses + fuzz, sample goldens, # proxy build, all host suites, tools goldens, lint gate # make test-quick -- same minus the fuzzers, static analyzer and tools # make test-asan -- BASIC harnesses rebuilt under ASan/UBSan plus the # host suites (which are already sanitized) DVXBASIC_DIR = src/apps/kpunch/dvxbasic # HOST_SUITES: the one list of host suites (shared with runCoverage.sh). include src/test/suites.mk test: apps $(MAKE) -C $(DVXBASIC_DIR) tests $(MAKE) -C src/tools/proxy $(MAKE) test-samples $(MAKE) test-host src/test/tools/runTools.sh $(MAKE) -C src/test/lint test-quick: apps $(MAKE) -C $(DVXBASIC_DIR) tests FUZZ_N=0 $(MAKE) test-samples $(MAKE) test-host $(MAKE) -C src/test/lint style ascii test-asan: apps $(MAKE) -C $(DVXBASIC_DIR) tests TESTSAN=1 $(MAKE) test-host # Runs every suite even after a failure, then fails naming the failed ones. test-host: @failed=""; for d in $(HOST_SUITES); do $(MAKE) -C src/test/$$d || failed="$$failed $$d"; done; \ if [ -n "$$failed" ]; then echo "test-host: FAILED suites:$$failed"; exit 1; fi test-samples: src/test/samples/runSamples.sh # The real DOS build in an emulator (src/test/dos/runDos.sh; not part of # make test). EMULATOR=86box (default) or dosbox; SCRIPTS= a subset. test-dos: all src/test/dos/runDos.sh $(or $(EMULATOR),86box) --no-build $(SCRIPTS) # Line coverage of the host suites: rebuilds everything with gcc # --coverage (no sanitizers) under obj/hostcov, runs the BASIC # harnesses, sample goldens and every host suite, then writes the # report to obj/coverage/html and prints a per-directory summary. coverage: tools $(MAKE) -C src/test/coverage HLPC = bin/host/dvxhlpc HELP_FILES = src/tools/helpFiles.sh # The system help: the user guide (userHelp.dhs, kept beside Program # Manager; Program Manager's own progman.dhs is its separate progman.hlp), # then the library reference found by $(HELP_FILES), then the widget # reference. Libraries, apps and widgets are discovered, so adding one # needs no edit here. USER_GUIDE_DHS = src/apps/kpunch/progman/userHelp.dhs BASIC_DHS = src/apps/kpunch/dvxbasic/ideguide.dhs src/apps/kpunch/dvxbasic/langref.dhs \ src/apps/kpunch/dvxbasic/ctrlover.dhs src/apps/kpunch/dvxbasic/form.dhs # Needs bin/host/dvxhlpc, and every module built and its help deployed # (library and app help are classified by the modules found in bin/). # Each app's own help (.dhs beside its source) becomes .hlp # next to .app. compile-help: deploy-helpsrc @mkdir -p docs $(HLPC) -o bin/apps/kpunch/dvxhelp/dvxhelp.hlp \ --html docs/dvx_help_viewer.html \ src/apps/kpunch/dvxhelp/help.dhs libHelp=$$($(HELP_FILES) libs) && \ $(HLPC) -o bin/apps/kpunch/progman/dvxhelp.hlp \ --html docs/dvx_system_reference.html \ -i src/libs/kpunch/libdvx \ $(USER_GUIDE_DHS) \ $$libHelp \ src/widgets/kpunch/wgtsys.dhs \ $$(find src/widgets/kpunch -name "*.dhs" ! -path "*/wgtsys.dhs" | sort) $(HLPC) -o bin/apps/kpunch/dvxbasic/dvxbasic.hlp \ --html docs/dvx_basic_reference.html \ $(BASIC_DHS) \ $$(find src/widgets/kpunch -name "*.bhs" | sort) $(HELP_FILES) compile $(HLPC) SDKDIR = bin/sdk # Public header lists (SDK_*_H), shared with the ABI size test. SDK_ROOT = include src/sdkHeaders.mk # The SDK's own files (README, sdk.mk, newProject.sh, project templates) # live in src/sdk; its bin/ holds the host tools a project build runs. SDK_SRC = src/sdk SDK_TOOLS = bin/host/dvxres bin/host/dvxhlpc bin/host/bascomp src/tools/dxeGen.sh # The host tools come from tools (dvxres, dvxhlpc) and apps (bascomp). deploy-sdk: tools apps @echo "Building SDK..." @# Start from an empty tree so a header dropped from the lists goes away. rm -rf $(SDKDIR) @mkdir -p $(SDKDIR)/bin $(SDKDIR)/include/core $(SDKDIR)/include/shell $(SDKDIR)/include/tasks $(SDKDIR)/include/sql $(SDKDIR)/include/texthelp $(SDKDIR)/include/listhelp $(SDKDIR)/include/fileops $(SDKDIR)/include/xfer $(SDKDIR)/include/conn $(SDKDIR)/include/print $(SDKDIR)/include/net $(SDKDIR)/include/basic $(SDKDIR)/samples/basic/basdemo $(SDKDIR)/samples/basic/widshow cp $(SDK_CORE_H) $(SDKDIR)/include/core/ cp $(SDK_SHELL_H) $(SDKDIR)/include/shell/ cp $(SDK_TASKS_H) $(SDKDIR)/include/tasks/ cp $(SDK_SQL_H) $(SDKDIR)/include/sql/ cp $(SDK_TEXTHELP_H) $(SDKDIR)/include/texthelp/ cp $(SDK_LISTHELP_H) $(SDKDIR)/include/listhelp/ cp $(SDK_FILEOPS_H) $(SDKDIR)/include/fileops/ cp $(SDK_XFER_H) $(SDKDIR)/include/xfer/ cp $(SDK_CONN_H) $(SDKDIR)/include/conn/ cp $(SDK_PRINT_H) $(SDKDIR)/include/print/ @# Networking: dvxNet.h and the standard socket headers, which keep their @# subdirectories (sys/, netinet/, arpa/); sdk.mk adds include/net only @# for programs that set NET = 1. cp $(SDK_NET_H) $(SDKDIR)/include/net/ @for h in $(SDK_NET_STD_H); do \ mkdir -p $(SDKDIR)/include/net/$$(dirname $$h) && cp $(SDK_NET_DIR)/$$h $(SDKDIR)/include/net/$$h || exit 1; \ done @for h in $(SDK_SERIAL_H); do \ mkdir -p $(SDKDIR)/include/serial/$$(dirname $$h) && cp $(SDK_SERIAL_DIR)/$$h $(SDKDIR)/include/serial/$$h || exit 1; \ done @# Widget headers -- one subdir per widget @for h in $(SDK_WIDGET_H); do \ wgt=$$(basename $$(dirname $$h)); \ mkdir -p $(SDKDIR)/include/widget/$$wgt && cp $$h $(SDKDIR)/include/widget/$$wgt/ || exit 1; \ done @# BASIC include files @cp src/include/basic/*.bas $(SDKDIR)/include/basic/ @# BASIC sample: basdemo (project file + form + icon + help source) @cp src/apps/kpunch/basdemo/basdemo.dbp $(SDKDIR)/samples/basic/basdemo/ @cp src/apps/kpunch/basdemo/basdemo.frm $(SDKDIR)/samples/basic/basdemo/ @cp src/apps/kpunch/basdemo/basdemo.dhs $(SDKDIR)/samples/basic/basdemo/ @cp src/apps/kpunch/basdemo/ICON32.BMP $(SDKDIR)/samples/basic/basdemo/ @# BASIC sample: widshow (widget showcase) @cp src/apps/kpunch/widshow/widshow.dbp $(SDKDIR)/samples/basic/widshow/ @cp src/apps/kpunch/widshow/widshow.frm $(SDKDIR)/samples/basic/widshow/ @cp src/apps/kpunch/widshow/widshow.dhs $(SDKDIR)/samples/basic/widshow/ @cp src/apps/kpunch/widshow/ICON32.BMP $(SDKDIR)/samples/basic/widshow/ @# SDK files, project templates and the host tools cp $(SDK_SRC)/README.TXT $(SDK_SRC)/sdk.mk $(SDK_SRC)/newProject.sh $(SDKDIR)/ cp -R $(SDK_SRC)/templates $(SDKDIR)/ cp $(SDK_TOOLS) $(SDKDIR)/bin/ # Every build output: the DOS targets through each directory's clean, # then the whole object tree (host libraries, test binaries, coverage) # and the host-only bin/ directories. clean: for d in $(LIBS); do $(MAKE) -C src/libs/kpunch/$$d clean || exit 1; done $(MAKE) -C src/loader clean $(MAKE) -C src/widgets/kpunch clean $(MAKE) -C src/apps/kpunch clean $(MAKE) -C src/tools clean $(MAKE) -C src/tools/proxy clean rm -rf obj bin/host bin/test bin/system rm -rf bin/config bin/widgets bin/libs bin/sdk rm -f docs/*.html