Make it easy to create new packages

main
Justine Tunney 2 years ago
parent b4269930f7
commit d23bb6612e
  1. 18
      README.md
  2. 0
      examples/package/README.md
  3. 29
      examples/package/build.mk
  4. 60
      examples/package/lib/build.mk
  5. 17
      examples/package/new.sh
  6. 2
      examples/package/program.c

@ -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

@ -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)
# Invalidates objects in package when makefile is edited.
$(EXAMPLES_PACKAGE_OBJS): examples/package/build.mk
# Creates target that builds everything in this package and subpackages.
# 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)

@ -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))

@ -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

@ -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;
}

Loading…
Cancel
Save