Projects:Makefile
From Tractatus
One of the interesting things about INTJ's and Enneagram 5's is that they constantly start new projects, like Web Pages. As a result of this attribute, and my boredom with my last job in RACF L2, I was constantly starting new projects. What is the first thing you do when you start a new software project? Ok, well, what is the second thing you do? Create a Makefile.
So I kept doing this. And each time I would duplicate a bunch of stuff. Each time, I would read the man page for make. So, I decided to create a Universal Makefile which I would just copy into a directory, and would do the correct thing.
Currently, it looks like this(z/OS version). The basic idea is that you copy it into the project directory, create a few source.d files to record project specific dependencies, and then issue a fewmake deps. At that point, you should be able to
make ''result''and it will hopefully produce the desired file. Note that there are a whole bunch of other rules. For example, when I create something that I want to use later, I put the headers in ~/include, and the library's in ~/libexec. This lets me actually reuse code. Whoa!
I do not personally recommend doing this kind of thing. I think it lies on the border between Abomination and Bad Idea on the Isthmus of Genius.
The Makefile I currently use is:
SRCS=$(wildcard $(addprefix *,$(SUFFIXES))) LIBEXECS=$(wildcard *.a) HEADERS=$(wildcard *.h) LD = gcc CC ?= gcc CPP ?= gcc YACC ?= bison BISON = bison LEX ?= flex LEXLIB ?= fl INSTALL ?= cp INCLUDEDIR?= ~/include LIBEXECDIR?= ~/libexec BINDIR?= ~/bin INCLUDEDIRS+= $(INCLUDEDIR) INCLUDE_ARG = $(addprefix -I ,$(INCLUDEDIRS)) LIBEXECDIRS+= $(LIBEXECDIR) LIBEXECDIRS+= . LIBEXEC_ARG = $(addprefix -L ,$(LIBEXECDIRS)) LIBS_ARG = $(addprefix -l ,$(LIBS)) CFLAGS+= -Wall $(INCLUDE_ARG) $(LIBEXEC_ARG) CPPFLAGS+= -Wall $(INCLUDE_ARG) $(LIBEXEC_ARG) LDFLAGS+= $(addprefix -L ,$(LIBEXECDIRS)) all:: every -include *.d every:: .PHONY: deps deps: .deps DEPFILES=$(addprefix .,$(addsuffix .d,$(SRCS))) .deps: $(DEPFILES) @rm -f $@ @touch .deps -include .deps -include .*.d # Rules below this line .%.c.d: %.c @$(CC) $(CCFLAGS) -MT $@ -MT $*.o -MM -MF $@ $< @echo "$*.o: .$*.c.d $*.c" >> $@ @echo "clean:: " >> $@ @echo " @rm -f $@ $*.o" >> $@ @echo "Made(c): $@" .%.C.d: %.C @$(CPP) $(CPPFLAGS) -MT $@ -MT $*.o -MM -MF $@ $< @echo "$*.o: .$*.C.d $*.C" >> $@ @echo "clean:: " >> $@ @echo " @rm -f $@ $*.o" >> $@ @echo "Made(C): $@" .%.y.d: %.y @echo "$*.tab.h: $*.y $@" > $@ @echo "$*.tab.c: $*.y $@" >> $@ @echo "$*.o: $*.tab.c" >> $@ @echo "$@: $^" >> $@ @echo "clean::" >> $@ @echo " @rm -f $@ $*.tab.h $*.tab.c $*.tab.o" >> $@ @echo "Made(y): $@" .%.Y.d: %.Y @echo "$*.tab.H: $*.Y $@" > $@ @echo "$*.tab.C: $*.Y $@" >> $@ @echo "$*.o: $*.tab.C" >> $@ @echo "$@: $^" >> $@ @echo "clean::" >> $@ @echo " @rm -f $@ $*.tab.H $*.tab.C $*.tab.o" >> $@ @echo "Made(Y): $@" .%.l.d: %.l @echo "$*.c: $*.l" > $@ @echo "$@: $^" >> $@ @echo "$*:LIBS+=$(LEXLIB)" >> $@ @echo "clean:: " >> $@ @echo " @rm -f $@ $*.c" >> $@ @echo "Made(l): $@" .%.L.d: %.L @echo "$*.C: LFLAGS+=-+" > $@ @echo "$*.C: $*.L" >> $@ @echo "$@: $^" >> $@ @echo "$*:LIBS+=$(LEXLIB)" >> $@ @echo "clean:: " >> $@ @echo " @rm -f $@ $*.C" >> $@ @echo "Made(l): $@" .%.tex.d: %.tex @echo "clean:: " >> $@ @echo " @rm -f $@ $*.ind $*.idx $*.ilg $*.toc" >> $@ @echo " @rm -f $@ $*.log $*.dvi $*.aux" >> $@ @echo "Made(l): $@" #.%.o.d: %.o # @echo "$*.o: .$*.C.d $*.C" > $@ # @echo "$@: $^ " >> $@ # @echo "clean:: " >> $@ # @echo " @rm -f $@ $*.o" >> $@ # @echo "Made(o): $@" .%.d: % @echo "$@: $^" > $@ @echo "clean:: " >> $@ @echo " @rm -f $@" >> $@ @echo "Made: $@" #my%.d: # -cp $@ $@.bak # echo "#This Makefile has been automatically generated." > $@ # echo "EXECS += $*" >> $@ # echo "$*: .$*.o.d $*.o" >> $@ # echo "all:: $*" >> $@ # echo "clean::" >>$@ # echo " $(RM) $* $@" >> $@ # echo " " >> $@ %.s: CPPFLAGS+= -S %.s: %.c $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< %.s: %.cc $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< %.c: LFLAGS?=-t %.c: %.l .%.l.d $(LEX) $(LFLAGS) $*.l > $@ %.C: LFLAGS?=-t %.C: %.L .%.L.d $(LEX) $(LFLAGS) -+ $*.L > $@ %.tab.c %.tab.h: %.y $(YACC) $(YACCFLAGS) -d -b $* $*.y %.tab.C %.tab.H: %.Y $(BISON) $(YACCFLAGS) -d -b $* $*.Y lib%.a: @$(AR) $(ARFLAGS) $@ $^ # Latex rules .DELETE_ON_ERROR: %.dvi %.dvi: %.tex latex \\nonstopmode\\input $< %.pdf: %.tex pdflatex \\nonstopmode\\input $< .DELETE_ON_ERROR: %.idx %.idx: %.tex latex \\nonstopmode\\input $< -rm $*.dvi %.ind: %.idx makeindex $< # graphviz rules %.png: %.dot dot -Tpng $< -o $@ %.ps: %.dot dot -Tps $< -o $@ # Document format rules %.ps: %.dvi dvips -o $@ $< %.pdf: %.dvi dvipdf $< $@ %.pdf: %.ps ps2pdf $< $@ %.pdf: %.doc antiword -a a4 $< > $@ %.ps: %.doc antiword -p a4 $< > $@ %.txt: %.doc antiword -t $< > $@ %.asc: % gpg --armor --detach-sign $* $(EXECS): $(LD) -o $@ $(filter %.o,$^) $(LIBS_ARG) $(LIBEXEC_ARG) # $(LD) $(LDFLAGS) -o $@ $(filter %.o,$^) $(addprefix -l ,$(LIBS)) .PHONY: install_headers install_execs install_libexecs .PHONY: uninstall_headers uninstall_execs uninstall_libexecs install_headers: $(HEADERS) echo $(^F) -mkdir -p $(addprefix $(strip $(INCLUDEDIR))/,$(^D)) -$(INSTALL) $(^F) $(INCLUDEDIR) install_execs: $(EXECS) -mkdir -p $(BINDIR) -$(INSTALL) $^ $(BINDIR) install_libexecs: $(LIBEXECS) -mkdir -p $(LIBEXECDIR) -$(INSTALL) $^ $(LIBEXECDIR) uninstall_headers: $(HEADERS) -$(RM) -i $(addprefix $(INCLUDEDIR)/,$(^F)) -rmdir -p $(addprefix $(INCLUDEDIR)/,$(^D)) uninstall_execs: $(EXECS) -$(RM) -i $(addprefix $(BINDIR)/,$^) -rmdir -p $(BINDIR) uninstall_libexecs: $(LIBEXECS) -$(RM) -i $(addprefix $(LIBEXECDIR)/,$^) -rmdir -p $(LIBEXECDIR) .PHONY: install install:: install_headers install_execs install_libexecs .PHONY: uninstall uninstall:: uninstall_headers uninstall_execs uninstall_libexecs .PHONY: clean clean:: clean_file @$(RM) .deps @$(RM) *~ .PHONY: clean_file clean_file: @$(RM) $^