Tractat.usIain | About | Help | FAQ | Special pages | Log in
n. handling , management, treatment.
Printable version | Disclaimers | Privacy policy

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 few
make 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) $^

Retrieved from "http://www.tractat.us/wiki/Projects:Makefile"

This page has been accessed 695 times. This page was last modified on 21 March 2011, at 01:10. Content is available under Attribution-Noncommercial-Share Alike 2.5 .


Find

Browse
Iain
Current events
Recent changes
Random page
Help
Edit
View source
Editing help
This page
Discuss this page
New section
Printable version
Context
Page history
What links here
Related changes
My pages
Log in / create account
Special pages
New pages
File list
Statistics
More...