COREPATH=../../../src #include $(COREPATH)/Makefile.defs CFG2TXT=../../scripts/cdefs2doc/dump_rpcs.pl CFG2DOCBOOK=../../scripts/cdefs2doc/dump_rpcs.pl # output directory for generated txt files txt_output_dir=. # output directory for generated docbook xml files docbook_output_dir=docbook # list of files containing rpc defs in the following format: # : # can be easily updated by adding the output of: # make diff-list (which obeys grp_exclude and file_exclude) # or completely regenerated by replacing files_list with the output of: # make gen-files-list # NOTE: suffix duplicated modules located in modules_s with '_s' to # avoid file naming conflicts # files_list= \ $(COREPATH)/core/core_cmd.c:core \ $(COREPATH)/modules/app_jsdt/app_jsdt_api.c:app_jsdt \ $(COREPATH)/modules/app_lua/app_lua_mod.c:app_lua \ $(COREPATH)/modules/app_perl/app_perl_mod.c:app_perl \ $(COREPATH)/modules/app_sqlang/app_sqlang_api.c:app_sqlang \ $(COREPATH)/modules/auth_ephemeral/auth_ephemeral_mod.c:auth_ephemeral \ $(COREPATH)/modules/auth_xkeys/auth_xkeys.c:auth_xkeys \ $(COREPATH)/modules/benchmark/benchmark.c:benchmark \ $(COREPATH)/modules/call_obj/call_obj_mod.c:call_obj \ $(COREPATH)/modules/carrierroute/carrierroute.c:carrierroute \ $(COREPATH)/modules/cdp/cdp_rpc.c:cdp \ $(COREPATH)/modules/cfg_rpc/cfg_rpc.c:cfg_rpc \ $(COREPATH)/modules/cfgt/cfgt_int.c:cfgt \ $(COREPATH)/modules/cfgutils/cfgutils.c:cfgutils \ $(COREPATH)/modules/cnxcc/cnxcc_mod.c:cnxcc \ $(COREPATH)/modules/corex/corex_rpc.c:corex \ $(COREPATH)/modules/counters/counters.c:counters \ $(COREPATH)/modules/cplc/cpl_loader.c:cplc \ $(COREPATH)/modules/ctl/ctl.c:ctl \ $(COREPATH)/modules/db_berkeley/db_berkeley.c:db_berkeley \ $(COREPATH)/modules/db_flatstore/flat_rpc.c:db_flatstore \ $(COREPATH)/modules/db_flatstore/km_flatstore_mod.c:db_flatstore \ $(COREPATH)/modules/db_text/db_text.c:db_text \ $(COREPATH)/modules/debugger/debugger_api.c:debugger \ $(COREPATH)/modules/dialog/dialog.c:dialog \ $(COREPATH)/modules/dialplan/dialplan.c:dialplan \ $(COREPATH)/modules/dispatcher/dispatcher.c:dispatcher \ $(COREPATH)/modules/dmq/dmq.c:dmq \ $(COREPATH)/modules/domain/domain_mod.c:domain \ $(COREPATH)/modules/drouting/drouting.c:drouting \ $(COREPATH)/modules/htable/htable.c:htable \ $(COREPATH)/modules/http_client/curlrpc.c:http_client \ $(COREPATH)/modules/imc/imc.c:imc \ $(COREPATH)/modules/ims_dialog/ims_dialog.c:ims_dialog \ $(COREPATH)/modules/ims_registrar_scscf/reg_rpc.c:ims_registrar_scscf \ $(COREPATH)/modules/ims_usrloc_pcscf/ul_rpc.c:ims_usrloc_pcscf \ $(COREPATH)/modules/ims_usrloc_scscf/ul_rpc.c:ims_usrloc_scscf \ $(COREPATH)/modules/jsonrpcs/jsonrpcs_mod.c:jsonrpcs \ $(COREPATH)/modules/keepalive/keepalive_rpc.c:keepalive \ $(COREPATH)/modules/kex/core_stats.c:kex \ $(COREPATH)/modules/kex/mod_stats.c:kex \ $(COREPATH)/modules/kex/pkg_stats.c:kex \ $(COREPATH)/modules/lcr/lcr_rpc.c:lcr \ $(COREPATH)/modules/malloc_test/malloc_test.c:malloc_test \ $(COREPATH)/modules/matrix/matrix.c:matrix \ $(COREPATH)/modules/mqueue/mqueue_mod.c:mqueue \ $(COREPATH)/modules/msrp/msrp_cmap.c:msrp \ $(COREPATH)/modules/mtree/mtree_mod.c:mtree \ $(COREPATH)/modules/nathelper/nathelper.c:nathelper \ $(COREPATH)/modules/pdb/pdb.c:pdb \ $(COREPATH)/modules/pdt/pdt.c:pdt \ $(COREPATH)/modules/permissions/permissions.c:permissions \ $(COREPATH)/modules/pike/pike_rpc.c:pike \ $(COREPATH)/modules/pipelimit/pipelimit.c:pipelimit \ $(COREPATH)/modules/prefix_route/pr_rpc.c:prefix_route \ $(COREPATH)/modules/presence/presence.c:presence \ $(COREPATH)/modules/pua/pua.c:pua \ $(COREPATH)/modules/pua_rpc/pua_rpc.c:pua_rpc \ $(COREPATH)/modules/pv/pv.c:pv \ $(COREPATH)/modules/ratelimit/ratelimit.c:ratelimit \ $(COREPATH)/modules/regex/regex_mod.c:regex \ $(COREPATH)/modules/rls/rls.c:rls \ $(COREPATH)/modules/rtpengine/rtpengine.c:rtpengine \ $(COREPATH)/modules/rtpproxy/rtpproxy.c:rtpproxy \ $(COREPATH)/modules/sca/sca.c:sca \ $(COREPATH)/modules/sctp/sctp_rpc.c:sctp \ $(COREPATH)/modules/sipcapture/sipcapture.c:sipcapture \ $(COREPATH)/modules/siptrace/siptrace.c:siptrace \ $(COREPATH)/modules/sl/sl_stats.c:sl \ $(COREPATH)/modules/statsc/statsc_mod.c:statsc \ $(COREPATH)/modules/tls/tls_rpc.c:tls \ $(COREPATH)/modules/tm/tm.c:tm \ $(COREPATH)/modules/tsilo/ts_rpc.c:tsilo \ $(COREPATH)/modules/uac/uac_reg.c:uac \ $(COREPATH)/modules/uid_domain/domain_rpc.c:uid_domain \ $(COREPATH)/modules/uid_gflags/uid_gflags.c:uid_gflags \ $(COREPATH)/modules/userblacklist/userblacklist.c:userblacklist \ $(COREPATH)/modules/usrloc/ul_rpc.c:usrloc \ $(COREPATH)/modules/websocket/websocket.c:websocket \ $(COREPATH)/modules/xcap_client/xcap_client.c:xcap_client \ $(COREPATH)/modules/xhttp_pi/xhttp_pi.c:xhttp_pi # list of excluded groups grp_exclude=pa # list of file prefixes to exclude (full path needed) file_exclude=$(COREPATH)/obsolete # special per file group overrides # format= grp_filename=... ,where filename does not contain the extension # e.g.: # grp_f_tcp_options=tcp # grp_f_sctp_options=sctp # special per group group name overrides # e.g.: # grp_g_maxfwd=mf # override auto-detected group if set to 1 (else the group is used inside the # file only if it cannot be aut-odetected) ifeq ($(group_override),1) override force_grp=force- else override force_grp= endif # command used for gcc (contains extra includes) gcc=gcc #-I$(COREPATH)/lib -I$(COREPATH) -I/usr/include/libxml2 # defines used by gcc c_defsX=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \ -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' \ -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 \ -DCFG_DIR='\"/usr/local/etc/kamailio/\"' \ -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \ -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLACKLIST -DUSE_NAPTR \ -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \ -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \ -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \ -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL \ -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM \ -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT \ -DSIGINFO64_WORKARROUND -DUSE_FUTEX -DHAVE_SELECT c_defs=$(subst ^^,='\",$(subst ",\"',$(subst =",^^,$(shell $(MAKE) -s -C ../../../src printcdefs)))) c_defs+= -DMOD_NAME='\"rpcgen\"' c_defs+= -I$(COREPATH)/modules/app_sqlang/squirrel/include # common makefile vars used in defs LOCALBASE=/usr/local SYSBASE=/usr filter_files=$(filter-out $(addsuffix %,$(file_exclude)),\ $(filter-out $(addprefix %:,$(grp_exclude)),$(1))) #filtered files list flist=$(call filter_files,$(files_list)) # throws an error if input is not in the format filename:grp check_fname_grp=$(if $(filter-out 2,$(words $(subst :, ,$(1)))),\ $(error bad format "$(1)", it should be filename:grp)) # get prereq from file:grp (get_prereq(file:grp) => file) get_prereq=$(firstword $(subst :, ,$(1))) # get grp from file:grp (get_grp(file:grp) => grp) get_listed_grp=$(word 2, $(subst :, ,$(1))) # get module interface define get_modiface=$(word 3, $(subst :, ,$(1))) find_modiface=$(if $(findstring modules,$(1)),$(shell $(MAKE) -s -C $(dir $(1)) printmiface),-DNONE) # get base file name from file:grp: get_bname(file:grp) # => basename(file) without extension (e.g. get_bname(foo/bar.c:x) => bar) # get_bname=$(basename $(notdir $(call get_prereq,$(1)))) #get grp from file:grp, using the overrides get_grp=$(strip $(if $(grp_f_$(call get_bname,$(1))), \ $(grp_f_$(call get_bname,$(1))),\ $(if $(grp_g_$(call get_listed_grp,$(1))),\ $(grp_g_$(call get_listed_grp,$(1))),\ $(call get_listed_grp,$(1))) ) ) # get target from file:grp (get_target(file:grp) => rpc_grp.txt) get_target=rpc_$(call get_grp,$(1)) # $(LF) definition (do not remove) define LF endef # get all the lines containing DEFS or INCLUDES definitions from the Makefile. # WARNING: does not work with all sed implementation (tested with GNU sed). # It uses a hack to restore the LFs (LFs are removed by $(shell)): LFs are # replaced with '^LF^' and then ^LF^ is subst'ed back to a real LF. get_make_idefs=$(subst ^LF^,$(LF),$(shell sed \ -ne '/^[\t ]*\(DEFS\|INCLUDES\)[\t ]*[+:]\?=.*[^\]$$/H'\ -ne '/^[\t ]*\(DEFS\|INCLUDES\)[\t ]*[+:]\?=.*\\$$/,/\(^$$\)\|\([^\]$$\)/H'\ -ne '$${g;s/\n/^LF^/g;p}'\ < $(1)/Makefile )) # get all the lines from the makefile containing variable definitions. # It will also return conditionals and try to filter out possible rules. # WARNING: does not work with all sed implementation (tested with GNU sed). # It uses a hack to restore the LFs (LFs are removed by $(shell)): LFs are # replaced with '^LF^' and then ^LF^ is subst'ed back to a real LF. get_make_vars=$(subst ^LF^,$(LF),$(shell sed -n \ -e ': start' \ -e '/^\(ifeq\|ifneq\|else\|endif\)[\t ]*\($$\|.*[^\]$$\)/{H;b end}' \ -e '/^\(ifeq\|ifneq\|else\|endif\)[\t ]\+.*[\]$$/,/[^\]$$/{H;b end}' \ -e '/^[a-zA-Z._/$$][a-zA-Z0-9._()/$$ \t-]*:\([^=]\|$$\)/b eat_rule' \ -e '/^[\t ]*[A-Za-z._][A-Za-z0-9._-]*[\t ]*[+:]\?=.*[^\]$$/{H;b end}' \ -e '/^[\t ]*[A-Za-z._][A-Za-z0-9._-]*[\t ]*[+:]\?=.*\\$$/,/\(^$$\)\|\([^\]$$\)/{H;b end}' \ -e ': end' \ -e '$${g;s/\n/^LF^/g;p}'\ -e 'b' \ -e ': eat_rule' \ -e '$$b end' \ -e 'n' \ -e '/^[a-zA-Z._/$$][a-zA-Z0-9._()/$$ \t-]*:\([^=]\|$$\)/b eat_rule' \ -e '/^[\t]/b eat_rule' \ -e 'b start' \ < $(1)/Makefile )) define mk_rules $(call check_fname_grp, $(1)) #$$(info generating rpc_$$(call get_grp,$(1)).txt: $$(call get_prereq,$(1))) DEFS:= INCLUDES:= # extract all the includes and defs from the module makefile and # evaluate them $$(eval $$(call get_make_vars,$$(dir $$(call get_prereq,$(1))))) # override COREPATH (we know better) COREPATH=../../../src # save the result in a per group e_idefs_ var $$(eval e_idefs_$$(call get_grp,$(1)):=$$(DEFS) $$(INCLUDES)) # debugging: #$$(info eval: $$(call get_make_vars,$$(dir $$(call get_prereq,$(1))))) #$$(info e_idefs_$$(call get_grp,$(1))=$$(e_idefs_$$(call get_grp,$(1)))) $(txt_output_dir)/$$(call get_target,$(1)).txt: \ $$(call get_prereq,$(1)) Makefile $(CFG2TXT) $(CFG2TXT) --file $$< --$(force_grp)grp=$$(call get_grp,$(1)) \ --gcc="$(gcc)" --txt \ --defs="$(c_defs) $$(call get_modiface,$(1)) $$(e_idefs_$$(call get_grp,$(1)))" \ > "$$@" || (rm -f "$$@"; exit 1) $(docbook_output_dir)/$$(call get_target,$(1)).xml: \ $$(call get_prereq,$(1)) Makefile $(CFG2TXT) $(CFG2DOCBOOK) --file $$< --$(force_grp)grp=$$(call get_grp,$(1)) \ --gcc="$(gcc)" --docbook \ --defs="$(c_defs) $$(e_idefs_$$(call get_grp,$(1)))" \ > "$$@" || (rm -f "$$@"; exit 1) clean_$$(call get_target,$(1)).txt: rm -f "$(txt_output_dir)/$$(call get_target,$(1)).txt" clean_$$(call get_target,$(1)).xml: rm -f "$(docbook_output_dir)/$$(call get_target,$(1)).xml" txt: $(txt_output_dir)/$$(call get_target,$(1)).txt docbook: $(docbook_output_dir)/$$(call get_target,$(1)).xml clean_txt: clean_$$(call get_target,$(1)).txt clean_docbook: clean_$$(call get_target,$(1)).xml endef find_rpc_files_cmd= find $(COREPATH) -type f -name "*.c" \ -exec grep "rpc_export_t[ ][a-zA-Z0-9_]*\[\][ ]*=" /dev/null {} \; \ | cut -d: -f1 # shell command to generate a file:grp list from a list of files # grp will be the modulename if the file is in a module directory or # the file name with the extension and _cmd, cmd_ or _rpc stripped out of # it. # output: list of " "filename":"grpname gen_file_grp_cmd=\ sed -e "s!\(.*/modules[^/]*/\([^/][^/]*\)/.*\)! \1:\2!" \ -e "s!^\([^ ].*/\([^/.]*\)[^/]*$$\)!\1:\2!" \ -e "s!^\([^ :]*\):\(.*\)_cmd[_]*!\1:\2!" \ -e "s!^\([^ :]*\):\(.*\)cmd[_]*!\1:\2!" \ -e "s!^\([^ :]*\):\(.*\)_rpc[_]*!\1:\2!" # special vars for generating the list of files or updates found_lst=$(shell $(find_rpc_files_cmd) | $(gen_file_grp_cmd)) # filtered found lst f_found_lst=$(call filter_files,$(found_lst)) diff_lst=$(filter-out $(flist),$(f_found_lst)) get_core_files=$(filter-out $(COREPATH)/modules% $(COREPATH)/lib%,$(1)) sort_files=$(sort $(call get_core_files,$(1)))\ $(sort $(filter-out $(call get_core_files,$(1)),$(1))) # replace $(COREPATH) with the text "$(COREPATH)" subst_corepath=$(patsubst $(patsubst %/,%,$(COREPATH))/%,\$$(COREPATH)/%,$(1)) # help will be the default rule (on-purpose since without having a patched # GCC:TranslationUnit module, make all won't work) .PHONY: help help: @echo "To regenerate $(foreach f,$(flist),$(call get_target,$f).{txt,xml})" @echo "type: $(MAKE) all ." @echo "or to regenerate all the rpc lists by searching all" @echo " the source files for definitions, type: $(MAKE) autogen ." @echo "NOTE: you need the GCC:TranslationUnit perl module with an " @echo "extra patch applied (see $(CFG2TXT) --patch)." .PHONY: txt txt: .PHONY: docbook docbook: .PHONY: clean_txt clean_txt: .PHONY: clean_docbook clean_docbook: .PHONY: all all: txt $(docbook_output_dir)/rpc_list.xml .PHONY: clean clean: clean_txt clean_docbook @rm -f $(docbook_output_dir)/rpc_list.xml .PHONY: proper proper: @rm -f $(txt_output_dir)/rpc_*.txt @rm -f $(docbook_output_dir)/rpc_*.xml repo_ver="Kamailio "\ "git-$(shell git rev-parse --verify --short=6 HEAD 2>/dev/null)" ifeq ($(repo_ver),git-) repo_ver="Kamailio unknown" endif $(docbook_output_dir)/rpc_list.xml: Makefile \ $(foreach f,$(flist),$(docbook_output_dir)/$(call get_target,$f).xml) @echo '' >$@ @echo '' >>$@ @echo '>$@ @echo ' "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"' >>$@ @echo ' [ >$@ @echo " \"xmlns:xi CDATA #FIXED 'http://www.w3.org/2001/XInclude'\">]">>$@ @echo '>' >>$@ @echo '' >>$@ @echo ' RPC Commands List' >>$@ @echo ' ' >>$@ @echo ' kamailio.org' >>$@ @echo ' ' >>$@ @echo ' ' >>$@ @echo ' Kamailio' >>$@ @echo ' Development Team' >>$@ @echo ' https://www.kamailio.org' >>$@ @echo '
sr-dev@lists.kamailio.org
' >>$@ @echo '
' >>$@ @echo '
' >>$@ @echo ' ' >>$@ @echo ' 2008-2017' >>$@ @echo ' Kamailio Project' >>$@ @echo ' ' >>$@ @echo '
' >>$@ @$(foreach f,$(flist),\ echo ' ' \ >>$@ ; ) @echo '
' >>$@ # finds all the files containing cfg defs .PHONY: find find: @$(find_rpc_files_cmd) # print the list of the autogenerated files .PHONY: print-lst print-lst: @$(find_rpc_files_cmd) | $(gen_file_grp_cmd) # .PHONY: gen-file-list .PHONY: gen-files_list .PHONY: gen_files_list gen-file-list gen-files-list gen_files_list: @$(foreach f,$(call subst_corepath,$(call sort_files,$(f_found_lst))),\ echo "$f \\";) print-modifaces: @$(foreach f,$(call sort_files,$(f_found_lst)),\ echo "$(call subst_corepath,$(f)):$(call find_modiface, $(f)) \\";) .PHONY: check-list .PHONY: update-list .PHONY: diff-list check-list update-list diff-list: @$(foreach f,$(call subst_corepath,$(call sort_files,$(diff_lst))),\ echo "$f \\";) # try to generate the docs from all the sources .PHONY: autogen autogen: @$(MAKE) all files_list="$(call sort_files,$(f_found_lst))" $(foreach f,$(flist),$(eval $(call mk_rules,$(f))))