forked from mischasan/hx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrules.mk
142 lines (110 loc) · 6.03 KB
/
rules.mk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# INPUTS
# $(all) : list of module names that want standard "clean".
# $BLD : empty, or one of: cover debug profile
# $(<module>.clean): list of non-target dirs/files to clean up.
# $(<module>.test): list of .pass targets for <module>
# TODO
# Mon Feb 25 2013
# - use all += rather than forcing boilerplate dependencies (all : hx.all etc)?
# - CLEAN UP FreeBSD build on knee
ifndef RULES_MK
RULES_MK:=1# Allow repeated "-include".
PS4 := \# # Prefix for "sh -x" output.
export LD_LIBRARY_PATH PS4
# Import from PREFIX, export to DESTDIR.
PREFIX ?= /usr/local
DESTDIR ?= $(PREFIX)
OSNAME := $(shell uname -s)
CFLAGS. = -O9
CFLAGS.cover = --coverage -DNDEBUG
LDFLAGS.cover = --coverage
CFLAGS.debug = -O0 -Wno-uninitialized
CPPFLAGS.debug = -UNDEBUG
CFLAGS.profile = -pg -DNDEBUG
LDFLAGS.profile = -pg
# PROFILE tests get stats on syscalls in their .pass files.
exec.profile = strace -cf
LDLIBS.FreeBSD = -lm
LDLIBS.Linux = -ldl -lm -lresolv
# Before gcc 4.5, -Wno-unused-result was unknown and causes an error.
Wno-unused-result := $(shell gcc -dumpversion | awk '$$0 >= 4.5 {print "-Wno-unused-result"}')
# XXX -funsigned-char would save time.
CFLAGS += -ggdb -MMD -fdiagnostics-show-option -fstack-protector --param ssp-buffer-size=4 -fno-strict-aliasing
CFLAGS += -Wall -Werror -Wextra -Wcast-align -Wcast-qual -Wno-clobbered -Wformat=2 -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wno-unknown-pragmas -Wunused $(Wno-unused-result) -Wwrite-strings
CFLAGS += -Wno-attributes $(CFLAGS.$(BLD))
# -D_FORTIFY_SOURCE=2 on some plats rejects any libc call whose return value is ignored.
# For some calls (system, write) this makes sense. For others (vasprintf), WTF?
CPPFLAGS += -mtune=native -I$(PREFIX)/include -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE $(CPPFLAGS.$(BLD))
LDFLAGS += -L$(PREFIX)/lib $(LDFLAGS.$(BLD))
LDLIBS += $(LDLIBS.$(OSNAME))
#---------------- Explicitly CANCEL EVIL BUILTIN RULES:
% : %.c
%.c : %.l
%.c : %.y
%.r : %.l
#----------------
.PHONY : all clean cover debug gccdefs install profile source tags test
.DEFAULT_GOAL := all
# $(all) contains all subproject names. It can be used in ACTIONS but not RULES,
# since it accumulates across "include */GNUmakefile"'s.
# All $(BLD) types use the same pathnames for binaries.
# To switch from release to debug, first "make clean".
# To extract and save exports, "make install DESTDIR=rel".
all :;@echo "$@ done for BLD='$(BLD)'"
clean :;@rm -rf $(shell $(MAKE) -nps all test cover profile | sed -n '/^# I/,$${/^[^\#\[%.][^ %]*: /s/:.*//p;}') \
$(clean) $(foreach A,$(all), $($A)/{gmon.out,tags,*.fail,*.gcda,*.gcno,*.gcov,*.prof}) \
$(filter %.d,$(MAKEFILE_LIST))
cover : BLD := cover
%.cover : %.test ; gcov -bcp $($@) | covsum
debug : BLD := debug
debug : all
# Expand: translate every occurrence of "${var}" in a file to its env value (or ""):
# $(Expand) template >target
Expand = perl -pe 's/ (?<!\\) \$${ ([A-Z_][A-Z_0-9]*) } / $$ENV{$$1} || ""/geix'
# $(call Install,TGTDIR,SRCFILES):
Install = if [ "$(strip $2)" ]; then mkdir -p $1; pax -rw -pe -s:.*/:: $2 $1; fi
# If you believe in magic vars, e.g. "myutil.bin = prog1 prog2 prog3"
# causing "myutil.install" to copy those files to $(DESTDIR)/bin
# then here's your automagic "install":
#XXX: install man/man3/hx.3 etc!
%.install : %.all $(%.bin) $(%.etc) $(%.include) $(%.ini) $(%.lib) $(%.sbin) \
;@$(call Install,$(DESTDIR)/bin, $($*.bin)) \
; $(call Install,$(DESTDIR)/etc, $($*.etc)) \
; $(call Install,$(DESTDIR)/ini, $($*.ini)) \
; $(call Install,$(DESTDIR)/lib, $($*.lib)) \
; $(call Install,$(DESTDIR)/sbin, $($*.sbin)) \
; $(call Install,$(DESTDIR)/include,$($*.include))
profile : BLD := profile
%.profile : %.test ;@for x in $($*.test:.pass=); do gprof -b $$x >$$x.prof; done
%.test : $(%.test)
# GMAKE trims leading "./" from $*, hence $*(*D)/$(*F). Sigh.
%.pass : % ; rm -f $@; $(exec.$(BLD)) $(*D)/$(*F) >$*.fail 2>&1 && mv -f $*.fail $@
# To build a .so, "make clean" first, to ensure all .o files compiled with -fPIC
%.so : CFLAGS := -fPIC $(filter-out $(CFLAGS.cover) $(CFLAGS.profile), $(CFLAGS))
%.so : %.o ; $(CC) $(LDFLAGS) -o $@ -shared $< $(LDLIBS)
%.so : %.a ; $(CC) $(CFLAGS) -o $@ -shared -Wl,-whole-archive $< $(LDLIBS)
%.a : ; [ "$^" ] && ar crs $@ $(filter %.o,$^)
%.yy.c : %.l ; flex -o $@ $<
%.tab.c : %.y ; bison $<
%/.. : ;@mkdir -p $(@D)
% : %.gz ; gunzip -c $^ >$@
# Ensure that intermediate files (e.g. the foo.o caused by "foo : foo.c")
# are not auto-deleted --- which causes a re-compile every second "make".
.SECONDARY :
#---------------- TOOLS:
# NOTE: "source" MUST be set with "=", not ":=", else MAKE recurses infinitely.
source = $(filter-out %.d, $(shell $(MAKE) -nps all test cover profile | sed -n '/^. Not a target/{n;/^[^.*][^ ]*:/s/:.*//p;}' | LC_ALL=C sort -u))
# gccdefs : all gcc internal #defines.
gccdefs :;@$(CC) $(CPPFLAGS) -E -dM - </dev/null | cut -c8- | sort
# sh : invoke a shell within the makefile's env:
sh :; PS1='$(PS1) [make] ' $(SHELL)
# tags : requires $(source) hence requires *.d, to find all relevant .h files
tags : all; @ctags `ls $(source) 2>/dev/null | grep '\.[ch]$$' `
# %.I lists all (recursive) #included files; e.g.: "make /usr/include/errno.h.I"
%.I : % ;@ls -1 2>&- `$(CC) $(CPPFLAGS) -M $*` ||:
%.i : %.c ; $(COMPILE.c) -E -o $@ $<
%.s : %.c ; $(COMPILE.c) -S -o $@ $< && deas $@
# "make SomeVar." prints $(SomeVar)
%. :;@echo '$($*)'
endif
# vim: set nowrap :