diff --git a/.gitignore b/.gitignore index 85027773b..5ec57a167 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,3 @@ GPATH examples/*/sdkconfig examples/*/sdkconfig.old examples/*/build - -# Bootloader files -components/bootloader/src/sdkconfig.old \ No newline at end of file diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index d45cf144e..91be3a6d6 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -11,20 +11,23 @@ ifeq ("$(IS_BOOTLOADER_BUILD)","") BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) -BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader +BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin +BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig + +# Custom recursive make for bootloader sub-project +BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ + V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ + BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) -$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig - $(Q) PROJECT_PATH= \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN) +$(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig + $(Q) $(BOOTLOADER_MAKE) $@ bootloader-clean: - $(Q) PROJECT_PATH= \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V) + $(Q) $(BOOTLOADER_MAKE) app-clean config-clean + $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old clean: bootloader-clean @@ -36,14 +39,17 @@ all_binaries: $(BOOTLOADER_BIN) ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN) -# synchronise the project level config to the component's -# config -$(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig - $(Q) cp $< $@ - # bootloader-flash calls flash in the bootloader dummy project bootloader-flash: $(BOOTLOADER_BIN) - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V) + $(BOOTLOADER_MAKE) flash + +# synchronise the project level config to the bootloader's +# config +$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR) + $(Q) cp $< $@ + +$(BOOTLOADER_BUILD_DIR): + $(Q) mkdir -p $@ else CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include diff --git a/components/esp32/component.mk b/components/esp32/component.mk index b41acee60..788f88012 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -6,7 +6,7 @@ # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the esp-idf build system document if you need to do this. # --include $(PROJECT_PATH)/build/include/config/auto.conf +-include include/config/auto.conf COMPONENT_SRCDIRS := . hwcrypto @@ -44,6 +44,8 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) # saves us from having to add the target to a Makefile.projbuild $(COMPONENT_LIBRARY): esp32_out.ld +# .. is BUILD_DIR_BASE here, as component makefiles +# are evaluated with CWD=component build dir esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h $(CC) -I ../include -C -P -x c -E $< -o $@ diff --git a/make/common.mk b/make/common.mk index 14aa4074b..2b7376a4d 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,7 @@ # # (Note that we only rebuild auto.conf automatically for some targets, # see project_config.mk for details.) --include $(PROJECT_PATH)/build/include/config/auto.conf +-include $(BUILD_DIR_BASE)/include/config/auto.conf #Handling of V=1/VERBOSE=1 flag # diff --git a/make/project.mk b/make/project.mk index d91165cfd..2b2eff3f5 100644 --- a/make/project.mk +++ b/make/project.mk @@ -37,6 +37,7 @@ help: @echo "'make partition_table', etc, etc." # disable built-in make rules, makes debugging saner +MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR # Figure out PROJECT_PATH if not set @@ -50,6 +51,7 @@ endif #The directory where we put all objects/libraries/binaries. The project Makefile can #configure this if needed. BUILD_DIR_BASE ?= $(PROJECT_PATH)/build +export BUILD_DIR_BASE #Component directories. These directories are searched for components. #The project Makefile can override these component dirs, or define extra component directories. @@ -105,7 +107,7 @@ COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(ad $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS)))) #Also add project include path, for sdk includes -COMPONENT_INCLUDES += $(PROJECT_PATH)/build/include/ +COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) export COMPONENT_INCLUDES #COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected @@ -230,7 +232,7 @@ define GenerateComponentPhonyTarget # $(2) - target to generate (build, clean) .PHONY: $(notdir $(1))-$(2) $(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1)) - @+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) + $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) endef define GenerateComponentTargets diff --git a/make/project_config.mk b/make/project_config.mk index d2909bb30..7ca83ce5a 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -7,38 +7,38 @@ COMPONENT_KCONFIGS_PROJBUILD := $(foreach component,$(COMPONENT_PATHS),$(wildcar #For doing make menuconfig etc KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig -# clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules +# set SDKCONFIG to the project's sdkconfig, +# unless it's overriden (happens for bootloader) +SDKCONFIG ?= $(PROJECT_PATH)/sdkconfig + +# reset MAKEFLAGS as the menuconfig makefile uses implicit compile rules $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: - MAKEFLAGS="" \ - CC=$(HOSTCC) LD=$(HOSTLD) \ + MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) +# use a wrapper environment for where we run Kconfig tools +KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ + COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ + COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" + menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) MENUCONFIG - $(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig + $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig -ifeq ("$(wildcard $(PROJECT_PATH)/sdkconfig)","") +ifeq ("$(wildcard $(SDKCONFIG))","") #No sdkconfig found. Need to run menuconfig to make this if we need it. -$(PROJECT_PATH)/sdkconfig: menuconfig +$(SDKCONFIG): menuconfig endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) DEFCONFIG - $(Q) mkdir -p $(PROJECT_PATH)/build/include/config - $(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config + $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(PROJECT_PATH)/build/include/config/auto.conf +AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf # disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets # (and not building default target) @@ -46,19 +46,15 @@ ifneq ("$(MAKECMDGOALS)","") ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) AUTO_CONF_REGEN_TARGET := # dummy target -$(PROJECT_PATH)/build/include/config/auto.conf: +$(BUILD_DIR_BASE)/include/config/auto.conf: endif endif -$(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h: $(PROJECT_PATH)/sdkconfig $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG - $(Q) mkdir -p $(PROJECT_PATH)/build/include/config - $(Q) cd build; KCONFIG_AUTOHEADER="$(PROJECT_PATH)/build/include/sdkconfig.h" \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h + $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config + $(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig + $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) @@ -68,4 +64,4 @@ clean: config-clean config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean - $(Q) rm -rf $(PROJECT_PATH)/build/include/config $(PROJECT_PATH)/build/include/sdkconfig.h + $(Q) rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 86be1f82e..7c8cbc1f1 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -2,7 +2,7 @@ # # Test the build system for basic consistency # -# Just a bash script that tests some likely make failure scenarios in a row +# A bash script that tests some likely make failure scenarios in a row # Creates its own test build directory under TMP and cleans it up when done. # # Environment variables: @@ -11,6 +11,18 @@ # ESP_IDF_TEMPLATE_GIT - Can override git clone source for template app. Otherwise github. # NOCLEANUP - Set to '1' if you want the script to leave its temporary directory when done, for post-mortem. # +# +# Internals: +# * The tests run in sequence & the system keeps track of all failures to print at the end. +# * BUILD directory is set to default BUILD_DIR_BASE +# * The "print_status" function both prints a status line to the log and keeps track of which test is running. +# * Calling the "failure" function prints a failure message to the log and also adds to the list of failures to print at the end. +# * The function "assert_built" tests for a file relative to the BUILD directory. +# * The function "take_build_snapshot" can be paired with the functions "assert_rebuilt" and "assert_not_rebuilt" to compare file timestamps and verify if they were rebuilt or not since the snapshot was taken. +# +# To add a new test case, add it to the end of the run_tests function. Note that not all test cases do comprehensive cleanup +# (although very invasive ones like appending CRLFs to all files take a copy of the esp-idf tree), however the clean_build_dir +# function can be used to force-delete all files from the build output directory. # Set up some variables # @@ -21,110 +33,137 @@ export V=1 function run_tests() { - FAILURES= - STATUS="Starting" - print_status "Checking prerequisites" - [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2 + FAILURES= + STATUS="Starting" + print_status "Checking prerequisites" + [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2 - print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..." - git clone ${ESP_IDF_TEMPLATE_GIT} template - cd template - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." + print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..." + git clone ${ESP_IDF_TEMPLATE_GIT} template + cd template + git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - print_status "Updating template config..." - make defconfig || exit $? + print_status "Updating template config..." + make defconfig || exit $? - BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin" - APP_BINS="app-template.elf app-template.bin" + BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin" + APP_BINS="app-template.elf app-template.bin" - print_status "Initial clean build" - # if make fails here, everything fails - make || exit $? - # check all the expected build artifacts from the clean build - assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin - [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built" + print_status "Initial clean build" + # if make fails here, everything fails + make || exit $? + # check all the expected build artifacts from the clean build + assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin + [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built" - print_status "Updating component source file rebuilds component" - # touch a file & do a build - take_build_snapshot - touch ${IDF_PATH}/components/esp32/syscalls.c - make || failure "Failed to partial build" - assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o - assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin + print_status "Updating component source file rebuilds component" + # touch a file & do a build + take_build_snapshot + touch ${IDF_PATH}/components/esp32/syscalls.c + make || failure "Failed to partial build" + assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o + assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin - print_status "Bootloader source file rebuilds bootloader" - take_build_snapshot - touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c - make bootloader || failure "Failed to partial build bootloader" - assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o - assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin + print_status "Bootloader source file rebuilds bootloader" + take_build_snapshot + touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c + make bootloader || failure "Failed to partial build bootloader" + assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o + assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin - print_status "Partition CSV file rebuilds partitions" - take_build_snapshot - touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv - make partition_table - assert_rebuilt partitions_singleapp.bin - assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS} + print_status "Partition CSV file rebuilds partitions" + take_build_snapshot + touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv + make partition_table || failure "Failed to build partition table" + assert_rebuilt partitions_singleapp.bin + assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS} - print_status "Partial build doesn't compile anything by default" - take_build_snapshot - # verify no build files are refreshed by a partial make - ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@") - make - assert_not_rebuilt ${ALL_BUILD_FILES} + print_status "Partial build doesn't compile anything by default" + take_build_snapshot + # verify no build files are refreshed by a partial make + ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@") + make || failure "Partial build failed" + assert_not_rebuilt ${ALL_BUILD_FILES} - print_status "Cleaning should remove all files from build" - make clean - ALL_BUILD_FILES=$(find ${BUILD} -type f) - if [ -n "${ALL_BUILD_FILES}" ]; then - failure "Files weren't cleaned: ${ALL_BUILD_FILES}" - fi + print_status "Cleaning should remove all files from build" + make clean || failure "Failed to make clean" + ALL_BUILD_FILES=$(find ${BUILD} -type f) + if [ -n "${ALL_BUILD_FILES}" ]; then + failure "Files weren't cleaned: ${ALL_BUILD_FILES}" + fi print_status "Bootloader build shouldn't leave build output anywhere else" - rm -rf --preserve-root ${BUILD} + clean_build_dir make bootloader # find wizardry: find any file not named sdkconfig.h that # isn't in the "bootloader" or "config" directories find ${BUILD} -type d \( -name bootloader -o -name config \) -prune , -type f ! -name sdkconfig.h || failure "Bootloader built files outside the bootloader or config directories" - print_status "Can still clean build if all text files are CRLFs" - make clean - find . -exec unix2dos {} \; # CRLFify template dir - # make a copy of esp-idf and CRLFify it - CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf - mkdir -p ${CRLF_ESPIDF} - cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF} - # don't CRLFify executable files, as Linux will fail to execute them - find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \; - make IDF_PATH=${CRLF_ESPIDF} - # do the same checks we do for the clean build - assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin - [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" + print_status "Moving BUILD_DIR_BASE out of tree" + clean_build_dir + OUTOFTREE_BUILD=${TESTDIR}/alt_build + make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" + NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi + DEFAULT_BUILD_FILES=$(find ${BUILD} -mindepth 1) + if [ -n "${DEFAULT_BUILD_FILES}" ]; then + failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}" + fi - # NOTE: If adding new tests, add them above this CRLF test... + print_status "BUILD_DIR_BASE inside default build directory" + clean_build_dir + make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir" + NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi - print_status "All tests completed" - if [ -n "${FAILURES}" ]; then - echo "Some failures were detected:" - echo -e "${FAILURES}" - exit 1 - else - echo "Build tests passed." - fi + print_status "Parallel builds should work OK" + clean_build_dir + (make -j5 2>&1 | tee ${TESTDIR}/parallel_build.log) || failure "Failed to build in parallel" + if grep -q "warning: jobserver unavailable" ${TESTDIR}/parallel_build.log; then + failure "Parallel build prints 'warning: jobserver unavailable' errors" + fi + + print_status "Can still clean build if all text files are CRLFs" + make clean || failure "Unexpected failure to make clean" + find . -exec unix2dos {} \; # CRLFify template dir + # make a copy of esp-idf and CRLFify it + CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf + mkdir -p ${CRLF_ESPIDF} + cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF} + # don't CRLFify executable files, as Linux will fail to execute them + find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \; + make IDF_PATH=${CRLF_ESPIDF} || failure "Failed to build with CRLFs in source" + # do the same checks we do for the clean build + assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin + [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" + + + print_status "All tests completed" + if [ -n "${FAILURES}" ]; then + echo "Some failures were detected:" + echo -e "${FAILURES}" + exit 1 + else + echo "Build tests passed." + fi } function print_status() { - echo "******** $1" - STATUS="$1" + echo "******** $1" + STATUS="$1" } function failure() { - echo "!!!!!!!!!!!!!!!!!!!" - echo "FAILURE: $1" - echo "!!!!!!!!!!!!!!!!!!!" - FAILURES="${FAILURES}${STATUS} :: $1\n" + echo "!!!!!!!!!!!!!!!!!!!" + echo "FAILURE: $1" + echo "!!!!!!!!!!!!!!!!!!!" + FAILURES="${FAILURES}${STATUS} :: $1\n" } TESTDIR=${TMP}/build_system_tests_$$ @@ -140,62 +179,68 @@ BUILD=${TESTDIR}/template/build # copy all the build output to a snapshot directory function take_build_snapshot() { - rm -rf ${SNAPSHOT} - cp -ap ${TESTDIR}/template/build ${SNAPSHOT} + rm -rf ${SNAPSHOT} + cp -ap ${TESTDIR}/template/build ${SNAPSHOT} } # verify that all the arguments are present in the build output directory function assert_built() { - until [ -z "$1" ]; do - if [ ! -f "${BUILD}/$1" ]; then - failure "File $1 should be in the build output directory" - fi - shift - done + until [ -z "$1" ]; do + if [ ! -f "${BUILD}/$1" ]; then + failure "File $1 should be in the build output directory" + fi + shift + done } # Test if a file has been rebuilt. function file_was_rebuilt() { - # can't use [ a -ot b ] here as -ot only gives second resolution - # but stat -c %y seems to be microsecond at least for tmpfs, ext4.. - if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then - return 0 - else - return 1 - fi + # can't use [ a -ot b ] here as -ot only gives second resolution + # but stat -c %y seems to be microsecond at least for tmpfs, ext4.. + if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then + return 0 + else + return 1 + fi } # verify all the arguments passed in were rebuilt relative to the snapshot function assert_rebuilt() { - until [ -z "$1" ]; do - assert_built "$1" - if [ ! -f "${SNAPSHOT}/$1" ]; then - failure "File $1 should have been original build snapshot" - fi - if ! file_was_rebuilt "$1"; then - failure "File $1 should have been rebuilt" - fi - shift - done + until [ -z "$1" ]; do + assert_built "$1" + if [ ! -f "${SNAPSHOT}/$1" ]; then + failure "File $1 should have been original build snapshot" + fi + if ! file_was_rebuilt "$1"; then + failure "File $1 should have been rebuilt" + fi + shift + done } # verify all the arguments are in the build directory & snapshot, # but were not rebuilt function assert_not_rebuilt() { - until [ -z "$1" ]; do - assert_built "$1" - if [ ! -f "${SNAPSHOT}/$1" ]; then - failure "File $1 should be in snapshot build directory" - fi - if file_was_rebuilt "$1"; then - failure "File $1 should not have been rebuilt" - fi - shift - done + until [ -z "$1" ]; do + assert_built "$1" + if [ ! -f "${SNAPSHOT}/$1" ]; then + failure "File $1 should be in snapshot build directory" + fi + if file_was_rebuilt "$1"; then + failure "File $1 should not have been rebuilt" + fi + shift + done +} + +# do a "clean" that doesn't depend on 'make clean' +function clean_build_dir() +{ + rm -rf --preserve-root ${BUILD}/* } cd ${TESTDIR}