You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

407 lines
20 KiB

#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This file is part of dobuild.
# Copyright (c) 2019 Contributors as noted in the AUTHORS file.
#
# SPDX-License-Identifier: MPL-2.0
current_makefile := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
# Guard from user inclusion
ifndef standardrules_include_guard
$(error $(current_makefile) is not intended to be included directly - include standardrules.mk instead)
endif
ifndef generic_include_guard
generic_include_guard := 1
ifndef defaults_include_guard
include $(patsubst %/,%,$(dir $(current_makefile)))/defaults.mk
endif
#######################################################################################################################
# Overridable generic defaults
DOBUILD_GENERIC_ADAPTER ?= generic
#######################################################################################################################
# Overridable generic macros, hooks to customize target default values
# hook called to retrieve the target generic extension directory, may return an empty value
# $(call dobuild_generic_extdir,target-name)
dobuild_generic_extdir ?=
# hook called to retrieve the target generic adapter name, may return an empty value
# $(call dobuild_generic_adapter,target-name)
dobuild_generic_adapter ?=
# hook called to retrieve the target generic prerequisites, may return an empty list in which case the default generic
# prerequisites are used
# $(call dobuild_generic_prerequisites,target-name)
dobuild_generic_prerequisites ?=
# hook called to retrieve the target generic order only prerequisites, may return an empty list in which case the
# default generic order only prerequisites are used
# $(call dobuild_generic_orderonly_prerequisites,target-name)
dobuild_generic_orderonly_prerequisites ?=
# hook called to retrieve the target generic perpare step, may return an empty value
# $(call dobuild_generic_prepare,target-name)
dobuild_generic_prepare ?= prepare
# hook called to retrieve the target generic assemble step
# $(call dobuild_generic_assemble,target-name)
dobuild_generic_assemble ?= assemble
# hook called to retrieve the target generic save artifacts step, may return an empty value
# $(call dobuild_generic_saveartifacts,target-name)
dobuild_generic_saveartifacts ?= save-artifacts
# hook called to retrieve the target generic lint step, may return an empty value
# $(call dobuild_generic_lint,target-name)
dobuild_generic_lint ?= lint
# hook called to retrieve the target generic check step, may return an empty value
# $(call dobuild_generic_check,target-name)
dobuild_generic_check ?= check
# hook called to retrieve the target generic memcheck step, may return an empty value
# $(call dobuild_generic_memcheck,target-name)
dobuild_generic_memcheck ?= check-memcheck
# hook called to retrieve the target generic package step, may return an empty value
# $(call dobuild_generic_package,target-name)
dobuild_generic_package ?= package
# hook called to retrieve the target generic install step, may return an empty value
# $(call dobuild_generic_install,target-name)
dobuild_generic_install ?= package-install
# hook called to retrieve the target generic delegate step
# $(call dobuild_generic_delegate,target-name)
dobuild_generic_delegate ?= delegate
# hook called to retrieve the target generic build testing option,
# may return an empty value in which case BUILD_TESTING is used
# $(call dobuild_generic_buildtesting,target-name)
dobuild_generic_buildtesting ?=
#######################################################################################################################
# Generic macros
# replaces template values of target field with target properties and resolves result against extension search
# directories, returning the first existing resolved path
# $(call generic_resolve_ext,target-name,field)
generic_resolve_ext = $(firstword $(call target_subst_and_resolve,$1,$2,$(cache.$1.ext_search_paths)))
# retrieves the target generic default prerequisites
# $(call generic_default_prerequisites,target-name)
generic_default_prerequisites = \
$(call image_buildtarget,$1) \
$(OUTDIR)/$1/DoBuildFiles/generic.properties
# retrieves the target generic default extension directory
# $(call generic_default_extdir,target-name)
generic_default_extdir = $(addprefix $(addsuffix /,$(EXTDIR)),$(cache.$1.adapter))
# creates a generic run rule command
# $(call generic_run_cmd,target-name,command[,args],alternative-command[,output-command])
generic_run_cmd = $(call run_cmd,$1,$(or $(strip $(notdir $(wildcard $2))),$(strip $4)),$3,$5)
# create a generic perpare command
# $(call generic_prepare_cmd,target-name)
generic_prepare_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_prepare),,true,prepare)
# create a generic assemble command
# $(call generic_assemble_cmd,target-name)
generic_assemble_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_assemble),,$(call dobuild_generic_assemble,$1),assemble)
# create a generic save artifacts command
# $(call generic_saveartifacts_cmd,target-name)
generic_saveartifacts_cmd = { $(call generic_run_cmd,$1,$(cache.$1.generic_saveartifacts),,tar -cf - -T /dev/null,save-artifacts) | tar xvf - -C '$(OUTDIR)/$1/DoBuildFiles'; }
# create a generic lint command
# $(call generic_lint_cmd,target-name)
generic_lint_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_lint),,true,lint)
# create a generic check command
# $(call generic_check_cmd,target-name)
generic_check_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_check),,true,check)
# create a generic memcheck command
# $(call generic_memcheck_cmd,target-name)
generic_memcheck_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_memcheck),,true,memcheck)
# create a generic package command
# $(call generic_package_cmd,target-name)
generic_package_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_package),,true,package)
# create a generic install command
# $(call generic_install_cmd,target-name)
generic_install_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_install),$(generic_destdir),true,install)
# create a generic clean command
# $(call generic_clean_cmd,target-name)
generic_clean_cmd = rm -rf '$(OUTDIR)/$1'
# create a generic delegate command
# $(call generic_delegate_cmd,target-name,delegate-target-name)
generic_delegate_cmd = $(call generic_run_cmd,$1,$(cache.$1.generic_delegate),$2,$(call dobuild_generic_delegate,$1),delegate)
# creates a generic properties generation cmd
# $(call generic_props_cmd,target-name,input-file)
generic_props_cmd = sed \
-e 's!%TARGET%!$(call escape,$1,!)!g' \
-e 's!%DOBUILDDIR%!$(call escape,$(generic_dobuilddir),!)!g' \
-e 's!%PROJECTDIR%!$(call escape,$(generic_projectdir),!)!g' \
-e 's!%HOSTMARCH%!$(call escape,$(call target_host_arch,$1),!)!g' \
-e 's!%MARCH%!$(call escape,$(call target_arch_sub,$1),!)!g' \
-e 's!%DISTRIB%!$(call escape,$(call target_distrib,$1),!)!g' \
-e 's!%DISTRIB_ID%!$(call escape,$(call target_distrib_id,$1),!)!g' \
-e 's!%DISTRIB_VERSION%!$(call escape,$(call target_distrib_version,$1),!)!g' \
-e 's!%SYS%!$(call escape,$(call target_sys,$1),!)!g' \
-e 's!%ABI%!$(call escape,$(call target_abi,$1),!)!g' \
-e 's!%ID%!$(call escape,$(call target_id,$1),!)!g' \
-e 's!%VARIANT%!$(call escape,$(call target_variant,$1),!)!g' \
-e 's!%BUILD_TESTING%!$(call escape,$(cache.$1.generic_buildtesting),!)!g' \
$2
# creates a generic properties generation rule
# $(call generic_props_rule,target-name)
generic_props_rule = \
$$(OUTDIR)/$1/DoBuildFiles/generic.properties: $$(DOBUILDDIR)/assets/templates/properties.template $$(MAKEFILE_LIST); \
$$(SILENT)mkdir -p $$(dir $$@); $$(call generic_props_cmd,$1,$$<) > $$@
# creates a generic prepare rule
# $(call generic_prepare_rule,target-name)
generic_prepare_rule = \
$$(OUTDIR)/$1/DoBuildFiles/prepare.stage: $$(cache.$1.generic_prepare) $$(cache.$1.generic_prerequisites) | $$(cache.$1.generic_orderonly_prerequisites); \
$$(SILENT)$$(call generic_prepare_cmd,$1) && touch $$@
# creates a generic assemble rule
# $(call generic_assemble_rule,target-name)
generic_assemble_rule = \
build/$1 $$(OUTDIR)/$1/DoBuildFiles/assemble.stage: $$(cache.$1.generic_assemble) $$(OUTDIR)/$1/DoBuildFiles/prepare.stage | $$(OUTDIR)/$1/DoBuildFiles/save-artifacts.stage; \
$$(SILENT)$$(call generic_assemble_cmd,$1) && touch $$(OUTDIR)/$1/DoBuildFiles/assemble.stage
# creates a generic save artifacts rule
# $(call generic_saveartifacts_rule,target-name)
generic_saveartifacts_rule = \
$$(OUTDIR)/$1/DoBuildFiles/save-artifacts.stage: $$(cache.$1.generic_saveartifacts) $$(OUTDIR)/$1/DoBuildFiles/prepare.stage; \
$$(SILENT)$$(call generic_saveartifacts_cmd,$1) && touch $$@
# creates a generic lint rule
# $(call generic_lint_rule,target-name)
generic_lint_rule = \
lint/$1 $$(OUTDIR)/$1/DoBuildFiles/lint.stage: $$(cache.$1.generic_lint) $$(OUTDIR)/$1/DoBuildFiles/assemble.stage; \
$$(SILENT)$$(call generic_lint_cmd,$1) && touch $$(OUTDIR)/$1/DoBuildFiles/lint.stage
# creates a generic check rule
# $(call generic_check_rule,target-name)
generic_check_rule = \
check/$1 $$(OUTDIR)/$1/DoBuildFiles/check.stage: $$(cache.$1.generic_check) $$(OUTDIR)/$1/DoBuildFiles/assemble.stage; \
$$(SILENT)$$(call generic_check_cmd,$1) && touch $$(OUTDIR)/$1/DoBuildFiles/check.stage
# creates a generic memcheck rule
# $(call generic_memcheck_rule,target-name)
generic_memcheck_rule = \
memcheck/$1 $$(OUTDIR)/$1/DoBuildFiles/memcheck.stage: $$(cache.$1.generic_memcheck) $$(OUTDIR)/$1/DoBuildFiles/assemble.stage; \
$$(SILENT)$$(call generic_memcheck_cmd,$1) && touch $$(OUTDIR)/$1/DoBuildFiles/memcheck.stage
# creates a generic package rule
# $(call generic_package_rule,target-name)
generic_package_rule = \
package/$1 $$(OUTDIR)/$1/DoBuildFiles/package.stage: $$(cache.$1.generic_package) $$(OUTDIR)/$1/DoBuildFiles/assemble.stage; \
$$(SILENT)$$(call generic_package_cmd,$1) && touch $$(OUTDIR)/$1/DoBuildFiles/package.stage
# creates a generic install rule
# $(call generic_install_rule,target-name)
generic_install_rule = \
install/$1: $$(wildcard $$(cache.$1.generic_install)) $$(OUTDIR)/$1/DoBuildFiles/assemble.stage; \
$$(SILENT)$$(call generic_install_cmd,$1)
# creates a generic clean rule
# $(call generic_clean_rule,target-name)
generic_clean_rule = \
clean/$1: ; \
$$(SILENT)-$$(call generic_clean_cmd,$1)
# creates a generic delegate rule
# $(call generic_delegate_rule,adapter,target-name,delegate-target-name)
generic_delegate_rule = \
$1/$2/$3: $$(OUTDIR)/$2/DoBuildFiles/prepare.stage; \
$$(SILENT)$$(call generic_delegate_cmd,$2,$3)
# creates a generic delegate pattern rule
# $(call generic_delegate_pattern_rule,adapter,target-name)
generic_delegate_pattern_rule = \
$1/$2/%: $$(OUTDIR)/$2/DoBuildFiles/prepare.stage; \
$$(SILENT)$$(call generic_delegate_cmd,$2,$$*)
# creates a generic delegate makefile generation command, assuming target is the makefile to create and
# first prerequisite a file containing the delegate target names
# $(call generic_delegate_makefile_rule_cmd,target-name)
generic_delegate_makefile_rule_cmd = \
{ \
echo '$(\\\#) generated file - do not edit!!!'; \
echo; \
ID='$(call id,$@)'; \
echo "ifndef $${ID}_include_guard"; \
echo "$${ID}_include_guard := 1"; \
echo; \
$(foreach target,$(shell cat '$<' 2>/dev/null),\
echo '$(call generic_delegate_rule,$$(cache.$1.adapter),$1,$(target))'; \
echo; \
) \
echo 'endif'; \
echo; \
} > $@
# creates a generic delegate makefile generation rule
# $(call generic_delegate_makefile_rule,target-name)
generic_delegate_makefile_rule = \
$$(OUTDIR)/$1/DoBuildFiles/generic_delegaterules.mk: $$(wildcard $$(OUTDIR)/$1/DoBuildFiles/targets.txt) | $$(OUTDIR)/$1/DoBuildFiles; \
$$(SILENT)$$(call generic_delegate_makefile_rule_cmd,$1)
#######################################################################################################################
# Generic rule target configuration
GENERIC_ADAPTER = $(call memorize,GENERIC_ADAPTER,$(DOBUILD_GENERIC_ADAPTER))
generic_projectdir = $(or $(container_projectdir),$(PROJECTDIR))
generic_dobuilddir = $(or $(container_dobuilddir),$(DOBUILDIR))
generic_destdir = $(or $(container_destdir),$(DESTDIR))
generic_defaulttarget = $(if $(SKIP_DEFAULTTARGET),,$(DEFAULTTARGET))
generic_targets = $(filter $(generic_defaulttarget),$(GENERIC_TARGETS))
generic_selected_targets = $(if $(SKIP_DEFAULTTARGET),$(GENERIC_TARGETS),$(generic_targets))
generic_active_targets = $(call memorize,generic_active_targets,$(call target_filter,$(FILTER),$(generic_selected_targets),$(EXCLUDEFILTER)))
generic_prepare_targets = $(addsuffix /DoBuildFiles/prepare.stage,$(addprefix $(OUTDIR)/,$(generic_active_targets)))
generic_build_targets = $(addprefix build/,$(generic_active_targets))
generic_clean_targets = $(addprefix clean/,$(generic_active_targets))
generic_check_targets = $(addprefix check/,$(generic_active_targets))
generic_memcheck_targets = $(addprefix memcheck/,$(call target_filter,$(MEMCHECKFILTER),$(generic_active_targets),))
generic_lint_targets = $(addprefix lint/,$(generic_active_targets))
generic_dist_targets = $(addprefix package/,$(generic_active_targets))
generic_install_targets = $(addprefix install/,$(generic_active_targets))
generic_rule_targets = $(addsuffix /genericrules.mk,$(OUTDIR))
generic_outdirs = $(addprefix $(OUTDIR)/,$(generic_active_targets))
project_targets += $(GENERIC_TARGETS)
PREPARE_TARGETS += $(generic_prepare_targets)
BUILD_TARGETS += $(generic_build_targets)
LINT_TARGETS += $(generic_lint_targets)
CHECK_TARGETS += $(generic_check_targets)
MEMCHECK_TARGETS += $(generic_memcheck_targets)
CLEAN_TARGETS += $(generic_clean_targets)
INSTALL_TARGETS += $(generic_install_targets)
DIST_TARGETS += $(generic_dist_targets)
RULE_TARGETS += $(generic_rule_targets)
TARGETS += $(generic_active_targets)
OUTDIRS += $(generic_outdirs)
#######################################################################################################################
# Makefile dependencies
MAKEFILE_DEPS += touch
MAKEFILE_DEPS += echo
MAKEFILE_DEPS += sed
MAKEFILE_DEPS += tar
#######################################################################################################################
# Generic rules
$(generic_rule_targets):
$(SILENT) \
{ \
echo '$(\#) generated file - do not edit!!!'; \
echo; \
ID='$(call id,$@)'; \
echo "ifndef $${ID}_include_guard"; \
echo "$${ID}_include_guard := 1"; \
echo; \
$(foreach target,$(GENERIC_TARGETS),\
echo '$(\#)$(\#) BEGIN of generic $(target) configuration'; \
echo; \
echo '$(\#)$(\#)$(\#) defaults'; \
echo '$(target) ?= $$(call memorize,$(target),$(call target_properties_parse,$(target)))'; \
echo '$(target).env_path = $$(call env_default_path,$$1)'; \
echo '$(target).adapter = $$(call $$1.generic_adapter,$$1)'; \
echo '$(target).extdir = $$(call $$1.generic_extdir,$$1)'; \
echo '$(target).generic_adapter ?= $$(call dobuild_generic_adapter,$$1)'; \
echo '$(target).generic_extdir ?= $$(call dobuild_generic_extdir,$$1)'; \
echo '$(target).generic_prerequisites ?= $$(call dobuild_generic_prerequisites,$$1)'; \
echo '$(target).generic_orderonly_prerequisites ?= $$(call dobuild_generic_orderonly_prerequisites,$$1)'; \
echo '$(target).generic_prepare ?= $$(call dobuild_generic_prepare,$$1)'; \
echo '$(target).generic_assemble ?= $$(call dobuild_generic_assemble,$$1)'; \
echo '$(target).generic_saveartifacts ?= $$(call dobuild_generic_saveartifacts,$$1)'; \
echo '$(target).generic_lint ?= $$(call dobuild_generic_lint,$$1)'; \
echo '$(target).generic_check ?= $$(call dobuild_generic_check,$$1)'; \
echo '$(target).generic_memcheck ?= $$(call dobuild_generic_memcheck,$$1)'; \
echo '$(target).generic_package ?= $$(call dobuild_generic_package,$$1)'; \
echo '$(target).generic_install ?= $$(call dobuild_generic_install,$$1)'; \
echo '$(target).generic_delegate ?= $$(call dobuild_generic_delegate,$$1)'; \
echo '$(target).generic_buildtesting ?= $$(call dobuild_generic_buildtesting,$$1)'; \
echo; \
echo '$(\#)$(\#)$(\#) cached values'; \
echo 'cache.$(target).ext_search_paths = $$(call memorize,cache.$(target).ext_search_paths,$$(call split_s,$$(call env_host_path,$(target)),:))'; \
echo 'cache.$(target).env_path = $$(call memorize,cache.$(target).env_path,$$(call $(target).env_path,$(target)))'; \
echo 'cache.$(target).adapter = $$(call memorize,cache.$(target).adapter,$$(call target_get_and_subst,$(target),adapter,$(GENERIC_ADAPTER)))'; \
echo 'cache.$(target).extdir = $$(call memorize,cache.$(target).extdir,$$(call target_get_and_subst,$(target),extdir,$$(call generic_default_extdir,$(target))))'; \
echo 'cache.$(target).generic_prerequisites = $$(call memorize,cache.$(target).generic_prerequisites,$$(call target_get_and_subst,$(target),generic_prerequisites,) $$(call generic_default_prerequisites,$(target)))'; \
echo 'cache.$(target).generic_orderonly_prerequisites = $$(call memorize,cache.$(target).generic_orderonly_prerequisites,$$(call target_get_and_subst,$(target),generic_orderonly_prerequisites,))'; \
echo 'cache.$(target).generic_prepare = $$(call memorize,cache.$(target).generic_prepare,$$(call generic_resolve_ext,$(target),generic_prepare))'; \
echo 'cache.$(target).generic_assemble = $$(call memorize,cache.$(target).generic_assemble,$$(call generic_resolve_ext,$(target),generic_assemble))'; \
echo 'cache.$(target).generic_saveartifacts = $$(call memorize,cache.$(target).generic_saveartifacts,$$(call generic_resolve_ext,$(target),generic_saveartifacts))'; \
echo 'cache.$(target).generic_lint = $$(call memorize,cache.$(target).generic_lint,$$(call generic_resolve_ext,$(target),generic_lint))'; \
echo 'cache.$(target).generic_check = $$(call memorize,cache.$(target).generic_check,$$(call generic_resolve_ext,$(target),generic_check))'; \
echo 'cache.$(target).generic_memcheck = $$(call memorize,cache.$(target).generic_memcheck,$$(call generic_resolve_ext,$(target),generic_memcheck))'; \
echo 'cache.$(target).generic_package = $$(call memorize,cache.$(target).generic_package,$$(call generic_resolve_ext,$(target),generic_package))'; \
echo 'cache.$(target).generic_install = $$(call memorize,cache.$(target).generic_install,$$(call generic_resolve_ext,$(target),generic_install))'; \
echo 'cache.$(target).generic_delegate = $$(call memorize,cache.$(target).generic_delegate,$$(call generic_resolve_ext,$(target),generic_delegate))'; \
echo 'cache.$(target).generic_buildtesting = $$(call memorize,cache.$(target).generic_buildtesting,$$(or $$(call $(target).generic_buildtesting,$(target)),$$(BUILD_TESTING)))'; \
echo; \
echo '$(\#)$(\#)$(\#) rules'; \
echo '$(call generic_props_rule,$(target))'; \
echo; \
echo '$(call generic_prepare_rule,$(target))'; \
echo; \
echo '$(call generic_assemble_rule,$(target))'; \
echo; \
echo '$(call generic_saveartifacts_rule,$(target))'; \
echo; \
echo '$(call generic_lint_rule,$(target))'; \
echo; \
echo '$(call generic_check_rule,$(target))'; \
echo; \
echo '$(call generic_memcheck_rule,$(target))'; \
echo; \
echo '$(call generic_package_rule,$(target))'; \
echo; \
echo '$(call generic_install_rule,$(target))'; \
echo; \
echo '$(call generic_clean_rule,$(target))'; \
echo; \
echo '$(call generic_delegate_makefile_rule,$(target))'; \
echo; \
echo '$$(cache.$(target).adapter)/$(target): build/$(target)'; \
echo; \
echo '-include $$(OUTDIR)/$(target)/DoBuildFiles/generic_delegaterules.mk'; \
echo; \
echo '$(call generic_delegate_pattern_rule,$$(cache.$(target).adapter),$(target))'; \
echo; \
echo '$(\#)$(\#) END of generic $(target) configuration'; \
echo; \
) \
echo 'endif'; \
echo; \
} > $@
endif