Makefile: create and apply patches to generated sources

In order to enable changing the generated C configuration files manually,
this patch introduces the target `diffconfig` to the build system.

After generating the configuration files, a developer can manually modify
these sources (which are placed under build/configs) and invoke `make
diffconfig` to generate a patch that shows the made differences. Such
patches can be registered to a build by invoking the `applydiffconfig`
target. The build system will always apply them whenever the configuration
files are regenerated.

A typical workflow to create a patch is as follows.

    # The pre_build target relies on generated configuration files
    hypervisor$ make BOARD=xxx SCENARIO=yyy pre_build

    (manually edit files under build/configs/boards and
      build/configs/scenarios)

    hypervisor$ make diffconfig   # Patch generated to build/config.patch
    hypervisor$ cp build/config.patch /path/to/patch

The following steps apply apply the patch to another build.

    hypervisor$ make BOARD=xxx SCENARIO=yyy defconfig
    hypervisor$ make applydiffconfig PATCH=/path/to/patch-file-or-directory
    hypervisor$ make

After any patch is registered for a build, the configuration files will be
automatically regenerated the next time `make` is invoked.

To show a list of registered patches for generated configuration files,
invoke `make applydiffconfig` without specifying `PATCH`.

v2:
 * Add target `applydiffconfig` which accepts a PATCH variable to register
   an arbitrary patch file or a directory containing patch file(s) for a
   build. `.config_patches` is no longer used.

Tracked-On: #5644
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Junjie Mao 2021-01-06 12:10:12 +08:00 committed by wenlingz
parent 866c0881a3
commit 775214b710
2 changed files with 64 additions and 1 deletions

View File

@ -7,7 +7,17 @@ board_xml=$2
scenario_xml=$3
out=$4
apply_patch () {
echo "Applying patch ${1}:"
patch -p1 < ${1}
if [ $? -ne 0 ]; then
echo "Applying patch ${1} failed."
exit 1
fi
}
tool_dir=${base_dir}/../misc/acrn-config
diffconfig_list=${out}/.diffconfig
python3 ${tool_dir}/board_config/board_cfg_gen.py --board ${board_xml} --scenario ${scenario_xml} --out ${out} &&
python3 ${tool_dir}/scenario_config/scenario_cfg_gen.py --board ${board_xml} --scenario ${scenario_xml} --out ${out}
@ -15,3 +25,19 @@ python3 ${tool_dir}/scenario_config/scenario_cfg_gen.py --board ${board_xml} --s
if [ $? -ne 0 ]; then
exit $?
fi
if [ -f ${diffconfig_list} ]; then
cd ${out} &&
cat ${diffconfig_list} | while read line; do
if [ -f ${line} ]; then
apply_patch ${line}
elif [ -d ${line} ]; then
find ${line} -maxdepth 1 -name '*.patch' | while read f; do
apply_patch ${f}
done
else
echo "${line}: No such file or directory"
exit 1
fi
done
fi

View File

@ -125,6 +125,11 @@ HV_UNIFIED_XML := $(HV_CONFIG_DIR)/unified.xml
HV_CONFIG_H := $(HV_OBJDIR)/include/config.h
HV_CONFIG_MK := $(HV_CONFIG_DIR)/config.mk
HV_CONFIG_TIMESTAMP := $(HV_CONFIG_DIR)/.timestamp
HV_DIFFCONFIG_LIST := $(HV_CONFIG_DIR)/.diffconfig
HV_CONFIG_A_DIR := $(HV_OBJDIR)/a # Directory containing generated configuration sources for diffconfig
HV_CONFIG_B_DIR := $(HV_OBJDIR)/b # Directory containing edited configuration sources for diffconfig
HV_CONFIG_DIFF := $(HV_OBJDIR)/config.patch # Patch encoding differences between generated and edited config. sources
# Backward-compatibility for RELEASE=(0|1)
ifdef RELEASE
@ -226,7 +231,7 @@ $(HV_CONFIG_H): $(HV_UNIFIED_XML)
@xsltproc -o $@ --xinclude --xincludestyle $(HV_CONFIG_XFORM_DIR)/config.h.xsl $<
@echo "$@ generated"
$(HV_CONFIG_TIMESTAMP): $(HV_UNIFIED_XML) | $(HV_CONFIG_DIR)
$(HV_CONFIG_TIMESTAMP): $(HV_UNIFIED_XML) ${HV_DIFFCONFIG_LIST} | $(HV_CONFIG_DIR)
@sh $(BASEDIR)/scripts/genconf.sh $(BASEDIR) $(HV_BOARD_XML) $(HV_SCENARIO_XML) $(HV_CONFIG_DIR)
@touch $@
@ -240,6 +245,38 @@ showconfig:
@echo "- SCENARIO = $(SCENARIO)"
@echo "- RELEASE = $(RELEASE)"
diffconfig:
@rm -rf $(HV_CONFIG_A_DIR) $(HV_CONFIG_B_DIR)
@sh $(BASEDIR)/scripts/genconf.sh $(BASEDIR) $(BOARD_FILE) $(HV_CONFIG_XML) $(HV_CONFIG_A_DIR)
@cd $(HV_CONFIG_DIR) && find . -name '*.c' -or -name '*.h' -or -name '*.config' | while read f; do \
nf=$(HV_CONFIG_B_DIR)/$${f}; mkdir -p `dirname $${nf}` && cp $${f} $${nf}; \
done
@cd $(HV_OBJDIR) && git diff --no-index --no-prefix a/ b/ > $(HV_CONFIG_DIFF) || true
@echo "Diff on generated configuration files is available at $(HV_CONFIG_DIFF)."
@echo "To make a patch effective, use `applydiffconfig PATCH=/path/to/patch` to register it to a build."
applydiffconfig:
ifdef PATCH
ifneq ($(realpath $(PATCH)),)
@echo $(realpath $(PATCH)) >> ${HV_DIFFCONFIG_LIST}
@echo "${PATCH} is registered for build directory ${HV_OBJDIR}."
@echo "Registered patches will be applied the next time 'make' is invoked."
@echo "To unregister a patch, remove it from ${HV_DIFFCONFIG_LIST}."
else
@echo "${PATCH}: No such file or directory"
endif
else
@echo "No patch file or directory is specified"
@echo "Try 'make applydiffconfig PATCH=/path/to/patch' to register patches for generated configuration files."
ifneq ($(realpath $(HV_DIFFCONFIG_LIST)),)
@echo "Registers patches:"
@cat $(HV_DIFFCONFIG_LIST)
endif
endif
$(HV_DIFFCONFIG_LIST):
@touch $@
menuconfig:
@echo "To tweak the configurations, run $(HV_CONFIG_TOOL_DIR)/config_app/app.py using python3 and load $(HV_SCENARIO_XML) in the web browser."