1
2COREPATH=../../../src
3
4#include $(COREPATH)/Makefile.defs
5
6CFG2TXT=../../scripts/cdefs2doc/dump_counters.pl
7CFG2DOCBOOK=../../scripts/cdefs2doc/dump_counters.pl
8
9# output directory for generated txt files
10txt_output_dir=.
11# output directory for generated docbook xml files
12docbook_output_dir=docbook
13
14# list of files containing counter defs in the following format:
15# <filename>:<cfg_grp_name>
16# can be easily updated by adding the output of:
17#   make diff-list   (which obeys grp_exclude and file_exclude)
18# or completely regenerated by replacing files_list with the output of:
19#   make gen-files-list
20files_list= \
21	$(COREPATH)/core/resolve.c:resolve \
22	$(COREPATH)/core/tcp_stats.c:tcp \
23	$(COREPATH)/modules/cdp/cdp_stats.c:cdp \
24	$(COREPATH)/modules/db_mysql/db_mysql.c:db_mysql \
25	$(COREPATH)/modules/ims_charging/ims_charging_stats.c:ims_charging \
26	$(COREPATH)/modules/ims_dialog/dlg_ng_stats.c:ims_dialog \
27	$(COREPATH)/modules/ims_qos/ims_qos_stats.c:ims_qos \
28	$(COREPATH)/modules/ims_usrloc_scscf/ul_scscf_stats.c:ims_usrloc_scscf \
29	$(COREPATH)/modules/sctp/sctp_stats.c:sctp
30
31
32# list of excluded groups
33grp_exclude=
34# list of file prefixes to exclude (full path needed)
35file_exclude=$(COREPATH)/obsolete
36
37# special per file group overrides
38# format= grp_filename=... ,where filename does not contain the extension
39# e.g.:
40#     grp_f_tcp_stats=tcp
41#     grp_f_sctp_stats=sctp
42
43# special per group group name overrides
44# e.g.:
45#      grp_g_maxfwd=mf
46grp_g_resolve=dns
47grp_g_db_mysql=mysql
48
49# override auto-detected group if set to 1 (else the group is used inside the
50# file only if it cannot be autodetected)
51ifeq ($(group_override),1)
52override force_grp=force-
53else
54override force_grp=
55endif
56
57# command used for gcc (contains extra includes)
58gcc=gcc
59#-I$(COREPATH)/lib -I$(COREPATH) -I/usr/include/libxml2
60
61# defines used by gcc
62c_defs=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \
63	   -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' \
64	   -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 \
65	   -DCFG_DIR='\"/usr/local/etc/kamailio/\"' \
66	   -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \
67	   -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \
68	   -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLACKLIST -DUSE_NAPTR \
69	   -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \
70	   -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \
71	   -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \
72	   -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \
73	   -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL \
74	   -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM \
75	   -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT \
76	   -DSIGINFO64_WORKARROUND -DUSE_FUTEX -DHAVE_SELECT
77
78
79# common makefile vars used in defs
80LOCALBASE=/usr/local
81SYSBASE=/usr
82
83filter_files=$(filter-out $(addsuffix %,$(file_exclude)),\
84				$(filter-out $(addprefix %:,$(grp_exclude)),$(1)))
85
86#filtered files list
87flist=$(call filter_files,$(files_list))
88
89# throws an error if input is not in the format filename:grp
90check_fname_grp=$(if $(filter-out 2,$(words $(subst :, ,$(1)))),\
91					$(error bad format "$(1)", it should be filename:grp))
92
93# get prereq from file:grp (get_prereq(file:grp) => file)
94get_prereq=$(firstword $(subst :, ,$(1)))
95
96# get grp from file:grp (get_grp(file:grp) => grp)
97get_listed_grp=$(word 2, $(subst :, ,$(1)))
98
99# get base file name from file:grp: get_bname(file:grp)
100# => basename(file) without extension (e.g. get_bname(foo/bar.c:x) => bar)
101#
102get_bname=$(basename $(notdir $(call get_prereq,$(1))))
103
104#get grp from file:grp, using the overrides
105get_grp=$(strip $(if $(grp_f_$(call get_bname,$(1))), \
106					$(grp_f_$(call get_bname,$(1))),\
107					$(if $(grp_g_$(call get_listed_grp,$(1))),\
108						$(grp_g_$(call get_listed_grp,$(1))),\
109						$(call get_listed_grp,$(1))) ) )
110
111# get target from file:grp (get_target(file:grp) => counter_grp.txt)
112get_target=counters_$(call get_grp,$(1))
113
114
115# $(LF) definition (do not remove)
116define LF
117
118
119endef
120
121# get all the lines containing DEFS or INCLUDES definitions from the Makefile.
122# WARNING: does not work with all sed implementation (tested with GNU sed).
123# It uses a hack to restore the LFs (LFs are removed by $(shell)): LFs are
124# replaced with '^LF^' and then ^LF^ is subst'ed back to a real LF.
125get_make_idefs=$(subst ^LF^,$(LF),$(shell sed \
126 -ne '/^[\t ]*\(DEFS\|INCLUDES\)[\t ]*[+:]\?=.*[^\]$$/H'\
127 -ne '/^[\t ]*\(DEFS\|INCLUDES\)[\t ]*[+:]\?=.*\\$$/,/\(^$$\)\|\([^\]$$\)/H'\
128 -ne '$${g;s/\n/^LF^/g;p}'\
129< $(1)/Makefile ))
130
131
132# get all the lines from the makefile containing variable definitions.
133# It will also return conditionals and try to filter out possible rules.
134# WARNING: does not work with all sed implementation (tested with GNU sed).
135# It uses a hack to restore the LFs (LFs are removed by $(shell)): LFs are
136# replaced with '^LF^' and then ^LF^ is subst'ed back to a real LF.
137get_make_vars=$(subst ^LF^,$(LF),$(shell sed -n \
138 -e ': start' \
139 -e '/^\(ifeq\|ifneq\|else\|endif\)[\t ]*\($$\|.*[^\]$$\)/{H;b end}' \
140 -e '/^\(ifeq\|ifneq\|else\|endif\)[\t ]\+.*[\]$$/,/[^\]$$/{H;b end}' \
141 -e '/^[a-zA-Z._/$$][a-zA-Z0-9._()/$$ \t-]*:\([^=]\|$$\)/b eat_rule' \
142 -e '/^[\t ]*[A-Za-z._][A-Za-z0-9._-]*[\t ]*[+:]\?=.*[^\]$$/{H;b end}' \
143 -e '/^[\t ]*[A-Za-z._][A-Za-z0-9._-]*[\t ]*[+:]\?=.*\\$$/,/\(^$$\)\|\([^\]$$\)/{H;b end}' \
144 -e ': end' \
145 -e '$${g;s/\n/^LF^/g;p}'\
146 -e 'b' \
147 -e ': eat_rule' \
148 -e '$$b end' \
149 -e 'n' \
150 -e '/^[a-zA-Z._/$$][a-zA-Z0-9._()/$$ \t-]*:\([^=]\|$$\)/b eat_rule' \
151 -e '/^[\t]/b eat_rule' \
152 -e 'b start' \
153< $(1)/Makefile ))
154
155
156define  mk_rules
157
158$(call check_fname_grp, $(1))
159
160#$$(info generating counter_$$(call get_grp,$(1)).txt: $$(call get_prereq,$(1)))
161
162
163DEFS:=
164INCLUDES:=
165# extract all the includes and defs from the module makefile and
166# evaluate them
167$$(eval $$(call get_make_vars,$$(dir $$(call get_prereq,$(1)))))
168# override COREPATH (we know better)
169COREPATH=../../../src
170# save the result in a per group e_idefs_<grp_name> var
171$$(eval e_idefs_$$(call get_grp,$(1)):=$$(DEFS) $$(INCLUDES))
172
173# debugging:
174#$$(info eval: $$(call get_make_vars,$$(dir $$(call get_prereq,$(1)))))
175#$$(info e_idefs_$$(call get_grp,$(1))=$$(e_idefs_$$(call get_grp,$(1))))
176
177$(txt_output_dir)/$$(call get_target,$(1)).txt: \
178								$$(call get_prereq,$(1)) Makefile $(CFG2TXT)
179	$(CFG2TXT) --file $$< --$(force_grp)grp=$$(call get_grp,$(1)) \
180		--gcc="$(gcc)" --txt \
181		--defs="$(c_defs) $$(e_idefs_$$(call get_grp,$(1)))" \
182		> "$$@" || (rm -f "$$@"; exit 1)
183
184$(docbook_output_dir)/$$(call get_target,$(1)).xml: \
185								$$(call get_prereq,$(1)) Makefile $(CFG2TXT)
186	$(CFG2DOCBOOK) --file $$< --$(force_grp)grp=$$(call get_grp,$(1)) \
187		--gcc="$(gcc)" --docbook \
188		--defs="$(c_defs) $$(e_idefs_$$(call get_grp,$(1)))" \
189		> "$$@" || (rm -f "$$@"; exit 1)
190
191
192clean_$$(call get_target,$(1)).txt:
193	rm -f "$(txt_output_dir)/$$(call get_target,$(1)).txt"
194
195clean_$$(call get_target,$(1)).xml:
196	rm -f "$(docbook_output_dir)/$$(call get_target,$(1)).xml"
197
198txt: $(txt_output_dir)/$$(call get_target,$(1)).txt
199
200docbook: $(docbook_output_dir)/$$(call get_target,$(1)).xml
201
202clean_txt: clean_$$(call get_target,$(1)).txt
203
204clean_docbook: clean_$$(call get_target,$(1)).xml
205
206
207endef
208
209find_counter_files_cmd= find $(COREPATH) -type f -name "*.c" \
210		-exec grep "counter_def_t[	 ][	 ]*[a-zA-Z0-9_][a-zA-Z0-9_]*\[\][	 ]*=" /dev/null {} \; \
211		| cut -d: -f1
212
213# shell command to generate a file:grp list from a list of files
214# grp will be the modulename if the file is in a module directory or
215# the file name with the extension and _cnt, cnt_, _stats, stats_,
216# _cnts, or cnts_ stripped out of
217# it.
218# output: list of  " "filename":"grpname
219gen_file_grp_cmd=\
220sed -e "s!\(.*/modules[^/]*/\([^/][^/]*\)/.*\)! \1:\2!" \
221    -e "s!^\([^ ].*/\([^/.]*\)[^/]*$$\)!\1:\2!" \
222    -e "s!^\([^ :]*\):\(.*\)_cnts\?[_]*!\1:\2!" \
223    -e "s!^\([^ :]*\):\(.*\)cnts\?[_]*!\1:\2!" \
224    -e "s!^\([^ :]*\):\(.*\)_stats[_]*!\1:\2!" \
225    -e "s!^\([^ :]*\):\(.*\)stats[_]*!\1:\2!"
226
227# special vars for generating the list of files or updates
228found_lst=$(shell $(find_counter_files_cmd) | $(gen_file_grp_cmd))
229# filtered found lst
230f_found_lst=$(call filter_files,$(found_lst))
231diff_lst=$(filter-out $(flist),$(f_found_lst))
232
233
234get_core_files=$(filter-out $(COREPATH)/modules% $(COREPATH)/lib%,$(1))
235sort_files=$(sort $(call get_core_files,$(1)))\
236			$(sort $(filter-out $(call get_core_files,$(1)),$(1)))
237
238# replace $(COREPATH) with the text "$(COREPATH)"
239subst_corepath=$(patsubst $(patsubst %/,%,$(COREPATH))/%,\$$(COREPATH)/%,$(1))
240
241
242# help will be the default rule (on-purpose since without having a patched
243# GCC:TranslationUnit module, make all won't work)
244.PHONY: help
245help:
246	@echo "To regenerate $(foreach f,$(flist),$(call get_target,$f).{txt,xml})"
247	@echo "type: $(MAKE) all ."
248	@echo "or to regenerate all the counter lists by searching all"
249	@echo " the source files for definitions, type: $(MAKE) autogen ."
250	@echo "NOTE: you need the GCC:TranslationUnit perl module with an "
251	@echo "extra patch applied (see $(CFG2TXT) --patch)."
252
253.PHONY: txt
254txt:
255
256.PHONY: docbook
257docbook:
258
259.PHONY: clean_txt
260clean_txt:
261
262.PHONY: clean_docbook
263clean_docbook:
264
265
266.PHONY: all
267all: txt $(docbook_output_dir)/counter_list.xml
268
269.PHONY: clean
270clean: clean_txt clean_docbook
271	@rm -f $(docbook_output_dir)/counter_list.xml
272
273.PHONY: proper
274proper:
275	@rm -f $(txt_output_dir)/counters_*.txt
276	@rm -f $(docbook_output_dir)/counters_*.xml
277
278repo_ver="sip-router"\
279	"git-$(shell  git rev-parse --verify --short=6 HEAD 2>/dev/null)"
280ifeq ($(repo_ver),git-)
281repo_ver="sip-router unknown"
282endif
283
284$(docbook_output_dir)/counter_list.xml: Makefile \
285		$(foreach f,$(flist),$(docbook_output_dir)/$(call get_target,$f).xml)
286	@echo '<?xml version="1.0" encoding="UTF-8"?>' >$@
287	@echo '<!-- this file is autogenerated, do not edit! -->' >>$@
288	@echo '<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"' >>$@
289	@echo '	"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"' >>$@
290	@echo '	[ <!ENTITY % local.common.attrib' >>$@
291	@echo "	 \"xmlns:xi CDATA #FIXED 'http://www.w3.org/2001/XInclude'\">]">>$@
292	@echo '>' >>$@
293	@echo '<book id="counter_list"'\
294		'xmlns:xi="http://www.w3.org/2001/XInclude">' >>$@
295	@echo '	<title>Counter List</title>' >>$@
296	@echo '	<bookinfo>' >>$@
297	@echo '   <productname class="trade">kamailio.org</productname>' >>$@
298	@echo '   <authorgroup>' >>$@
299	@echo '    <author>' >>$@
300	@echo '      <firstname>Kamailio</firstname>' >>$@
301	@echo '      <surname>Development Team</surname>' >>$@
302	@echo '      <affiliation><orgname>https://www.kamailio.org</orgname></affiliation>' >>$@
303	@echo '      <address>sr-dev@lists.kamailio.org</address>' >>$@
304	@echo '    </author>' >>$@
305	@echo '   </authorgroup>' >>$@
306	@echo '   <copyright>' >>$@
307	@echo '    <year>2008-2017</year>' >>$@
308	@echo '    <holder>Kamailio Project</holder>' >>$@
309	@echo '   </copyright>' >>$@
310	@echo '	</bookinfo>' >>$@
311	@$(foreach f,$(flist),\
312		echo '		<xi:include'\
313			'href="'$(call get_target,$f).xml'"/>' \
314			>>$@ ; )
315	@echo '</book>' >>$@
316
317# finds all the files containing cfg defs
318.PHONY: find
319find:
320	@$(find_counter_files_cmd)
321
322# print the list of the autogenerated files
323.PHONY: print-lst
324print-lst:
325	@$(find_counter_files_cmd) | $(gen_file_grp_cmd)
326
327#
328.PHONY: gen-file-list
329.PHONY: gen-files_list
330.PHONY: gen_files_list
331gen-file-list gen-files-list gen_files_list:
332	@$(foreach f,$(call subst_corepath,$(call sort_files,$(f_found_lst))),\
333		echo "$f \\";)
334
335.PHONY: check-list
336.PHONY: update-list
337.PHONY: diff-list
338check-list update-list diff-list:
339	@$(foreach f,$(call subst_corepath,$(call sort_files,$(diff_lst))),\
340		echo "$f \\";)
341
342
343# try to generate the docs from all the sources
344.PHONY: autogen
345autogen:
346	@$(MAKE) all files_list="$(call sort_files,$(f_found_lst))"
347
348$(foreach f,$(flist),$(eval $(call mk_rules,$(f))))
349