-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
140 lines (116 loc) · 4.81 KB
/
Makefile
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
include Utilities.mk
# Do not edit this file directly. Configuration is done in Makefile.conf.
# Most configuration here honors existing settings.
include Makefile.conf
EMPTY:=
SPACE:=$(EMPTY) $(EMPTY)
COMMA:=,
define BREAK
$1
$(1:%= )
endef
BR:=$(call BREAK,\)#) <- Backslashes can confuse highlighters/validaters
DEST_DIR:=
NULL?=/dev/null
DIR_BIN?=$(DEST_DIR)bin/
DIR_DBG?=dbg/
DIR_APP?=app/
DIR_SRC?=src/
DIR_HDR?=include/
DIR_SO?=$(DEST_DIR)lib/
DIR_O?=$(DEST_DIR)obj/
DIR_DEP?=$(DIR_O)
vpath %.cpp $(DIR_APP)
vpath %.cpp $(DIR_SRC)
vpath %.hpp $(DIR_HPP)
vpath %.tpp $(DIR_HDR)
MERGE=$(subst $(SPACE),$1,$2)
SORT_MERGE=$(call MERGE,$1,$(sort $2))
SPLIT=$(subst $1,$(SPACE),$2)
override RPATH:=-Wl,-rpath,$(call SORT_MERGE,:,$(call SPLIT,:,$(RPATH) $(DIR_O) $(DIR_SO)))
override CXXFLAGS+=$(strip $(addprefix -I,$(sort $(DIR_HDR))))\
$(sort $(call CONFIG_O,$(REQ_ALL)))
SO_LDLIBS:=$(LDLIBS)
EXE_LDLIBS:=$(LDLIBS)
override LDFLAGS+=$(RPATH) $(strip $(addprefix -L,$(sort $(DIR_SO) $(DIR_O)))) # TODO
PAT_APP=$(1:%=$(DIR_APP)%.cpp)
PAT_CPP=$(1:%=$(DIR_SRC)%.cpp)
PAT_HPP=$(1:%=$(DIR_HDR)%.hpp)
PAT_TPP=$(1:%=$(DIR_HDR)%.tpp)
PAT_D=$(1:%=$(DIR_DEP)%.d)
PAT_TD=$(1:%=$(DIR_DEP)%.Td)
PAT_O=$(1:%=$(DIR_O)%.o)
PAT_SO=$(1:%=$(DIR_SO)lib%.so)
PAT_EXE=$(1:%=$(DIR_BIN)%)
# Pattern inverses; both paths are taken so that the pipeline is flexible;
# sources and targets can be added/removed/etc. beyond their automatic
# discovery/generation.
UNPAT_APP=$(1:$(DIR_APP)%.cpp=%)
UNPAT_CPP=$(1:$(DIR_SRC)%.cpp=%)
UNPAT_HPP=$(1:$(DIR_HDR)%.hpp=%)
UNPAT_TPP=$(1:$(DIR_HDR)%.hpp=%)
UNPAT_D=$(1:$(DIR_DEP)%.d)
UNPAT_TD=$(1:$(DIR_DEP)%.Td)
UNPAT_EXE=$(1:$(DIR_BIN)%=%)
UNPAT_SO=$(1:$(DIR_SO)lib%.so=%)
UNPAT_O=$(1:$(DIR_O)%.o=%)
#include Utilities.mk
# Preserve alternate application sources from configuration
override SRCS_EXE+=$(call WPAT,APP,*)
override HDRS_EXE:=$(wildcard $(SRCS_EXE:%.cpp=%.hpp %.tpp))
# Only remove this if app and library byproducts are separated!
# obj/.o,.d,.Td files will collide until the next Makefile version.
override SRCS_SO:=$(filter-out $(SRCS_EXE),$(SRCS_SO) $(call WPAT,CPP,*))
NAMES_EXE:=$(sort $(call UNPAT_APP,$(SRCS_EXE)))
NAMES_SO:=$(sort $(call UNPAT_CPP,$(SRCS_SO)))
DEPS_EXE:=$(call PAT_D,$(NAMES_EXE))
DEPS_SO:=$(call PAT_D,$(NAMES_SO))
FILES_EXE:=$(sort $(call REPAT,APP,EXE,$(SRCS_EXE)))
FILES_SO:=$(sort $(call REPAT,CPP,SO,$(SRCS_SO)))
TARGET?=$(firstword $(FILES_EXE))
default: $(TARGET) $(COMPLETE)
$(COMPLETE): $(FILES_SO) $(FILES_EXE); @echo $(CXXFLAGS) $(CXXFLAGS_COMPLETE) > $@
val-%:; @echo $($*)
var-%:; @echo '"$$($*)"="$($*)"'
state-%:; @echo '$$(value $*)=$(value $*)'
vars-%:; @$(foreach V,$($*),echo '$V={$($V)}';)
# Now clean-main removes bin/main, and clean-bin and clean-EXE are the same
# - but this is too greedy to run without a --dry-run pass, which outweighs
# or negates the benefit of convenience for the uninitiated.
clean-%:; @rm -i -f $(wildcard $(filter $*% %$* %$*%,\
$(foreach V,EXE SO O D TD,$(call PAT_$V,$(NAMES_EXE) $(NAMES_SO))))\
$(call DO_EA,$(*:%=PAT_%),$(NAMES_EXE) $(NAMES_SO)))
clean: $(addprefix clean-,EXE SO O D COMPLETE)
BUILD_DEP=$(CXX) $(CXXFLAGS) -MM $(BR) -MT '$(DIR_O)$*.o' $< -MF $@
$(call PAT_D,$(NAMES_EXE)): $(DIR_O)%.d: $(DIR_APP)%.cpp; $(BUILD_DEP)
$(call PAT_D,$(NAMES_SO)): $(DIR_O)%.d: $(DIR_SRC)%.cpp; $(BUILD_DEP)
$(call PAT_EXE,$(NAMES_EXE)): $(DIR_BIN)%: $(DIR_O)%.o $(DIR_O)%.d #$(FILES_SO) $(DEPS_$*)
$(CXX) $(LDFLAGS)\
$(strip -o $@ $< $(LDLIBS) $(LDLIBS_$*) $(sort $(call CONFIG_SO,$(REQ_$*))))
$(foreach X,$(NAMES_EXE),$(eval \
$$(call PAT_EXE,$X): $$(DEPS_$X)))
$(call PAT_O,$(NAMES_EXE)): $(DIR_O)%.o: \
$(DIR_APP)%.cpp $(DIR_O)%.d $(foreach N,CPP O SO,$(call $N_EXTRACT,$*))
$(CXX) $(CXXFLAGS) $(CXXFLAGS_$*) $(sort $(call CONFIG_O,$(REQ_$*))) -c\
$(strip -o $@ $<)
$(call PAT_SO,$(NAMES_SO)): $(DIR_SO)lib%.so: $(DIR_O)%.o
$(CXX) $(LDFLAGS) $< -shared\
$(strip -o $@ $(LDLIBS) $(LDLIBS_$*) $(sort $(call CONFIG_SO,$(REQ_$*))))
$(call PAT_O,$(NAMES_SO)): \
$(DIR_O)%.o: $(DIR_SRC)%.cpp $(DIR_DEP)%.d \
$(foreach N,CPP O SO,$(call $N_EXTRACT,$*))
$(CXX) $(CXXFLAGS) $(CXXFLAGS_$*) $(sort $(call CONFIG_O,$(REQ_$*))) -fPIC -c \
$(strip -o $@ $(call PAT_SRC,$*) $<)
$(foreach L,$(NAMES_SO),$(eval \
$$(call PAT_SO,$L): $$(DEPS_$L)))
# Inputs and makefiles are never targets - make can skip a lot of implicit rules
$(foreach F, $(wildcard Makefile* *.mk $(DIR_APP)* $(DIR_SRC)* $(DIR_HDR)*),$(eval $(F):;))
#SOS_view=$(call REPAT,CPP,SO,$(wildcard \
$(call PAT_CPP,$(patsubst -l%,%,$(filter -l%,$(LDLIBS_view))))))
# Generate auto-dep injection - what could go wrong?
#-include $(call PAT_D,$(NAMES_EXE) $(NAMES_SO))
include $(wildcard $(DEPS_EXE) $(DEPS_SO)) Doxygen.mk $(wildcard $(POST))
debug: override CXXFLAGS+=-Og -ggdb -g3 -fno-omit-frame-pointer
debug: clean default
.PHONY: val-% var-% vars-% state-% debug clean-% clean
.PRECIOUS: $(DIR_DEP)%.d $(COMPLETE)