# -*- makefile-gmake -*- # $Id$ ### Rules for building within a single directory sources = sources DATE = /bin/date VDB_REQ = VDB # Interpret command-line specifications of APP_PROJ or LIB_PROJ as a # cue to clear out all other *_PROJ settings not also provided there. ifneq "$(filter command, $(origin APP_PROJ) $(origin LIB_PROJ))" "" APP_PROJ= LIB_PROJ= EXPENDABLE_APP_PROJ= EXPENDABLE_LIB_PROJ= ifeq "$(origin APP_PROJ):$(sources:sources=$(LIB_PROJ))" "command line:" ASN_PROJ= DTD_PROJ= XSD_PROJ= WSDL_PROJ= JSD_PROJ= PROTOBUF_PROJ= METAL_PROJ= endif endif ### Protect against two MAKE processes running in the same dir ifneq "" "$(filter-out @*@, $(CD_REPORTER))" ifneq "" "$(wildcard $(PYTHON3) $(VIRTUAL_ENV)/bin/python3)" RUN_WITH_CD_REPORTER = $(build_root)/build/run_with_cd_reporter.sh endif endif ifeq "$(wildcard $(build_root)/bin/run_with_lock)" "" RWL = $(abs_top_srcdir)/scripts/common/impl/run_with_lock.sh else RWL = $(build_root)/bin/run_with_lock \ -getter $(abs_top_srcdir)/scripts/common/impl/get_lock.sh \ -reviewer $(abs_top_srcdir)/scripts/common/impl/is_log_interesting.awk endif ifeq "$(srcdir)" "." ifneq "" "$(wildcard /net/snowman/vol/export2/win-coremake)" WIN_COREMAKE = /net/snowman/vol/export2/win-coremake else WIN_COREMAKE = /Volumes/win-coremake endif PTB_ROOT = $(WIN_COREMAKE)/App/Ncbi/cppcore/ptb BOOTSTRAP_PTB = $(build_root)/bin/project_tree_builder ifeq "$(PREBUILT_PTB_EXE)" "bootstrap" RELEASE_PTB = else COMMON_SH = $(abs_top_srcdir)/scripts/common/common.sh ifneq "" "$(wildcard $(PTB_ROOT))" PLATFORM := $(shell . $(COMMON_SH) && COMMON_DetectPlatform) RELEASE_PTB = $(PTB_ROOT)/$(PLATFORM)/project_tree_builder.RELEASE endif endif PTB_CANDIDATES = $(PREBUILT_PTB_EXE) $(RELEASE_PTB) $(BOOTSTRAP_PTB) PTB := $(word 1, $(wildcard $(PTB_CANDIDATES))) endif ### Tests config variables check_run = $(abs_top_srcdir)/scripts/common/check/check_run.sh check_add = $(abs_top_srcdir)/scripts/common/check/check_add.sh proj_count := $(words $(wildcard $(srcdir)/Makefile.*.???)) ifeq "1:" "$(NCBI_USING_FLAT_MAKEFILE):$(filter 0 1,$(proj_count))" MAKE_LOCK_MAP = @cd $(abs_srcdir) && $(RWL) \ $(top_srcdir)/scripts/common/impl/make_lock_map.sh \ -bd $(builddir) -sd $(rel_srcdir:src/%=%) w_lock_map = -map $(srcdir)/.\#lock-map endif ifneq "" "$(filter 3.7%,$(MAKE_VERSION))" # Work around extra expansion of $(call ...) arguments prior to version 3.80. # i's expansion sports braces for compatibility with out-of-tree metamakefiles # that delegate to Makefile.$${i}_???; x's lacks them to avoid breaking # $$x_mfile. i = $${i} x = $$x endif but_exp = ' (but expendable)' make_tag = $(word 1,$(MAKE))$(patsubst %,[%],$(filter-out 0,$(MAKELEVEL))) ifneq "" "$(findstring k,$(MFLAGS))" ign = - endif ifeq "" "$(findstring s,$(MFLAGS))" echo_unless_silent = echo else echo_unless_silent = : endif # 1: proj_name, 2: lock_map?, 3: command, 4: target, 5: ext, 6: cleanup, # 7: error_status, 8: is_expendable? define do_make_one_leaf_proj NCBICXX_TESTING_REQS=1 $(3) -q requirements REQUIRES= && \ $(if $(8),NCBI_BUT_EXPENDABLE=$(but_exp);,) \ if NCBICXX_TESTING_REQS=1 $(3) -q requirements; then \ if $(3) -q depend >/dev/null 2>&1 && $(3) -q $(4) >/dev/null 2>&1; then \ $(echo_unless_silent) "$(make_tag) (Makefile.$(1)$(5)): Nothing to be done for \`$(4)'."; \ elif $(echo_unless_silent) $(3) $(4) && \ $(RWL) -base "make_$(1)" -log "make_$(1).log" $(2) \ ! $(RUN_WITH_CD_REPORTER) $(3) $(4) ; then \ echo "FAILED$$NCBI_BUT_EXPENDABLE: $(rel_srcdir)/Makefile.$(1)$(5)" ; \ $(6) ; \ exit $(7) ; \ fi ; \ else \ echo "NOTE: skipping project \"$(1)\" due to unmet requirements"; \ [ "$(5)" = .app ] || $(3) mark-as-disabled || true ; \ fi endef # 1: proj_name, 2: target, 3: ext define warn_one_leaf_proj $(if $(filter-out export-headers,$(2)),/bin/echo Warning: non-existent $(3:.%=%) project '"$(1)"') endef # 1: proj_name, 2: lock_map?, 3: command, 4: target, 5: ext, 6: cleanup, # 7: error_status, 8: is_expendable? define make_one_leaf_proj $(if $(wildcard $(srcdir)/Makefile.$(1)$(5) Makefile.$(1)$(5)),$(call do_make_one_leaf_proj,$(1),$(2),$(3),$(4),$(5),$(6),$(7),$(8)),$(call warn_one_leaf_proj,$(1),$(4),$(5))) endef # The blank line before endef keeps foreach from running commands together. MAKE_USR = $(MAKE) -f "$$x_mfile" builddir="$(builddir)" \ srcdir="$(abs_srcdir)" $(MFLAGS_NR) ANY_USR_PROJ = $(USR_PROJ)$(XUNIX_USR_PROJ)$(EXPENDABLE_USR_PROJ) ANY_UNIX_PROJ = $(UNIX_PROJ)$(EXPENDABLE_UNIX_PROJ) ifneq "$(ANY_USR_PROJ)$(ANY_UNIX_PROJ)" "" ALL_USR_PROJ=$(filter-out $(UNIX_PROJ),$(USR_PROJ) $(XUNIX_USR_PROJ)) \ $(UNIX_PROJ) ALL_XUSR_PROJ=$(filter-out $(EXPENDABLE_UNIX_PROJ),$(EXPENDABLE_USR_PROJ)) \ $(EXPENDABLE_UNIX_PROJ) # 1: proj_name, 2: target, 3: is_expendable define make_one_usr_proj +@x_mfile=$(if $(wildcard Makefile.$(1)),,$(srcdir)/)Makefile.$(1) ; \ $(call make_one_leaf_proj,$(1),,$(MAKE_USR),$(2),,:,1,$(3)) endef # 1: target define make_each_usr_proj +@test -f requirements || $(TOUCH) -t 197607040000 requirements $(foreach p,$(ALL_USR_PROJ),$(ign)$(call make_one_usr_proj,$(p),$(1),)) $(foreach p,$(ALL_XUSR_PROJ),-$(call make_one_usr_proj,$(p),$(1),1)) +@test -s requirements || $(RM) -f requirements endef endif SPEC_TYPES = ASN DTD XSD WSDL JSD PROTOBUF MAKE_ASN = $(builddir)/new_module.sh "$$i" MAKE_DTD = $(builddir)/new_module.sh --dtd "$$i" MAKE_XSD = $(builddir)/new_module.sh --xsd "$$i" MAKE_WSDL = $(builddir)/new_module.sh --wsdl "$$i" MAKE_JSD = $(builddir)/new_module.sh --jsd "$$i" MAKE_PROTOBUF = $(builddir)/new_module.sh --protobuf "$$i" # 1: proj_name, 2: proj_type, 3: target define make_one_spec_proj $(ign)+@i=$(1) ; \ $(echo_unless_silent) "cd $(abs_srcdir) && $(MAKE_$(2)) $(3)" ; \ cd $(abs_srcdir) && \ if MAKE="$(MAKE) $(MFLAGS_NR)" \ $(RWL) -base make_asn -log "$(CURDIR)/make_$(1)_src.log" $(MAKE_$(2)) $(3) \ && $(MAKE_LIB) src-stamp; then \ : ; \ else \ echo "FAILED$$NCBI_BUT_EXPENDABLE: $(rel_srcdir)/Makefile.$$i.lib" ; \ exit 6 ; \ fi endef # 1: proj_type, 2: target define make_spec_type $(foreach p,$($(1)_PROJ),$(call make_one_spec_proj,$(p),$(1),$(2))) endef # 1: target define make_each_spec $(foreach t,$(SPEC_TYPES),$(call make_spec_type,$(t),$(1))) endef ### The i shell variable is a legacy of the previous approach, ### retained for compatibility with new_project and import_project. MAKE_LIB = $(MAKE) -f "$(builddir)/Makefile.lib.tmpl" srcdir="$(srcdir)" \ TMPL="$$i" $(MFLAGS_NR) ifeq "" "$(filter $(LIB_PROJ),$(foreach t,$(SPEC_TYPES),$($(t)_PROJ)))" LIB_TYPES = $(SPEC_TYPES) LIB else LIB_TYPES = LIB endif # 1: proj_name, 2: command, 3: target, 4: ext, 5: cleanup_target, # 6: error_status, 7: is_expendable? define make_one_cxx_proj +@i=$(1) ; \ $(call make_one_leaf_proj,$(1),$(w_lock_map),$(2),$(3),$(4),$(2) $(5),$(6),$(7)) endef # 1: proj_name, 2: target, 3: is_expendable define make_one_lib_proj $(call make_one_cxx_proj,$(1),$(MAKE_LIB),$(2),.lib,$(deactivate),2,$(3)) endef # 1: proj_type, 2: target, 3: is_expendable?, 4: ignore errors? define make_lib_proj_type $(foreach p,$($(1)_PROJ),$(4)$(call make_one_lib_proj,$(p),$(2),$(3))) endef # 1: target define make_each_lib_proj $(foreach t,$(LIB_TYPES),$(ign)$(call make_lib_proj_type,$(t),$(1),,$(ign))) $(call make_lib_proj_type,EXPENDABLE_LIB,$(1),1,-) endef MAKE_APP = $(MAKE) -f "$(builddir)/Makefile.app.tmpl" srcdir="$(srcdir)" \ TMPL="$$i" $(APP_NOCOPY) $(MFLAGS_NR) # 1: proj_name, 2: target, 3: is_expendable define make_one_app_proj $(call make_one_cxx_proj,$(1),$(MAKE_APP),$(2),.app,unlink,2,$(3)) endef # 1: target define make_each_app_proj $(foreach p,$(APP_PROJ),$(ign)$(call make_one_app_proj,$(p),$(1),)) $(foreach p,$(EXPENDABLE_APP_PROJ),-$(call make_one_app_proj,$(p),$(1),1)) endef MAKE_METAL = $(MAKE) -f "$(builddir)/Makefile.metal.tmpl" srcdir="$(srcdir)" \ TMPL="$$i" $(APP_NOCOPY) $(MFLAGS_NR) # 1: proj_name, 2: target, 3: is_expendable define make_one_metal_proj $(call make_one_cxx_proj,$(1),$(MAKE_METAL),$(2),.metal,unlink,2,$(3)) endef # 1: target define make_each_metal_proj $(foreach p,$(METAL_PROJ),$(ign)$(call make_one_metal_proj,$(p),$(1),)) endef ifneq "$(wildcard $(check_run))" "" # 1: target define make_check +@$(RWL) -base check $(check_run) $(signature) $(builddir) $(abs_top_srcdir) \ $(MAKE) $(MFLAGS_NR) IS_CHECK=Y $(1) || exit 7 endef endif # 1: proj_name define add_one_check @i=$(1) ; \ NCBICXX_TESTING_REQS=1 $(MAKE_APP) -q requirements REQUIRES= && \ if NCBICXX_TESTING_REQS=1 $(MAKE_APP) -q requirements >/dev/null 2>&1; then \ $(check_add) $(abs_srcdir) $(1) $(signature) $(subdir) || exit 5 ; \ else \ echo SKIP -- $(rel_srcdir:src/%=%)/$(1) \(unmet build REQUIRES\) ; \ fi endef # 1: proj_name define warn_one_check @/bin/echo SKIP -- $(rel_srcdir:src/%=%)/$(1) \(makefile absent\) endef define add_each_check $(foreach p,$(APP_PROJ) $(EXPENDABLE_APP_PROJ),$(if $(wildcard $(srcdir)/Makefile.$(p).app),$(call add_one_check,$(p)),$(call warn_one_check,$(p)))) endef generic_targets = libs mark-as-disabled clean purge check_add depend base_targets = all check $(generic_targets) local_targets = $(base_targets:%=%_l) sources_l $(local_targets): %: %.needs-reqs $(base_targets) sources: %: %_l ; has_usr = all_l sources_l clean_l purge_l has_usr_l_real = $(has_usr:%=%.real) has_usr_real = $(has_usr:%_l=%.real) has_usr_nonusr = $(has_usr:%_l=%.nonusr) has_usr_usr = $(has_usr:%_l=%.usr) clean_sources.usr purge_sources.usr has_usr_locked = $(has_usr:%_l=%.usr.locked) ifeq ":" "$(NCBI_USING_FLAT_MAKEFILE):$(filter 0 1,$(proj_count))" $(has_usr_l_real): %_l.real: @$(RWL) -base make__$(notdir $(CURDIR))_common \ $(MAKE) $(MFLAGS_NR) $*.nonusr else $(has_usr_l_real): %_l.real: %.nonusr ; endif $(has_usr_real): %.real: %_l.real ; $(has_usr_locked) $(has_usr_nonusr): configurables ifeq "$(sources:%=$(ANY_USR_PROJ)$(ANY_UNIX_PROJ))" "" $(has_usr_usr): ; else all.usr: sources.usr ; sources.usr: @-$(RM) -f .built .built_r @-echo "`$(DATE)`: starting to build in $(CURDIR)" > .building $(call make_each_usr_proj,all) @-$(RM) -f .building @-echo "`$(DATE)`: local build succeeded in $(CURDIR)" > .built clean.usr purge.usr: %.usr: @-$(RM) -f .building .built .built_r $(call make_each_usr_proj,$*) %_sources.usr: ign = - clean_sources.usr purge_sources.usr: %.usr: $(call make_each_usr_proj,$*) all.usr.locked: sources.usr.locked ; $(filter-out all.usr.locked,$(has_usr_locked)): %.usr.locked: @$(RWL) -base make_user_projects $(MAKE) $(MFLAGS_NR) $*.usr $(has_usr_nonusr): %.nonusr: %.usr.locked endif sources.nonusr: $(call make_each_spec,all) $(call make_each_lib_proj,export-headers) $(call make_each_lib_proj,flag-stamps) $(call make_each_app_proj,flag-stamps) $(MAKE_LOCK_MAP) all.nonusr: $(sources:%=%.nonusr) # $(wildcard Makefile.*.libdep) @-$(RM) -f .built .built_r @-echo "`$(DATE)`: starting to build in $(CURDIR)" > .building $(call make_each_lib_proj,all) $(call make_each_app_proj,all) ifeq "$(OSTYPE)" "darwin" $(call make_each_metal_proj,all) endif @-$(RM) -f .building @-echo "`$(DATE)`: local build succeeded in $(CURDIR)" > .built clean.nonusr purge.nonusr: %.nonusr: # %_sources $(call make_each_lib_proj,$*) $(call make_each_app_proj,$*) ifeq "$(OSTYPE)" "darwin" $(call make_each_metal_proj,$*) endif clean_sources purge_sources: %: %.usr $(call make_each_spec,$@) libs_l.real: $(sources) # $(wildcard Makefile.*.libdep) $(call make_each_lib_proj,all) mark-as-disabled%: ign = - mark-as-disabled_l.needs-reqs: mark-as-disabled_l.real ; mark-as-disabled_l.real: $(call make_each_lib_proj,mark-as-disabled) check_l.real: $(call make_check,check_add_l) check_add_l.real: $(add_each_check) depend_l.real: $(sources) $(call make_each_lib_proj,depend) $(call make_each_app_proj,depend) Makefile.%.libdep: $(srcdir)/Makefile.% # $(builddir)/Makefile.mk ifneq "$(srcdir)" "." cd $(builddir) && $(RWL) -base project_tree_builder \ $(abs_top_srcdir)/scripts/common/impl/create_flat_makefile.sh \ $(build_root) -s $(abs_top_srcdir) $(PROJECTS_:%=-p %) else ifneq "$(PTB)" "" cd $(import_root) && $(RWL) -base project_tree_builder \ $(PTB) -ext -extroot $(builddir) -nws \ -logfile Flat.full.configuration_log -conffile \ $(abs_top_srcdir)/src/build-system/project_tree_builder.ini \ -noadddep `cd .. && pwd` src Makefile.flat.full else @echo Not sure how to update $@ from $<. @exit 10 endif endif @if [ -f "$@" ]; then touch $@; fi base_req_needers = $(filter-out mark-as-disabled_l,$(local_targets)) .PHONY: $(base_targets) $(has_usr_nonusr) $(has_usr_usr) .PHONY: $(has_usr_locked) $(has_usr_l_real) $(has_usr_real) .PHONY: sources clean_sources purge_sources .PHONY: libs_l.real mark-as-disabled_l.real check_l.real check_add_l.real .PHONY: depend_l.real