Make it easy to create new packages

main
Justine Tunney 2020-06-15 19:59:12 -07:00
parent b4269930f7
commit d23bb6612e
6 changed files with 90 additions and 36 deletions

View File

@ -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 examples/package/new.sh com/github/user/project
emacs com/github/user/project/program.c emacs com/github/user/project/program.c
make o//com/github/user/project/program.c make o//com/github/user/project/program.com
o//com/github/user/project/program.c o//com/github/user/project/program.com
Please note GNU make is awesome. Little known fact: make is a functional 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 which performs strict dependency checking, to correct Google's published
mistakes c. 2006 which was when they switched from using a GNU Make repo 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 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←      ╲←         @             °→      ♠←       ←      2←      L←      ╲←      
x←                                                               x←                                                              
See also `build/dump -xd o/tiny/examples/life.com.dbg | less` assembly See also `build/objdump -xd o/tiny/examples/life.com.dbg | less` to view
and our linker script [ape/ape.lds] which glues the binaries together. 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

View File

@ -14,6 +14,10 @@
# #
# make o//examples/package # make o//examples/package
# o/examples/package/program.com # o/examples/package/program.com
#
# AUTHORS
#
# %AUTHOR%
PKGS += EXAMPLES_PACKAGE PKGS += EXAMPLES_PACKAGE
@ -24,15 +28,15 @@ EXAMPLES_PACKAGE_FILES := $(wildcard examples/package/*)
EXAMPLES_PACKAGE_SRCS = $(filter %.c,$(EXAMPLES_PACKAGE_FILES)) EXAMPLES_PACKAGE_SRCS = $(filter %.c,$(EXAMPLES_PACKAGE_FILES))
EXAMPLES_PACKAGE_HDRS = $(filter %.h,$(EXAMPLES_PACKAGE_FILES)) EXAMPLES_PACKAGE_HDRS = $(filter %.h,$(EXAMPLES_PACKAGE_FILES))
EXAMPLES_PACKAGE_COMS = $(EXAMPLES_PACKAGE_OBJS:%.o=%.com) 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. # Remaps source file names to object names.
# Also asks a wildcard rule to automatically run tool/build/zipobj.c # Also asks a wildcard rule to automatically run tool/build/zipobj.c
EXAMPLES_PACKAGE_OBJS = \ EXAMPLES_PACKAGE_OBJS = \
$(EXAMPLES_PACKAGE_SRCS:%.c=o/$(MODE)/%.o) \ $(EXAMPLES_PACKAGE_SRCS:%.c=o/$(MODE)/%.o) \
$(EXAMPLES_PACKAGE_SRCS:%=o/$(MODE)/%.zip.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. # Lists packages whose symbols are or may be directly referenced here.
# Note that linking stubs is always a good idea due to synthetic code. # Note that linking stubs is always a good idea due to synthetic code.
@ -46,13 +50,7 @@ EXAMPLES_PACKAGE_DIRECTDEPS = \
EXAMPLES_PACKAGE_DEPS := \ EXAMPLES_PACKAGE_DEPS := \
$(call uniq,$(foreach x,$(EXAMPLES_PACKAGE_DIRECTDEPS),$($(x)))) $(call uniq,$(foreach x,$(EXAMPLES_PACKAGE_DIRECTDEPS),$($(x))))
# Invalidates objects in this package when this makefile is edited $(EXAMPLES_PACKAGE_A).pkg: \
$(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_OBJS) \ $(EXAMPLES_PACKAGE_OBJS) \
$(foreach x,$(EXAMPLES_PACKAGE_DIRECTDEPS),$($(x)_A).pkg) $(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 # @see build/rules.mk for definition of rule that does .com.dbg -> .com
o/$(MODE)/examples/package/%.com.dbg: \ o/$(MODE)/examples/package/%.com.dbg: \
$(EXAMPLES_PACKAGE_DEPS) \ $(EXAMPLES_PACKAGE_DEPS) \
o/$(MODE)/examples/package/package.pkg \
o/$(MODE)/examples/package/%.o \ o/$(MODE)/examples/package/%.o \
$(CRT) \ $(CRT) \
$(APE) $(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 .PHONY: o/$(MODE)/examples/package
o/$(MODE)/examples/package: \ o/$(MODE)/examples/package: \
o/$(MODE)/examples/package/lib \ o/$(MODE)/examples/package/lib \
$(EXAMPLES_PACKAGE_BINS) \ $(EXAMPLES_PACKAGE_BINS)
$(EXAMPLES_PACKAGE_CHECKS)

View File

@ -9,47 +9,87 @@
# #
# Your library doesn't have a main() function and can be compromised # Your library doesn't have a main() function and can be compromised
# of sources written in multiple languages. # 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 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_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_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 = o/$(MODE)/examples/package/lib/lib.a
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/*)
# 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 = \
$(EXAMPLES_PACKAGE_LIB_A_SRCS_S) \ $(EXAMPLES_PACKAGE_LIB_A_SRCS_S) \
$(EXAMPLES_PACKAGE_LIB_A_SRCS_C) $(EXAMPLES_PACKAGE_LIB_A_SRCS_C)
# Change suffixes of different languages extensions into object names.
EXAMPLES_PACKAGE_LIB_A_OBJS = \ EXAMPLES_PACKAGE_LIB_A_OBJS = \
$(EXAMPLES_PACKAGE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \ $(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_C:%.c=o/$(MODE)/%.o) \
$(EXAMPLES_PACKAGE_LIB_A_SRCS:%=o/$(MODE)/%.zip.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 = \ EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS = \
LIBC_STDIO \ LIBC_STDIO \
LIBC_STUBS LIBC_STUBS
# Evaluates variable as set of transitive package dependencies.
EXAMPLES_PACKAGE_LIB_A_DEPS := \ EXAMPLES_PACKAGE_LIB_A_DEPS := \
$(call uniq,$(foreach x,$(EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS),$($(x)))) $(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_A): \
examples/package/lib/ \ examples/package/lib/ \
$(EXAMPLES_PACKAGE_LIB_A).pkg \ $(EXAMPLES_PACKAGE_LIB_A).pkg \
$(EXAMPLES_PACKAGE_LIB_A_OBJS) $(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).pkg: \
$(EXAMPLES_PACKAGE_LIB_A_OBJS) \ $(EXAMPLES_PACKAGE_LIB_A_OBJS) \
$(foreach x,$(EXAMPLES_PACKAGE_LIB_A_DIRECTDEPS),$($(x)_A).pkg) $(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_LIBS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)))
EXAMPLES_PACKAGE_LIB_SRCS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)_SRCS)) EXAMPLES_PACKAGE_LIB_SRCS = $(foreach x,$(EXAMPLES_PACKAGE_LIB_ARTIFACTS),$($(x)_SRCS))

View File

@ -10,6 +10,7 @@
DIR=${1:?need directory arg} DIR=${1:?need directory arg}
VAR=$(echo "$DIR" | tr a-z A-Z | tr / _) VAR=$(echo "$DIR" | tr a-z A-Z | tr / _)
DIRNAME=${DIR%/*}
BASENAME=${DIR##*/} BASENAME=${DIR##*/}
FILENAME="$DIR/$BASENAME" FILENAME="$DIR/$BASENAME"
MAKEFILE="$DIR/$BASENAME.mk" MAKEFILE="$DIR/$BASENAME.mk"
@ -20,14 +21,20 @@ if [ -d "$DIR" ]; then
fi fi
mkdir -p "$DIR" && mkdir -p "$DIR" &&
cp -R examples/package/new/* "$DIR" && cp -R examples/package/* "$DIR" &&
rm -f "$DIR/new.sh" &&
find "$DIR" -type f | find "$DIR" -type f |
xargs sed -i -e " xargs sed -i -e "
s/EXAMPLES_PACKAGE/$VAR/g s~EXAMPLES_PACKAGE~$VAR~g
s/examples\/package\/package/$FILENAME/g s~examples/package/package~$FILENAME~g
s/examples\/package/$DIR/g s~examples/package~$DIR~g
s~%AUTHOR%~$(git config user.name) <$(git config user.email)>~g
" && " &&
sed -i -e " 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\ /#-φ-examples\/package\/new\.sh/i\
include $MAKEFILE include $DIR/lib/build.mk
/#-φ-examples\/package\/new\.sh/i\
include $DIR/build.mk
" Makefile " Makefile

View File

@ -1,6 +1,6 @@
#include "examples/package/lib/myprint.h" #include "examples/package/lib/myprint.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
MyPrint("welcome to your package"); MyPrint("welcome to your package\n");
return 0; return 0;
} }