diff --git a/README.md b/README.md index 9b69cb0d..6a71088f 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,11 @@ We provide a script that makes it easy to start a new package: examples/package/new.sh com/github/user/project emacs com/github/user/project/program.c - make o//com/github/user/project/program.c - o//com/github/user/project/program.c + make o//com/github/user/project/program.com + o//com/github/user/project/program.com Please note GNU make is awesome. Little known fact: make is a functional -programming language. We've improve upon it too see tool/build/package.c +programming language. We improved upon it too! In [tool/build/package.c] which performs strict dependency checking, to correct Google's published mistakes c. 2006 which was when they switched from using a GNU Make repo in favor of an inhouse derivative called Blaze which does strictness too @@ -244,5 +244,13 @@ please let us know so we can reach out and ask they consider a license.   @             °→      ♠←       ←      2←      L←      ╲←       x←                                                               -See also `build/dump -xd o/tiny/examples/life.com.dbg | less` assembly -and our linker script [ape/ape.lds] which glues the binaries together. +See also `build/objdump -xd o/tiny/examples/life.com.dbg | less` to view +assembly and the linker glue in [ape/ape.lds] that makes it all possible + + +[ape/ape.lds]: ape/ape.lds +[examples/life.c]: examples/life.c +[libc/sysv/consts.sh]: libc/sysv/consts.sh +[libc/sysv/syscalls.sh]: libc/sysv/syscalls.sh +[tool/build/package.c]: tool/build/package.c +[tool/emacs/cosmo-stuff.el]: tool/emacs/cosmo-stuff.el diff --git a/examples/package/README.md b/examples/package/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/package/package.mk b/examples/package/build.mk similarity index 81% rename from examples/package/package.mk rename to examples/package/build.mk index 2bd4544f..183067f6 100644 --- a/examples/package/package.mk +++ b/examples/package/build.mk @@ -14,6 +14,10 @@ # # make o//examples/package # o/examples/package/program.com +# +# AUTHORS +# +# %AUTHOR% PKGS += EXAMPLES_PACKAGE @@ -24,15 +28,15 @@ EXAMPLES_PACKAGE_FILES := $(wildcard examples/package/*) EXAMPLES_PACKAGE_SRCS = $(filter %.c,$(EXAMPLES_PACKAGE_FILES)) EXAMPLES_PACKAGE_HDRS = $(filter %.h,$(EXAMPLES_PACKAGE_FILES)) EXAMPLES_PACKAGE_COMS = $(EXAMPLES_PACKAGE_OBJS:%.o=%.com) +EXAMPLES_PACKAGE_BINS = \ + $(EXAMPLES_PACKAGE_COMS) \ + $(EXAMPLES_PACKAGE_COMS:%=%.dbg) # Remaps source file names to object names. # Also asks a wildcard rule to automatically run tool/build/zipobj.c EXAMPLES_PACKAGE_OBJS = \ $(EXAMPLES_PACKAGE_SRCS:%.c=o/$(MODE)/%.o) \ $(EXAMPLES_PACKAGE_SRCS:%=o/$(MODE)/%.zip.o) -EXAMPLES_PACKAGE_BINS = \ - $(EXAMPLES_PACKAGE_COMS) \ - $(EXAMPLES_PACKAGE_COMS:%=%.dbg) # Lists packages whose symbols are or may be directly referenced here. # Note that linking stubs is always a good idea due to synthetic code. @@ -46,13 +50,7 @@ EXAMPLES_PACKAGE_DIRECTDEPS = \ EXAMPLES_PACKAGE_DEPS := \ $(call uniq,$(foreach x,$(EXAMPLES_PACKAGE_DIRECTDEPS),$($(x)))) -# Invalidates objects in this package when this makefile is edited -$(EXAMPLES_PACKAGE_OBJS): examples/package/vizlib.mk - -# Asks packager to index symbols and validate their relationships. -# @see tool/build/package.c -# @see build/rules.mk -o/$(MODE)/examples/package/build.pkg: \ +$(EXAMPLES_PACKAGE_A).pkg: \ $(EXAMPLES_PACKAGE_OBJS) \ $(foreach x,$(EXAMPLES_PACKAGE_DIRECTDEPS),$($(x)_A).pkg) @@ -60,15 +58,16 @@ o/$(MODE)/examples/package/build.pkg: \ # @see build/rules.mk for definition of rule that does .com.dbg -> .com o/$(MODE)/examples/package/%.com.dbg: \ $(EXAMPLES_PACKAGE_DEPS) \ - o/$(MODE)/examples/package/package.pkg \ o/$(MODE)/examples/package/%.o \ $(CRT) \ $(APE) - -@$(APELINK) + @$(APELINK) -# Creates target that builds everything in this package and subpackages. +# Invalidates objects in package when makefile is edited. +$(EXAMPLES_PACKAGE_OBJS): examples/package/build.mk + +# Creates target building everything in package and subpackages. .PHONY: o/$(MODE)/examples/package o/$(MODE)/examples/package: \ o/$(MODE)/examples/package/lib \ - $(EXAMPLES_PACKAGE_BINS) \ - $(EXAMPLES_PACKAGE_CHECKS) + $(EXAMPLES_PACKAGE_BINS) diff --git a/examples/package/lib/lib.mk b/examples/package/lib/build.mk similarity index 50% rename from examples/package/lib/lib.mk rename to examples/package/lib/build.mk index b85244db..2e39419f 100644 --- a/examples/package/lib/lib.mk +++ b/examples/package/lib/build.mk @@ -9,47 +9,87 @@ # # Your library doesn't have a main() function and can be compromised # of sources written in multiple languages. +# +# WARNING +# +# This library (examples/package/lib/) comes earlier in the +# topological order of things than its parent (examples/package/) +# because the parent package depends on the subpackage. Therefore, +# this package needs to be written earlier in the Makefile includes. +# +# EXAMPLE +# +# make o//examples/package/lib # build library w/ sanity checks +# at t o//examples/package/lib/lib.a +# +# AUTHORS +# +# %AUTHOR% PKGS += EXAMPLES_PACKAGE_LIB +# Declares build package. +# Other packages may list this variable in their deps list. +# Please note package relationships aren't allowed to be cyclic. +EXAMPLES_PACKAGE_LIB = \ + $(EXAMPLES_PACKAGE_LIB_A_DEPS) \ + $(EXAMPLES_PACKAGE_LIB_A) + +# While build configs might seem somewhat complicated but rest +# assured they're mostly maintainence free, thanks to wildcard +EXAMPLES_PACKAGE_LIB_A_FILES := $(wildcard examples/package/lib/*) EXAMPLES_PACKAGE_LIB_ARTIFACTS += EXAMPLES_PACKAGE_LIB_A -EXAMPLES_PACKAGE_LIB = $(EXAMPLES_PACKAGE_LIB_A_DEPS) $(EXAMPLES_PACKAGE_LIB_A) -EXAMPLES_PACKAGE_LIB_A = o/$(MODE)/examples/package/lib/lib.a EXAMPLES_PACKAGE_LIB_A_HDRS = $(filter %.h,$(EXAMPLES_PACKAGE_LIB_A_FILES)) -EXAMPLES_PACKAGE_LIB_A_SRCS_S = $(filter %.S,$(EXAMPLES_PACKAGE_LIB_A_FILES)) -EXAMPLES_PACKAGE_LIB_A_SRCS_C = $(filter %.c,$(EXAMPLES_PACKAGE_LIB_A_FILES)) -EXAMPLES_PACKAGE_LIB_A_CHECKS = $(EXAMPLES_PACKAGE_LIB_A).pkg - -EXAMPLES_PACKAGE_LIB_A_FILES := \ - $(wildcard examples/package/lib/*) \ - $(wildcard examples/package/lib/thunks/*) +EXAMPLES_PACKAGE_LIB_A = o/$(MODE)/examples/package/lib/lib.a +# Define sets of source files without needing further iops. +EXAMPLES_PACKAGE_LIB_A_SRCS_S = \ + $(filter %.S,$(EXAMPLES_PACKAGE_LIB_A_FILES)) +EXAMPLES_PACKAGE_LIB_A_SRCS_C = \ + $(filter %.c,$(EXAMPLES_PACKAGE_LIB_A_FILES)) EXAMPLES_PACKAGE_LIB_A_SRCS = \ $(EXAMPLES_PACKAGE_LIB_A_SRCS_S) \ $(EXAMPLES_PACKAGE_LIB_A_SRCS_C) +# Change suffixes of different languages extensions into object names. EXAMPLES_PACKAGE_LIB_A_OBJS = \ $(EXAMPLES_PACKAGE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \ $(EXAMPLES_PACKAGE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o) \ $(EXAMPLES_PACKAGE_LIB_A_SRCS:%=o/$(MODE)/%.zip.o) +# 1. Guarantees each header builds, i.e. includes symbols it needs. +# 2. Guarantees transitive closure of packages is directed acyclic. +EXAMPLES_PACKAGE_LIB_A_CHECKS = \ + $(EXAMPLES_PACKAGE_LIB_A).pkg \ + $(EXAMPLES_PACKAGE_LIB_A_HDRS:%=o/$(MODE)/%.ok) + +# Lists packages whose symbols are or may be directly referenced here. +# Note that linking stubs is always a good idea due to synthetic code. EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS = \ LIBC_STDIO \ LIBC_STUBS +# Evaluates variable as set of transitive package dependencies. EXAMPLES_PACKAGE_LIB_A_DEPS := \ $(call uniq,$(foreach x,$(EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS),$($(x)))) +# Concatenates object files into single file with symbol index. +# Please don't use fancy make features for mutating archives it's slow. $(EXAMPLES_PACKAGE_LIB_A): \ examples/package/lib/ \ $(EXAMPLES_PACKAGE_LIB_A).pkg \ $(EXAMPLES_PACKAGE_LIB_A_OBJS) +# Asks packager to index symbols and validate their relationships. +# It's the real secret sauce for having a huge Makefile w/o chaos. +# @see tool/build/package.c +# @see build/rules.mk $(EXAMPLES_PACKAGE_LIB_A).pkg: \ $(EXAMPLES_PACKAGE_LIB_A_OBJS) \ $(foreach x,$(EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS),$($(x)_A).pkg) -$(EXAMPLES_PACKAGE_LIB_A_OBJS): examples/package/lib/lib.mk +# Invalidates objects in package when makefile is edited. +$(EXAMPLES_PACKAGE_LIB_A_OBJS): examples/package/lib/build.mk EXAMPLES_PACKAGE_LIB_LIBS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x))) EXAMPLES_PACKAGE_LIB_SRCS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)_SRCS)) diff --git a/examples/package/new.sh b/examples/package/new.sh index 75cf2d46..5abe81ce 100755 --- a/examples/package/new.sh +++ b/examples/package/new.sh @@ -10,6 +10,7 @@ DIR=${1:?need directory arg} VAR=$(echo "$DIR" | tr a-z A-Z | tr / _) +DIRNAME=${DIR%/*} BASENAME=${DIR##*/} FILENAME="$DIR/$BASENAME" MAKEFILE="$DIR/$BASENAME.mk" @@ -20,14 +21,20 @@ if [ -d "$DIR" ]; then fi mkdir -p "$DIR" && - cp -R examples/package/new/* "$DIR" && + cp -R examples/package/* "$DIR" && + rm -f "$DIR/new.sh" && find "$DIR" -type f | xargs sed -i -e " - s/EXAMPLES_PACKAGE/$VAR/g - s/examples\/package\/package/$FILENAME/g - s/examples\/package/$DIR/g + s~EXAMPLES_PACKAGE~$VAR~g + s~examples/package/package~$FILENAME~g + s~examples/package~$DIR~g + s~%AUTHOR%~$(git config user.name) <$(git config user.email)>~g " && sed -i -e " + s~include $DIR/build.mk~# XXX: include $DIR/build.mk~ + s~include $DIR/lib/build.mk~# XXX: include $DIR/lib/build.mk~ /#-φ-examples\/package\/new\.sh/i\ -include $MAKEFILE +include $DIR/lib/build.mk + /#-φ-examples\/package\/new\.sh/i\ +include $DIR/build.mk " Makefile diff --git a/examples/package/program.c b/examples/package/program.c index 44dcc1dc..ab14601e 100644 --- a/examples/package/program.c +++ b/examples/package/program.c @@ -1,6 +1,6 @@ #include "examples/package/lib/myprint.h" int main(int argc, char *argv[]) { - MyPrint("welcome to your package"); + MyPrint("welcome to your package\n"); return 0; }