Jelajahi Sumber

make: Fix COMPONENT_OWNBUILDTARGET

Add build system test to match

Partial fix for https://github.com/espressif/esp-idf/issues/3664
Angus Gratton 4 tahun lalu
induk
melakukan
dea52a92b9

+ 1 - 0
.gitlab/ci/rules.yml

@@ -42,6 +42,7 @@
   - "tools/cmake/**/*"
   - "tools/kconfig_new/**/*"
   - "tools/tools.json"
+  - "tools/ci/test_build_system*.sh"
 
 .patterns-custom_test: &patterns-custom_test
   - "components/espcoredump/**/*"

+ 1 - 1
docs/en/api-guides/build-system-legacy.rst

@@ -497,7 +497,7 @@ Fully Overriding The Component Makefile
 
 Obviously, there are cases where all these recipes are insufficient for a certain component, for example when the component is basically a wrapper around another third-party component not originally intended to be compiled under this build system. In that case, it's possible to forego the esp-idf build system entirely by setting COMPONENT_OWNBUILDTARGET and possibly  COMPONENT_OWNCLEANTARGET and defining your own targets named ``build`` and ``clean`` in ``component.mk`` target. The build target can do anything as long as it creates $(COMPONENT_LIBRARY) for the project make process to link into the app binary.
 
-(Actually, even this is not strictly necessary - if the COMPONENT_ADD_LDFLAGS variable is overridden then the component can instruct the linker to link other binaries instead.)
+It is possible for the component build target to build additional libraries and add these to the linker arguments as well. It's even possible for the default $(COMPONENT_LIBRARY) to be a dummy library, however it's used to track the overall build status so the build target should always create it.
 
 .. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
 

+ 6 - 0
make/component_wrapper.mk

@@ -201,6 +201,12 @@ component_project_vars.mk::
 	@echo 'COMPONENT_LIBRARIES += $(COMPONENT_NAME)' >> $@
 	@echo 'COMPONENT_LDFRAGMENTS += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_LDFRAGMENTS))))' >> $@
 	@echo 'component-$(COMPONENT_NAME)-build: $(addprefix component-,$(addsuffix -build,$(COMPONENT_DEPENDS)))' >> $@
+ifdef COMPONENT_OWNBUILDTARGET
+	@echo 'COMPONENT_$(COMPONENT_NAME)_BUILDTARGET := $(COMPONENT_OWNBUILDTARGET)' >> $@
+endif
+ifdef COMPONENT_OWNCLEANTARGET
+	@echo 'COMPONENT_$(COMPONENT_NAME)_CLEANTARGET := $(COMPONENT_OWNCLEANTARGET)' >> $@
+endif
 ################################################################################
 # 5) Where COMPONENT_OWNBUILDTARGET / COMPONENT_OWNCLEANTARGET
 # is not set by component.mk, define default build, clean, etc. targets

+ 5 - 2
make/project.mk

@@ -616,11 +616,14 @@ endef
 define GenerateComponentTargets
 .PHONY: component-$(2)-build component-$(2)-clean
 
+COMPONENT_$(2)_BUILDTARGET ?= build
+COMPONENT_$(2)_CLEANTARGET ?= clean
+
 component-$(2)-build: check-submodules $(call prereq_if_explicit, component-$(2)-clean) | $(BUILD_DIR_BASE)/$(2)
-	$(call ComponentMake,$(1),$(2)) build
+	$(call ComponentMake,$(1),$(2)) $$(COMPONENT_$(2)_BUILDTARGET)
 
 component-$(2)-clean: | $(BUILD_DIR_BASE)/$(2) $(BUILD_DIR_BASE)/$(2)/component_project_vars.mk
-	$(call ComponentMake,$(1),$(2)) clean
+	$(call ComponentMake,$(1),$(2)) $$(COMPONENT_$(2)_CLEANTARGET)
 
 $(BUILD_DIR_BASE)/$(2):
 	@mkdir -p $(BUILD_DIR_BASE)/$(2)

+ 26 - 0
tools/ci/test_build_system.sh

@@ -432,6 +432,32 @@ endmenu\n" >> ${IDF_PATH}/Kconfig;
     mv Makefile.bak Makefile # revert previous modifications
     rm -rf extra_dir components
 
+    print_status "COMPONENT_OWNBUILDTARGET, COMPONENT_OWNCLEANTARGET can work"
+    take_build_snapshot
+    mkdir -p components/test_component
+    cat > components/test_component/component.mk  <<EOF
+COMPONENT_OWNBUILDTARGET:=custom_build
+COMPONENT_OWNCLEANTARGET:=custom_clean
+
+.PHONY: custom_target
+
+custom_build:
+	echo "Running custom_build!"
+	echo "" | \$(CC) -x c++ -c -o dummy_obj.o -
+	\$(AR) cr libtest_component.a dummy_obj.o
+
+custom_clean:
+	rm -f libtest_component.a dummy_obj.o
+EOF
+    make || failure "Failed to build with custom component build target"
+    [ -f ${BUILD}/test_component/dummy_obj.o ] || failure "Failed to build dummy_obj.o in custom target"
+    [ -f ${BUILD}/test_component/libtest_component.a ] || failure "Failed to build custom component library"
+    grep -q "libtest_component.a" ${BUILD}/*.map || failure "Linker didn't see the custom library"
+    make clean || failure "Failed to make clean with custom clean target"
+    [ -f ${BUILD}/test_component/dummy_obj.o ] && failure "Custom clean target didn't clean object file"
+    [ -f ${BUILD}/test_component/libtest_component.a ] && failure "Custom clean target didn't clean library"
+    rm -rf components/test_component
+
     print_status "All tests completed"
     if [ -n "${FAILURES}" ]; then
         echo "Some failures were detected:"