summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-11-20 21:52:55 -0800
committerOri Bernstein <ori@eigenstate.org>2015-11-20 22:26:12 -0800
commitd48a95ad5889f74777acadaeca615636f855b691 (patch)
treec9b4d8e1a246c73696506b137c12852c8f01eed8
downloadmk-d48a95ad5889f74777acadaeca615636f855b691.tar.gz
Initial revision.
-rw-r--r--README.rst140
-rw-r--r--c.mk136
-rwxr-xr-xconfigure42
-rw-r--r--example/Makefile4
-rw-r--r--example/hello.c12
-rw-r--r--example/main.c12
-rw-r--r--lexyacc.mk9
7 files changed, 355 insertions, 0 deletions
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..ac6cbea
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,140 @@
+Makefile Templates
+==================
+
+This contains a number of makefile templates. These Makefile
+templates are as follows:
+
+one.mk
+------
+
+Builds a single target from multiple input object files. It supports the
+following variables as targets:
+
+BIN
+ The name of a binary. This binary is not installed. This is
+ primarily useful for code generation.
+
+LIB
+ The name of a static library to build. This static library
+ is not installed. This is primarily convenient for breaking
+ your code up into smaller modules, which are linked together.
+
+SUB
+ A list of subdirectories to recurse into when building a well
+ known target (eg, `clean`, `install`, and so on).
+
+INSTBIN
+ The name of a binary which is installed to `$prefix/bin`. This
+ is the most common target which I use.
+
+INSTLIB
+ The name of a static library which is installed to `$prefix/lib`.
+ This makefile fragment expects the name to be in the form of
+ `lib$LIBNAME.a`.
+
+INSTHDR
+ A list of headers to install. The headers are copied to
+ `$prefix/include`.
+
+INSTPKG
+ This lists a set of pkg-config files, which are installed
+ to `$prefix/lib/pkgconfig`. If you are building a library
+ that others use, it is *highly* recommended to include a
+ pkg-config file for ease of use.
+
+INSTMAN
+ Installs a manpage. The manpage is expected to be named in
+ the form of `docname.SECT`, eg, `mycmd.1`, ad will be installed
+ into the appropriate directory.
+
+The inputs to all of the targets which are built are listed in the
+`OBJ` variable, making it the central part of the makefiles.
+
+OBJ
+ This is the list of all the .o files that go into either the
+ library or the binary that is being constructed.
+
+
+There are also a number of other variables that can be used to control
+the way that this makefile include works:
+
+EXTRA
+ This is a list of extra targets to build when running
+ `make all`. These targets should be provided by you.
+
+PCPKGS
+ This contains a list of pkg-config packages that this program
+ depends on. The libraries and include paths will be added to the
+ build for the target being compiled.
+
+DEPS
+ This contains a list of local libraries that the current target
+ depends on, in the form `../module/libmodule.a`. These dependencies
+ will be built before the module that defines the dependencies.
+
+EXTRADEP
+ This is a list of extra dependencies to be added to the BIN, INSTBIN,
+ LIB, or INSTLIB targets.
+
+EXTRACLEAN
+ This is a list of extra files to be removed on `make clean`
+
+LDFLAGS
+ This contains the linker flags. This should only be appended to,
+ and not overridden.
+
+CFLAGS
+ This contains the C compiler flags. This should only be appended to,
+ and not overridden.
+
+CXXFLAGS
+ This contains the C++ compiler flags. This should only be appended to,
+ and not overridden.
+
+INST_ROOT
+ This defines the directory to install into. In this example, it
+ is set by ./configure
+
+lexyacc.mk
+------
+
+Augments one.mk and many.mk rules with lex and yacc rules. These
+rules will take a yacc file named `input.y`, and produce `input.c` and
+`input.h` from it.
+
+Configure
+=========
+
+This also ships with a single, trivial script named configure. It
+only supports setting the prefix, which for many of the programs I need
+is enough.
+
+There are some examples of libraries -- for example, clang -- which do not
+ship with pkg-config files, and are typically not installed to /usr/lib. For
+those, code is added to the ./configure script.
+
+This script will automatically be run when running `make`.
+
+An Example
+==========
+
+Pulled from my Myrddin code::
+
+ INSTBIN=6m
+ OBJ= \
+ blob.o \
+ gen.o \
+ gengas.o \
+ genp9.o \
+ isel.o \
+ locs.o \
+ main.o \
+ ra.o \
+ peep.o \
+ simp.o \
+ typeinfo.o \
+
+ DEPS=../parse/libparse.a ../mi/libmi.a
+
+ include ../config.mk
+ include ../mk/c.mk
diff --git a/c.mk b/c.mk
new file mode 100644
index 0000000..e69a240
--- /dev/null
+++ b/c.mk
@@ -0,0 +1,136 @@
+.DEFAULT_GOAL=all
+_DEPS=$(addprefix .deps/, $(OBJ:.o=.d))
+
+_PCHDRS=$(shell [ -z "$(PCPKGS)" ] || pkg-config --cflags $(PCPKGS))
+_PCLIBS=$(shell [ -z "$(PCPKGS)" ] ||pkg-config --libs $(PCPKGS))
+
+_LIBSRCHPATHS=$(addprefix -L, $(dir $(DEPS)))
+_LIBINCPATHS=$(addprefix -I, $(dir $(DEPS))) $(_PCHDRS)
+_LIBPATHS=$(addprefix -l, $(patsubst lib%.a,%,$(notdir $(DEPS)))) $(_PCLIBS)
+
+# yeah, I should probably remove -Werror, but it's nice for developing alone.
+CFLAGS += -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-array-bounds -g
+CFLAGS += -MMD -MP -MF .deps/$(subst /,-,$*).d
+
+LIB ?= $(INSTLIB)
+BIN ?= $(INSTBIN)
+
+# disable implicit rules.
+.SUFFIXES:
+.SECONDARY:
+.PHONY: clean clean-gen clean-bin clean-obj clean-misc clean-backups
+.PHONY: all _modversions
+
+all: _modversions subdirs $(BIN) $(LIB) $(EXTRA)
+
+$(LIB): $(OBJ) $(EXTRADEP) $(DEPS)
+ $(AR) -rcs $@ $(OBJ)
+
+$(BIN): $(OBJ) $(EXTRADEP) $(DEPS)
+ $(CC) -o $@ $(OBJ) $(_LIBSRCHPATHS) $(_LIBPATHS) $(LDFLAGS)
+
+$(DEPS):
+ @cd $(dir $@) && $(MAKE)
+
+subdirs:
+ @for i in $(SUB); do (\
+ cd $$i && \
+ $(MAKE) || \
+ exit 1 \
+ ) || exit 1; done
+
+subdirs-clean:
+ @for i in $(SUB); do (\
+ cd $$i && \
+ $(MAKE) clean|| \
+ exit 1 \
+ ); done
+
+subdirs-install:
+ @for i in $(SUB); do (\
+ cd $$i && \
+ $(MAKE) install|| \
+ exit 1 \
+ ); done
+
+clean: subdirs-clean $(EXTRACLEAN)
+ rm -f ${BIN} ${OBJ} ${CLEAN} ${LIB}
+ rm -rf .deps/
+
+install: subdirs-install $(INSTBIN) $(INSTLIB) $(INSTHDR) $(INSTPKG) $(EXTRAINSTALL)
+ @for i in $(INSTBIN); do \
+ echo install $(abspath $$i $(DESTDIR)/$(INST_ROOT)/bin); \
+ mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/bin); \
+ install $$i $(abspath $(DESTDIR)/$(INST_ROOT)/bin); \
+ done
+ @for i in $(INSTLIB); do \
+ echo install -m 644 $$i $(abspath $(DESTDIR)/$(INST_ROOT)/lib); \
+ mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/lib); \
+ install -m 644 $$i $(abspath $(DESTDIR)/$(INST_ROOT)/lib); \
+ done
+ @for i in $(INSTHDR); do \
+ echo install $$i $(abspath $(DESTDIR)/$(INST_ROOT)/include); \
+ mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/include); \
+ install $$i $(abspath $(DESTDIR)/$(INST_ROOT)/include); \
+ done
+ @for i in $(INSTPKG); do \
+ echo install $(abspath $$i $(DESTDIR)/$(INST_ROOT)/lib/pkgconfig); \
+ mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/lib/pkgconfig); \
+ install $(abspath $$i $(DESTDIR)/$(INST_ROOT)/lib/pkgconfig); \
+ done
+ @for i in $(INSTMAN); do \
+ sect="$${i##*.}"; \
+ echo install -m 644 $$i $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${sect}); \
+ mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${sect}); \
+ install -m 644 $$i $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${sect}); \
+ done
+
+subdirs-uninstall:
+ @for i in $(SUB); do (\
+ cd $$i && \
+ $(MAKE) uninstall|| \
+ exit 1 \
+ ); done
+
+uninstall: subdirs-uninstall $(EXTRAUNINSTALL)
+ @for i in $(INSTBIN); do \
+ echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/bin/$$i); \
+ rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/bin/$$i); \
+ done
+ @for i in $(INSTLIB); do \
+ echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/$$i); \
+ rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/$$i); \
+ done
+ @for i in $(INSTHDR); do \
+ echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/include/$$i); \
+ rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/include/$$i); \
+ done
+ @for i in $(INSTPKG); do \
+ echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/pkgconfig/$$i); \
+ rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/pkgconfig/$$i); \
+ done
+ @for i in $(INSTMAN); do \
+ sect="$${i##*.}" \
+ echo rm -f $$i $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${sect}/$$i); \
+ rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${sect}/$$i); \
+ done
+
+%.o: %.c $(GENHDR) .deps/stamp
+ $(CC) -c $(CFLAGS) $(_LIBINCPATHS) $<
+
+%.o: %.cpp $(GENHDR) .deps/stamp
+ $(CXX) -c $(CFLAGS) $(_LIBINCPATHS) $<
+
+%.o: %.cc $(GENHDR) .deps/stamp
+ $(CXX) -c $(CFLAGS) $(_LIBINCPATHS) $<
+
+.deps/stamp:
+ mkdir -p .deps && touch .deps/stamp
+
+config.mk: configure
+ ./configure --redo
+
+_modversions:
+ @[ -z "$(PCPKGS)" ] || pkg-config --modversion $(PCPKGS) > /dev/null
+
+-include $(_DEPS)
diff --git a/configure b/configure
new file mode 100755
index 0000000..bfa86bd
--- /dev/null
+++ b/configure
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+prefix="/usr/local"
+
+for i in `seq 300`; do
+ echo "Lots of output to emulate automake... ok"
+ echo "Lalalala twiddling thumbs... ok"
+ echo "Testing for things you'll never use... fail"
+ echo "Satisfying the fortran77 lobby... ok"
+ echo "Burning CPU time checking for the obvious... ok"
+done
+echo "Autoconf emulated successfully"
+
+INST_ROOT='/usr/local'
+
+for arg in $*; do
+ shift 1
+ echo $*
+ case $arg in
+ "--redo" | "-r")
+ if [ -f ./configvar_cache ]; then
+ . ./configvar_cache
+ fi
+ ;;
+ --prefix=*)
+ prefix=`echo $arg | sed 's/^--prefix=//g'`
+ ;;
+ *) echo "Unrecognized argument $arg";;
+ esac
+done
+
+OS=`uname`
+
+
+echo "export INST_ROOT=$prefix" > config.mk
+
+echo "prefix=$prefix" > configvar_cache
+cat << EOF
+ Building with:
+ prefix=$prefix
+EOF
+
diff --git a/example/Makefile b/example/Makefile
new file mode 100644
index 0000000..773eb76
--- /dev/null
+++ b/example/Makefile
@@ -0,0 +1,4 @@
+BIN=hello
+OBJ=main.o hello.o
+
+include ../one.mk
diff --git a/example/hello.c b/example/hello.c
new file mode 100644
index 0000000..32feb10
--- /dev/null
+++ b/example/hello.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "hello.h"
+
+void hello_showargs(char **args, int nargs)
+{
+ size_t i;
+
+ for (i = 0; i < nargs; i++)
+ printf("%s\n", args[i]);
+}
diff --git a/example/main.c b/example/main.c
new file mode 100644
index 0000000..23d37fc
--- /dev/null
+++ b/example/main.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+#include "hello.h"
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ printf("Hello World!\n");
+ for (i = 1; i < argc; i++)
+ hello_showargs(argv + 1, argc - 1);
+}
diff --git a/lexyacc.mk b/lexyacc.mk
new file mode 100644
index 0000000..c1baf61
--- /dev/null
+++ b/lexyacc.mk
@@ -0,0 +1,9 @@
+NOERR_FLAGS = $(subst -Werror,,$(subst -Wall,,$(CFLAGS)))
+
+%.o: %.y
+ yacc -d -o$*.c $<
+ $(CC) -c $(NOERR_CFLAGS) $(_LIBINCPATHS) $*.c
+
+%.o: %.l
+ flex -o$*.c $<
+ $(CC) -c $(NOERR_CFLAGS) $(_LIBINCPATHS) $*.c