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