1# Kamailio build system
2#
3# common Makefile rules, included by main Makefile & the  modules
4#
5
6#
7# Uses: NAME, ALLDEP, CC, CFLAGS, C_DEFS, DEFS, C_INCLUDES, INCLUDES, LIBS,
8#       MKDEP, auto_gen, auto_gen_others, auto_gen_keep,
9#       depends, objs, extra_objs, static_modules, static_modules_path,
10#       LD_RPATH
11# (all this must  be defined previously!,  see Makefile.defs & Makefile)
12# Optional: SER_LIBS - list of ser libraries that will be automatically
13#  built if necessary. Format: path/shortname, where shortname is the
14#  name passed to -l (e.g. for libprint.so the shortname is print)
15#
16
17
18# check if the saved cfg corresponds with the current one
19# (if not rebuild everything)
20ifeq (,$(filter $(nodep_targets),$(MAKECMDGOALS)))
21-include makecfg.lst
22# if trying  to build a lib automatically and the lib is already compiled,
23# don't rebuild it if the only differences in DEFS or INCLUDES are covered
24# by LIB_NOREBUILD_DEFS/LIB_NOREBUILD_INCLUDES
25LIB_NOREBUILD_DEFS=
26
27# don't rebuild if the differences are covered by NOREBUILD_DEFS or
28# NOREBUILD_INCLUDES
29ifneq ($(strip $(filter-out $(NOREBUILD_DEFS),\
30		$(C_DEFS) $(DEFS))),$(strip $(CFG_DEFS)))
31#$(warning different defs: <$(strip $(C_DEFS) $(DEFS))> != )
32#$(warning               : <$(strip $(CFG_DEFS))>)
33$(shell rm -f makecfg.lst)
34endif
35ifneq ($(strip $(filter-out $(NOREBUILD_INCLUDES),\
36			$(C_INCLUDES) $(INCLUDES))),$(strip $(CFG_INCLUDES)))
37$(shell rm -f makecfg.lst)
38endif
39endif
40
41ALLDEP+=makecfg.lst
42
43# returns current type: "" core/unknown, "M" module, "L" libray, "U" util
44crt_type=$(if $(MOD_NAME),M,$(if $(LIB_NAME),L,$(if $(UTIL_NAME),U)))
45
46cmd_CC=$(CC) $(CFLAGS) $(C_INCLUDES) $(INCLUDES) $(C_DEFS) $(DEFS) -c $< -o $@
47cmd_LD=$(LD) $(LDFLAGS) $(objs) $(extra_objs) $(ALL_LIBS) $(SER_RPATH) \
48	-o $(NAME)
49
50ifeq (,$(CC_MKDEP_OPTS))
51# if CCC_MKDEP_OPTS is empty => CC cannot generate dependencies on the fly
52cmd_MKDEP=$(MKDEP) $(filter -D% -I%,$(CFLAGS)) $(C_INCLUDES) $(INCLUDES) \
53			$(C_DEFS) $(DEFS) $< \
54		|  sed	-e 's/\#.*//' -e '/:[ 	]*$$/d' -e '/^[ 	]*$$/d' \
55				-e 's|.*:|$@: $$(wildcard |' -e 's/\([^\\]\)$$/\1)/'> $*.d
56else
57# deps can be generated on the fly by cmd_CC
58cmd_CC+=$(CC_MKDEP_OPTS)
59# no MKDEP command any more
60cmd_MKDEP=
61endif # CC_MKDEP_OPTS
62
63# what will be displayed if quiet==silent
64silent_cmd_CC=CC ($(CC)) [$(strip $(crt_type) $(NAME))]		$@
65silent_cmd_LD=LD ($(LD)) [$(strip $(crt_type) $(NAME))]		$@
66
67ifneq (,$(filter 0 no off verbose noisy, $(Q) $(QUIET)))
68override Q:=
69quiet=verbose
70#shell optional print
71oecho=echo $(1)
72else
73quiet=silent
74Q=1
75MAKE+= --no-print-directory
76#shell optional print
77oecho=
78endif
79
80module_make=	if [ -n "$(1)" -a -r "$(1)/Makefile" ]; then \
81			$(call oecho, "" ;) \
82			$(call oecho, "" ;) \
83			if  $$(MAKE) -C $(1) $(2) || [ ${err_fail} != 1 ] ; then \
84				:; \
85			else \
86				exit 1; \
87			fi ; \
88		else \
89			echo module not found: $(1) ; \
90			exit 1; \
91		fi ;
92
93quote:= "
94escall= $(subst $$,\$$,$(subst $(quote),\$(quote),$1))
95exec_cmd= $(if $($(quiet)_cmd_$(1)),\
96			@echo "$(call escall,$($(quiet)_cmd_$(1)))" ;) $(cmd_$(1))
97
98#implicit rules
99%.o:%.c  $(ALLDEP)
100	$(call exec_cmd,CC)
101	@$(call cmd_MKDEP)
102
103# use RPATH and SER_LIBS if needed (make install and the module depends
104# on some ser libs)
105
106ifneq	($(SER_LIBS),)
107# abspath & realpath don't work on make <= 3.80
108SER_LIBS_DIRS:=$(dir $(SER_LIBS))
109ifneq	(,$(filter install install% %install, $(MAKECMDGOALS)))
110lib_compile_for_install=yes
111expected_lib_ipath=$(lib_target)
112else
113lib_compile_for_install=$(compile_for_install)
114# function: expected_lib_ipath ser_lib_dir
115expected_lib_ipath=$(1)
116endif
117ifneq	($(LD_RPATH),)
118ifneq	(,$(filter install install% %install, $(MAKECMDGOALS)))
119SER_RPATH_LST:=$(lib_target)
120else
121# realpath is not supported in make 3.80 or older
122ifeq (,$(filter-out 3.80 3.80.%,$(MAKE_VERSION)))
123fullpath=$(shell cd $(1); pwd)
124else
125fullpath=$(realpath $(1))
126endif
127
128SER_RPATH_LST:=$(call fullpath,$(dir $(SER_LIBS)))
129endif
130ifneq	($(strip $(SER_RPATH_LST)),)
131SER_RPATH:=$(addprefix $(LD_RPATH),$(SER_RPATH_LST))
132endif
133endif
134ifeq ($(OS), darwin)
135SER_IPATH_LST:=$(addsuffix /libiname.lst,$(SER_LIBS_DIRS))
136#$(warning $(NAME) DARWIN, SER_LIBS=$(SER_LIBS), $(SER_LIBS_DIRS), ipath_lst=$(SER_IPATH_LST))
137endif
138endif
139
140ALL_LIBS=$(LIBS)
141
142ifeq	(,$(filter clean %clean clean% proper %proper proper%, $(MAKECMDGOALS)))
143ifneq ($(SER_LIBS),)
144-include librpath.lst
145ifneq ($(SER_RPATH_LST), $(LIB_RPATH_LST))
146$(shell rm -f librpath.lst)
147endif
148endif
149
150SER_LIBS_DEPS:= \
151	$(foreach l, $(SER_LIBS), $(dir $l)$(LIB_PREFIX)$(notdir $l)$(LIB_SUFFIX))
152ALL_LIBS+=$(foreach l, $(SER_LIBS), -L$(dir $l) -l$(notdir $l))
153
154$(NAME): librpath.lst $(SER_LIBS_DEPS)
155
156$(SER_LIBS_DEPS): FORCE
157	@$(MAKE) -wC $(dir $@)  compile_for_install=$(lib_compile_for_install) \
158		NOREBUILD_DEFS="$(NOREBUILD_DEFS) $(LIB_NOREBUILD_DEFS)" \
159		NOREBUILD_INCLUDES="$(NOREBUILD_INCLUDES) $(LIB_NOREBUILD_INCLUDES)"
160
161.PHONY: FORCE
162FORCE:
163
164ifneq ($(SER_IPATH_LST),)
165
166$(NAME): $(SER_IPATH_LST)
167
168$(SER_IPATH_LST): FORCE
169	@if grep \
170		"COMPILED_INAME:=$(call expected_lib_ipath,$(shell cd $(@D); pwd))" \
171		$(@) 1>/dev/null 2>/dev/null ; \
172	then :; \
173	else \
174		$(call oecho,"re-building $(@D)" ;) \
175		$(MAKE) -wC $(@D) compile_for_install=$(lib_compile_for_install) ; \
176	fi
177
178.PHONY: FORCE-BUILD-LIBS
179FORCE-BUILD-LIBS:
180	@for r in $(SER_LIBS_DIRS) ; do \
181		$(call oecho,building lib $$r ;) \
182		$(MAKE) -wC $$r compile_for_install=$(lib_compile_for_install) ; \
183	done
184
185endif
186
187endif
188
189# normal rules
190$(NAME): $(objs) $(ALLDEP)
191	$(call exec_cmd,LD)
192
193
194librpath.lst: $(ALLDEP)
195	@echo LIB_RPATH_LST:=$(SER_RPATH_LST) >librpath.lst
196
197makecfg.lst:
198	@echo "CFG_DEFS:=$(call escall,$(strip \
199			$(filter-out $(NOREBUILD_DEFS), $(C_DEFS) $(DEFS))))" >>$@
200	@echo "CFG_INCLUDES:=$(call escall,$(strip \
201			$(filter-out $(NOREBUILD_INCLUDES),\
202				$(C_INCLUDES) $(INCLUDES))))" >>$@
203.PHONY: all
204all: $(NAME) every-module
205
206.PHONY: static
207static: $(objs)
208
209# clean only the current directory (no modules or utils)
210# (it's useful to have it separated from clean for speeding up make proper)
211.PHONY: local-clean
212local-clean:
213	-@rm -f $(objs) $(NAME) $(objs:.o=.il) *.a librpath.lst 2>/dev/null
214
215.PHONY: clean
216clean: local-clean
217
218.PHONY: clean-modules
219clean-modules:
220	-@for r in $(cmodules) $(static_modules_path) "" ; do \
221		if [ -d "$$r" ]; then \
222			$(call oecho,"module $$r" ;) \
223			$(MAKE) -C "$$r" clean ; \
224			[ -r "$$r"/doc/Makefile ] && $(MAKE) -C "$$r"/doc clean ; \
225		fi ; \
226	done
227
228# make proper for the local directory
229.PHONY: proper
230.PHONY: distclean
231.PHONY: realclean
232.PHONY: maintainer-clean
233proper distclean realclean maintainer-clean: local-clean
234	-@rm -f $(depends) $(auto_gen) $(auto_gen_others) $(auto_gen_keep) \
235			makecfg.lst 2>/dev/null
236
237maintainer-clean: clean-tmp
238
239.PHONY: proper-modules
240.PHONY: distclean-modules
241.PHONY: realclean-modules
242.PHONY: maintainer-clean-modules
243proper-modules realclean-modules distclean-modules maintainer-clean-modules: \
244 clean_target=$(patsubst %-modules,%,$@)
245proper-modules realclean-modules distclean-modules maintainer-clean-modules:
246	-@for r in $(cmodules) "" ; do \
247		if [ -d "$$r" ]; then \
248			$(MAKE) -C "$$r" $(clean_target); \
249			[ -r "$$r"/doc/Makefile ] && $(MAKE) -C "$$r"/doc $(clean_target);\
250		fi ; \
251	done
252
253.PHONY: clean-tmp
254clean-tmp:
255	-@rm -f TAGS tags *.dbg .*.swp
256
257
258.PHONY: doxygen
259doxygen:
260	-@mkdir -p $(doxygen_dir)
261	-@echo "Create Doxygen documentation"
262	# disable call graphes, because of the DOT dependencies
263	(cat ./$(COREPATH)/doc/doxygen/ser.doxygen; \
264	echo "HAVE_DOT=no" ;\
265	echo "PROJECT_NAME=SIP-ROUTER" ;\
266	echo "PROJECT_NUMBER=$(NAME)-$(RELEASE)" )| doxygen -
267	-@echo "Doxygen documentation created"
268
269.PHONY: clean_doxygen
270clean_doxygen:
271	-@rm -rf $(doxygen_dir)/{xml,man,rtf,latex,html}
272	-@rmdir --ignore-fail-on-non-empty -p $(doxygen_dir) || true
273
274
275.PHONY: TAGS
276.PHONY: tags
277TAGS tags:
278	$(MKTAGS) --exclude="obsolete/*" --exclude="test/*" -R .
279
280.PHONY: TAGS-ALL
281.PHONY: tags-all
282TAGS-ALL tags-all:
283	$(MKTAGS) -R .
284
285
286
287ifeq (,$(MAKECMDGOALS))
288-include $(depends)
289else
290ifeq (,$(strip $(nodep_targets)))
291include $(COREPATH)/Makefile.targets
292endif
293ifneq (,$(filter-out $(nodep_targets),$(MAKECMDGOALS)))
294-include $(depends)
295endif
296endif # ifeq (,$(MAKECMDGOALS))
297