-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMakefile
142 lines (98 loc) · 3.8 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
141
142
S = src
O = obj
L = lib
I = inc
D = dep
define n
endef
CC = clang++ --std=c++20 -O3
include project.mk
ifneq ($L,)
ifeq ($(wildcard $L),)
$(error lib directory not found : "$L"$n\
If you are calling make from another directory, please give the path to the lib folder to this makefile)
endif
endif
RM = rm -fv $1
RMDIR = $(if $(wildcard $1),$(if $(if $1,$(shell ls $1),),$(warning "$1 is not empty, not removed"),rmdir $1))
DEP = $(SRC:$S/%.cpp=$D/%.d)
OBJ = $(SRC:$S/%.cpp=$O/%.o)
TMP_DIRS=$(sort $(foreach DIRS,$(OBJ) $(DEP),$(dir $(shell echo '$(DIRS)' | sed ':do;p;s,^\(.*\)/[^/]*$$,\1,;\%^\(.*\)/[^/]*$$%b do;d'))))
INCLUDES += $I
$(foreach MOD,$(LIB_MOD),$(eval $(MOD)_DIR?=$L/$(MOD)))
LIB = $(foreach MOD,$(LIB_MOD),$(patsubst %,$($(MOD)_DIR)/%,$($(MOD)_LIB)))
INCLUDES += $(foreach MOD,$(LIB_MOD),$(patsubst %,$($(MOD)_DIR)/%,$($(MOD)_INC)))
LDFLAGS += $(foreach LIBRARY,$(LIB),-L$(dir $(LIBRARY)) -l$(patsubst lib%.a,%,$(notdir $(LIBRARY))))
LIB_DEP = $(LIB:%=%.d)
$(foreach MOD,$(CMAKE_LIB_MOD),$(eval $(MOD)_DIR?=$L/$(MOD)))
CMAKE_LIB = $(foreach MOD,$(CMAKE_LIB_MOD),$(if $($(MOD)_LIB),$(patsubst %,$($(MOD)_DIR)/build/%,$($(MOD)_LIB))))
INCLUDES += $(foreach MOD,$(CMAKE_LIB_MOD),$(if $($(MOD)_INC),$(patsubst %,$($(MOD)_DIR)/%,$($(MOD)_INC))))
LDFLAGS += $(foreach LIBRARY,$(CMAKE_LIB),-L$(dir $(LIBRARY)) -l$(patsubst lib%.a,%,$(notdir $(LIBRARY))))
UNAME_S = $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CPPFLAGS +=
LDFLAGS +=
else ifeq ($(UNAME_S),Darwin)
CPPFLAGS +=
LDFLAGS +=
else
$(error OS not supported)
endif
.PHONY: all, clean, clean(), fclean, libclean, libclean(), realclean, re, relib, space, force
all: $(LIB_TARGET) $(EXEC_TARGET)
$(TMP_DIRS) $I:
@mkdir -p $@
.SECONDEXPANSION:
$D/%.d: $S/%.cpp | $$(dir $$@) $(INCLUDES)
$(info Updating dep list for $<)
@$(CC) -MM $(CPPFLAGS) $(INCLUDES:%=-I%) $< | \
sed 's,\($*\)\.o[ :]*,$O/\1.o $@ : ,g' > $@; \
.SECONDEXPANSION:
$(OBJ): $O/%.o: $S/%.cpp | $$(dir $$@) $(INCLUDES)
$(CC) -c -o $@ $(CPPFLAGS) $(INCLUDES:%=-I%) $<
define submodule_init
$(if $(wildcard $(1)), , $(shell git submodule update --init --progress --remote))
endef
define init_includes
$($(1)_INC:%=$($(1)_DIR)/%):
$(call submodule_init,$($(1)_DIR))
endef
$(foreach MOD,$(LIB_MOD) $(CMAKE_LIB_MOD),$(eval $(call init_includes,$(MOD))))
$(foreach MOD,$(CMAKE_LIB_MOD),$(eval $($(MOD)_DIR)/build/$($(MOD)_LIB): MOD = $(MOD)))
$(CMAKE_LIB): DIR = $($(MOD)_DIR)/build
$(CMAKE_LIB):
@mkdir -p $(DIR)
@sh -c "cd $(DIR); cmake .."
@$(MAKE) -C $(DIR)
$(foreach MOD,$(LIB_MOD),$(eval $($(MOD)_DIR)/$($(MOD)_LIB): MOD = $(MOD)))
$(LIB): DIR = $($(MOD)_DIR)
.SECONDEXPANSION:
$(LIB): $$(shell $$(MAKE) -C $$(DIR) -q $$($$(MOD)_LIB) > /dev/null || echo force)
@$(MAKE) -C $(DIR) $($(MOD)_LIB) L='$L'
$(EXEC_TARGET): $(LIB) $(if $(wildcard $(if $(CUSTOM_LIBS),noexternal,external)),clean) $(OBJ) project.mk | $(CMAKE_LIB)
@touch $(if $(CUSTOM_LIBS),external,noexternal)
$(CC) -o $@ $(OBJ) $(CPPFLAGS) $(LDFLAGS)
$(LIB_TARGET): $(OBJ) project.mk
ar -rc $@ $(OBJ)
ranlib $@
$(patsubst %,clean@%,$(OBJ) $(DEP) external noexternal $(EXEC_TARGET) $(LIB_TARGET)): clean@%:
@$(call RM,$*)
$(foreach FILE,$(OBJ) $(DEP) $(TMP_DIR),$(eval $(if $(filter-out ./,$(dir $(FILE))),clean@$(dir $(FILE)): clean@$(FILE),)))
$(TMP_DIRS:%=clean@%):
@$(call RMDIR,$%)
clean: $(TMP_DIRS:%=clean@%) clean@external clean@noexternal
fclean: clean $(patsubst %,clean@%,$(EXEC_TARGET) $(LIB_TARGET))
$(LIB_MOD:%=libclean@$L/%): libclean@%:
@$(MAKE) -s -C $* fclean "L="
$(CMAKE_LIB_MOD:%=libclean@$L/%/build): libclean@%:
rm -Rf $*
libclean: $(LIB_MOD:%=libclean@$L/%)
realclean: $(CMAKE_LIB_MOD:%=libclean@$L/%/build) libclean fclean
re: fclean all
relib: libclean all
force:
@true
-include customrules.mk
ifeq ($(filter %clean relib re %.d,$(MAKECMDGOALS)),)
-include $(patsubst $O%.o,$D%.d,$(wildcard $(OBJ)))
endif