Make.rules 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. .DEFAULT_GOAL := all
  2. .PHONY: all clean install count FORCE
  3. export MAKEFLAGS
  4. MAKEFLAGS += --no-print-directory
  5. ifneq (,$(DIRNAME))
  6. target_external :=
  7. endif
  8. I=$(if $(filter install,$(MAKECMDGOALS)),1,0)
  9. ifeq (,$(MAKEFILE_LIST))
  10. MAKEFILE_LIST := Makefile
  11. endif
  12. _INDEX := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  13. EXTDIRS := $(foreach p,$(target_external),$(if $(wildcard $p),,$(dir $p)))
  14. EXTIDXS := $(addprefix make_extdir_,$(wordlist 1,$(words $(EXTDIRS)),$(_INDEX)))
  15. all:: $(addprefix make_all_,$(SUBDIRS)) $(EXTIDXS) $(target) $(target_only);
  16. install:: $(addprefix make_all_,$(SUBDIRS)) $(EXTIDXS) $(target) $(target_only);
  17. ifeq ($I,1)
  18. all:: $(addprefix install_,$(target_install));
  19. install:: $(addprefix install_,$(target_install));
  20. endif
  21. FORCE:;
  22. clean:: $(addprefix make_clean_,$(SUBDIRS));
  23. #override CFLAGS += -Wall -D_GNU_SOURCE -D_REENTRANT -g -O2
  24. override CFLAGS += -Wall -D_GNU_SOURCE -D_REENTRANT -g
  25. ifeq ($(DEBUG), )
  26. override CFLAGS += -O2
  27. endif
  28. ECHO = /bin/echo
  29. ifneq (0,$C)
  30. RED = \\e[1m\\e[31m
  31. DARKRED = \\e[31m
  32. GREEN = \\e[1m\\e[32m
  33. DARKGREEN = \\e[32m
  34. BLUE = \\e[1m\\e[34m
  35. DARKBLUE = \\e[34m
  36. YELLOW = \\e[1m\\e[33m
  37. DARKYELLOW = \\e[33m
  38. MAGENTA = \\e[1m\\e[35m
  39. DARKMAGENTA = \\e[35m
  40. CYAN = \\e[1m\\e[36m
  41. DARKCYAN = \\e[36m
  42. RESET = \\e[m
  43. color:
  44. @$(ECHO) -e $(RED)RED$(RESET)
  45. @$(ECHO) -e $(GREEN)GREEN$(RESET)
  46. @$(ECHO) -e $(BLUE)BLUE$(RESET)
  47. @$(ECHO) -e $(YELLOW)YELLOW$(RESET)
  48. @$(ECHO) -e $(MAGENTA)MAGENTA$(RESET)
  49. @$(ECHO) -e $(CYAN)CYAN $(RESET)
  50. @$(ECHO) -e $(DARKRED)DARKRED$(RESET)
  51. @$(ECHO) -e $(DARKGREEN)DARKGREEN$(RESET)
  52. @$(ECHO) -e $(DARKBLUE)DARKBLUE$(RESET)
  53. @$(ECHO) -e $(DARKYELLOW)DARKYELLOW$(RESET)
  54. @$(ECHO) -e $(DARKMAGENTA)DARKMAGENTA$(RESET)
  55. @$(ECHO) -e $(DARKCYAN)DARKCYAN $(RESET)
  56. endif
  57. export P
  58. PSX = $(if $(findstring -j,-$(MAKEFLAGS)),$(GREEN)$(EPREFIX) )
  59. ifneq (,$(findstring clean,$(MAKECMDGOALS)))
  60. override P := 0
  61. EXTIDXS :=
  62. endif
  63. ifeq (0,$P)
  64. _TOTAL :=
  65. _TOTAL2 :=
  66. override TOTAL :=
  67. else
  68. _TOTAL := $(foreach p,$(basename $(filter-out %.so,$(target))),$($p_objs))
  69. _TOTAL2 := $(foreach p,$(basename $(filter %.so,$(target))),$($p_objs:.o=.pic.o))
  70. _TOTAL2 := $(words $(sort $(target) $(_TOTAL) $(_TOTAL2)))
  71. _TOTAL := $(SUBDIRS)
  72. endif
  73. $(foreach p,$(_TOTAL),$(eval $(shell $(MAKE) -s -C $p count DIRNAME=$p P=$P)))
  74. $(foreach p,$(EXTIDXS),$(eval $(shell $(MAKE) -s -C $(word $(subst make_extdir_,,$p),$(EXTDIRS)) count DIRNAME=$p P=$P)))
  75. _TOTAL += $(EXTIDXS)
  76. _TOTAL := $(if $(_TOTAL),$(words $(_TOTAL))*2 $(patsubst %,+$$(TOTAL_%),$(sort $(_TOTAL))))
  77. $(if $(_TOTAL),$(eval _TOTAL2:=$$(shell $(ECHO) $$$$(($(_TOTAL2)+$(_TOTAL))))))
  78. $(if $(TOTAL),,$(eval TOTAL:=$(_TOTAL2)))
  79. ifeq (0,$(TOTAL))
  80. TOTAL :=
  81. endif
  82. ifeq (,$(TOTAL))
  83. override PCT :=
  84. override PCT0 :=
  85. override PCT1 :=
  86. override inc :=
  87. else
  88. ifneq (,$(findstring -j,-$(MAKEFLAGS)))
  89. override PCT :=
  90. override PCT0 :=
  91. override PCT1 :=
  92. override inc :=
  93. else
  94. ifeq ($(START),)
  95. STEP := 0 00
  96. else
  97. STEP := $(START) $(shell B=$$(($(START)*100/$(TOTAL))); [ $$B -le 9 ] && B=0$$B; $(ECHO) $$B)
  98. endif
  99. START = $(firstword $(STEP))
  100. PCT0 = $(if $(findstring -j,-$(MAKEFLAGS)),," ")
  101. ifeq (2,$P)
  102. PCT1 = $(if $(findstring -j,-$(MAKEFLAGS)),,[$(TOTAL)/$(TOTAL)])
  103. PCT = $(if $(findstring -j,-$(MAKEFLAGS)),,[$(firstword $(STEP))/$(TOTAL)])
  104. else
  105. PCT1 = $(if $(findstring -j,-$(MAKEFLAGS)),,[100])
  106. PCT = $(if $(findstring -j,-$(MAKEFLAGS)),,[$(word 2,$(STEP))%])
  107. endif
  108. define inc
  109. $(if $(findstring -j,-$(MAKEFLAGS)),,STEP := $(shell A=$$(($(firstword $(STEP))+$(if $1,$1,1))); B=$$(($$A*995/$(TOTAL)/10)); [ $$B -le 9 ] && B=0$$B; $(ECHO) $$A $$B))
  110. endef
  111. ifeq (0,$P)
  112. inc := 0 00
  113. endif
  114. endif
  115. endif
  116. ifeq (default,$(origin LD))
  117. LD := $(CC)
  118. endif
  119. $(eval LD := $(CXX) -Wl,--as-needed)
  120. $(eval MMD = -MMD -MF .dep.$$@)
  121. define CC
  122. @$(ECHO) -e $(PCT) $(eval $(inc)) " CC "$(PSX)$(CYAN)$(patsubst tmp.%,%,$<) $(RESET)
  123. @gcc
  124. endef
  125. define CCSO
  126. @$(ECHO) -e $(PCT) $(eval $(inc)) " CC [PIC] "$(PSX)$(CYAN)$(patsubst tmp.%,%,$<) $(RESET)
  127. @gcc -fPIC
  128. endef
  129. define CXX
  130. @$(ECHO) -e $(PCT) $(eval $(inc)) " CXX "$(PSX)$(CYAN)$(patsubst tmp.%,%,$<) $(RESET)
  131. @g++
  132. endef
  133. define CXXSO
  134. @$(ECHO) -e $(PCT) $(eval $(inc)) " CXX [PIC] "$(PSX)$(CYAN)$(patsubst tmp.%,%,$<) $(RESET)
  135. @g++ -fPIC
  136. endef
  137. define MLD
  138. @$(ECHO) -e $(PCT) $(eval $(inc)) " LD "$(PSX)$(MAGENTA)$@ $(RESET)
  139. @$(LD)
  140. endef
  141. define MLDSO
  142. @$(ECHO) -e $(PCT) $(eval $(inc)) " LD [PIC] "$(PSX)$(MAGENTA)$@ $(RESET)
  143. @$(LD) -shared
  144. endef
  145. define AR
  146. @$(ECHO) -e $(PCT) $(eval $(inc)) " AR "$(PSX)$(MAGENTA)$@ $(RESET)
  147. @ar
  148. endef
  149. define BIN2C
  150. @$(ECHO) -e $(PCT) $(eval $(inc)) " BIN2C "$(PSX)$(YELLOW)$@ $(RESET)
  151. @xxd -i
  152. endef
  153. ENTER = @$(ECHO) -e $(PCT) $(eval $(inc)) " ENTER ==> "$(GREEN)
  154. LEAVE = @$(ECHO) -e $(PCT) $(eval $(inc)) " LEAVE <== "$(GREEN)
  155. define RM
  156. @$(ECHO) -e $(PCT0) " CLEAN "$(PSX)$(MAGENTA)$(if $(CLEAN),$(CLEAN),"<$(notdir $(CURDIR))>") $(RESET)
  157. @rm -f
  158. endef
  159. define INST
  160. @$(ECHO) -e $(PCT0) " INSTALL "$(PSX)$(YELLOW)$* $(RESET)
  161. @install
  162. endef
  163. DONE = @$(ECHO) -e $(PCT1) " DONE "$(MAGENTA)"<$(notdir $(CURDIR))>" $(RESET)
  164. BAD = ($(ECHO) -e $(PCT0) " BAD "$(PSX)$(RED)$(1) $(RESET); /bin/false)
  165. BAD = ($(ECHO) -e $(PCT0) " BAD "$(PSX)$(RED)$(1) $(RESET); /bin/false)
  166. MDEP = $(ECHO) -e $(PCT0) " MAKEDEP "$(YELLOW)$(EPREFIX)$(firstword $(MAKEFILE_LIST)) $(RESET) 1>&2
  167. tmp.%.c: %.c
  168. @ln -s $< $@
  169. tmp.%.cc: %.cc
  170. @ln -s $< $@
  171. tmp.%.cpp: %.cpp
  172. @ln -s $< $@
  173. %.pic.o: %.c
  174. $(CCSO) $(MMD) $(CFLAGS) $($*_cflags) -c -o $@ $<
  175. %_pic.o: %.c
  176. $(CCSO) $(MMD) $(CFLAGS) $($*_cflags) -c -o $@ $<
  177. %.o: %.c
  178. $(CC) $(MMD) $(CFLAGS) $($*_cflags) -c -o $@ $<
  179. %.pic.o: %.cc
  180. $(CXXSO) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  181. %_pic.o: %.cc
  182. $(CXXSO) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  183. %.o: %.cc
  184. $(CXX) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  185. %.pic.o: %.cpp
  186. $(CXXSO) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  187. %_pic.o: %.cpp
  188. $(CXXSO) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  189. %.o: %.cpp
  190. $(CXX) $(MMD) $(CFLAGS) $(CXXFLAGS) $($*_cflags) -c -o $@ $<
  191. %.bin.c: %
  192. $(BIN2C) $< >$@
  193. make_all_%::
  194. $(ENTER) $(EPREFIX)$* $(RESET)
  195. @$(MAKE) -s -C $* all DONE= I=$I P=$P TOTAL=$(TOTAL) START=$(START) EPREFIX=$(EPREFIX)$*/
  196. @$(eval $(call inc,$(TOTAL_$(strip $*))))
  197. $(LEAVE) $(EPREFIX)$* $(RESET)
  198. make_extdir_%::
  199. $(ENTER) $(word $*,$(EXTDIRS)) $(RESET)
  200. @$(MAKE) -s -C $(word $*,$(EXTDIRS)) all DONE= P=$P TOTAL=$(TOTAL) START=$(START)
  201. @$(eval $(call inc,$(TOTAL_make_extdir_$(strip $*))))
  202. $(LEAVE) $(word $*,$(EXTDIRS)) $(RESET)
  203. make_clean_%:
  204. @$(MAKE) -s -C $* clean CLEAN=$(if $(CLEAN),$(CLEAN)/)$*
  205. install_%.so: %.so
  206. @[ -f $(install_dir) ] || mkdir -p $(install_dir)
  207. $(INST) $(if $($*_soname),$($*_soname),$*.so) $(install_dir)
  208. $(if $($*_soname),@ln -sf $($*_soname) $(install_dir)/$*.so)
  209. install_%: %
  210. @[ -f $(install_dir) ] || mkdir -p $(install_dir)
  211. $(INST) $* $(if $(install_mode),-m $(install_mode),) $(install_dir)
  212. %: %.c
  213. %: %.cc
  214. %: %.cpp
  215. %: %.o
  216. _COMMA=,
  217. _method :=
  218. ifneq (,$(findstring second-expansion,$(.FEATURES)))
  219. # for gmake v3.81 or above, second-expansion method
  220. .SECONDEXPANSION:
  221. _SUB=:.o=.pic.o
  222. %.pic.a: $$(%_objs$$(_SUB))
  223. $(AR) cr $@ $^
  224. %.so: $$(%_objs$$(_SUB))
  225. # $(MLDSO) -z defs $(LDFLAGS) -o $(if $($*_soname),$($*_soname) -Wl$(_COMMA)-soname=$($*_soname),$@) $^ $($*_libs) $(LIBPATH) $(LIBS)
  226. $(MLDSO) -z defs $(LDFLAGS) -o $(if $($*_soname),$(if $($*_filename), $($*_filename), $($*_soname)) -Wl$(_COMMA)-soname=$($*_soname),$@) $^ $($*_libs) $(LIBPATH) $(LIBS)
  227. $(if $($*_soname),@ln -sf $($*_soname) $@)
  228. $(if $($*_soname),$(if $($*_filename), @ln -sf $($*_filename) $($*_soname)))
  229. # libdtc.so: $$(%_objs$$(_SUB))
  230. # $(MLDSO) -z defs $(LDFLAGS) -o $(if $($*_soname), $filename -Wl$(_COMMA)-soname=$($*_soname),$@) $^ $($*_libs) $(LIBPATH) $(LIBS)
  231. # $(if $($*_soname),@ln -sf $(filename) libdtc.so.1)
  232. # $(if $($*_soname),@ln -sf libdtc.so.1 $@)
  233. %.a: $$(%_objs)
  234. $(AR) cr $@ $^
  235. %: $$(%_objs)
  236. @test -n "$^" || $(call BAD,$@)
  237. $(MLD) $(LDFLAGS) -o $@ $^ $($*_libs) $(LIBPATH) $(LIBS)
  238. _method := second-expansion
  239. endif
  240. $(if $(_method),,$(if $(findstring i486,$(shell gcc -dumpmachine)),,$(eval _method := eval)))
  241. ifeq (eval,$(_method))
  242. # for gmake v3.80, $(eval) method
  243. define rule-piclib
  244. $p: $($(p:.pic.a=)_objs:.o=.pic.o)
  245. $$(AR) cr $p $$^
  246. endef
  247. define rule-lib
  248. $p: $($(p:.a=)_objs)
  249. $$(AR) cr $p $$^
  250. endef
  251. define rule-so
  252. $p: $($(p:.so=)_objs:.o=.pic.o)
  253. $$(MLDSO) -z defs $$(LDFLAGS) -o $(if $($(p:.so=)_soname),$($(p:.so=)_soname) -Wl$(_COMMA)-soname=$($(p:.so=)_soname),$p) $$^ $$($(p:.so=)_libs) $$(LIBPATH) $$(LIBS)
  254. $(if $($(p:.so=)_soname),@ln -s $($(p:.so=)_soname) $p)
  255. endef
  256. define rule-bin
  257. $p: $($p_objs)
  258. $$(MLD) $$(LDFLAGS) -o $p $$($p_objs) $$($p_libs) $$(LIBPATH) $$(LIBS)
  259. endef
  260. endif
  261. # gmake 3.80 don't allow ($eval) inside if/endif block
  262. $(foreach p,$(filter %.pic.a,$(target)),$(if $($(p:.pic.a=)_objs),$(eval $(rule-piclib))))
  263. $(foreach p,$(filter %.a,$(target)),$(if $($(p:.a=)_objs),$(eval $(rule-lib))))
  264. $(foreach p,$(filter %.so,$(target)),$(if $($(p:.so=)_objs),$(eval $(rule-so))))
  265. $(foreach p,$(filter-out %.a %.o %.so,$(target)),$(if $($p_objs),$(eval $(rule-bin))))
  266. ifneq (clean,$(MAKECMDGOALS))
  267. ifneq (count,$(MAKECMDGOALS))
  268. ifeq (,$(_method))
  269. # without $(eval), fallback to temporary Makefile
  270. _method := makefile
  271. define cmd-piclib
  272. $(ECHO) '$p: $($(p:.pic.a=)_objs:.o=.pic.o)' >>.make.dep; \
  273. $(ECHO) ' $$(AR) cr $p $$^' >>.make.dep
  274. endef
  275. define cmd-lib
  276. $(ECHO) '$p: $($(p:.a=)_objs)' >>.make.dep; \
  277. $(ECHO) ' $$(AR) cr $p $$^' >>.make.dep
  278. endef
  279. define cmd-so
  280. $(ECHO) '$p: $($(p:.so=)_objs:.o=.pic.o)' >>.make.dep; \
  281. $(ECHO) ' $$(MLDSO) -z defs $$(LDFLAGS) -o $(if $($(p:.so=)_soname),$($(p:.so=)_soname) -Wl$(_COMMA)-soname=$($(p:.so=)_soname),$p) $$^ $$($(p:.so=)_libs) $$(LIBPATH) $$(LIBS)' >>.make.dep; \
  282. $(ECHO) ' $(if $($(p:.so=)_soname),@ln -s $($(p:.so=)_soname) $p)' >>.make.dep
  283. endef
  284. define cmd-bin
  285. $(ECHO) '$p: $($p_objs)' >>.make.dep; \
  286. $(ECHO) ' $$(MLD) $$(LDFLAGS) -o $p $$($p_objs) $$($p_libs) $$(LIBPATH) $$(LIBS)' >>.make.dep
  287. endef
  288. ifeq (OK,$(shell [ $(firstword $(MAKEFILE_LIST)) -nt .make.dep ] && $(ECHO) OK))
  289. $(shell $(MDEP))
  290. $(shell >.make.dep)
  291. $(foreach p,$(filter %.pic.a,$(target)),$(if $($(p:.pic.a=)_objs),$(shell $(cmd-piclib))))
  292. $(foreach p,$(filter %.a,$(target)),$(if $($(p:.a=)_objs),$(shell $(cmd-lib))))
  293. $(foreach p,$(filter %.so,$(target)),$(if $($(p:.so=)_objs),$(shell $(cmd-so))))
  294. $(foreach p,$(filter-out %.a %.o %.so,$(target)),$(if $($p_objs),$(shell $(cmd-bin))))
  295. endif
  296. include .make.dep
  297. endif
  298. endif
  299. endif
  300. .SECONDARY:
  301. all::
  302. $(DONE)
  303. install:: all;
  304. clean::
  305. $(foreach p,$(filter %.so,$(target)),@-rm -f $($(p:.so=)_soname))
  306. clean::
  307. $(RM) .make.* *.o *.a *.d *.so .dep.* tmp.* *.log $(target) $(TSTS)
  308. count::
  309. @$(ECHO) TOTAL_$(if $(DIRNAME),$(DIRNAME),all)=$(TOTAL)
  310. method::
  311. @$(ECHO) rule method is $(_method).
  312. ifneq ($(wildcard .dep.*),)
  313. -include $(wildcard .dep.*)
  314. endif