Nico Huber has submitted this change. ( https://review.coreboot.org/c/coreboot/+/84385?usp=email )
Change subject: Makefile: Fix no-op incremental build ......................................................................
Makefile: Fix no-op incremental build
If make is ran a second time after an initial clean compile, the entire rom will be rebuilt. Subsequent calls to make will not rebuild the rom. This initial rebuild was due to build/util/kconfig/conf being newer than config.h, and the subsequent rebuild of the header marked everything else as out of date. The reason conf was newer than config.h is because it was being treated as an intermediate file [1]. In the rule for config.h, conf is a prerequisite, but since it is treated as an intermediate, its rule will not be run if config.h exists and all the prerequisites of conf (i.e. its source files) are also up to date.
On a clean build after a make menuconfig, config.h exists, satisfying these conditions. In this case, config.h is treated as being up to date even though conf does not exist. However, if another target does not exist and also has conf as a prerequisite, conf will then be built so that the target can be built. This caused conf to be newer than config.h, but by default GNU Make deletes intermediate files after a build which would prevent conf from affecting config.h on subsequent rebuilds.
However, commit dd6efce934fb ("Makefile: Add .SECONDARY") adds the .SECONDARY special target, which prevents intermediate files from being deleted after the build [2]. Thus, conf persists to the first no-op build, making config.h out of date. Since config.h is updated during this first rebuild, conf is no longer newer than it, and thus subsequent no-op builds behave as expected.
Fix this by preventing conf from being treated as an intermediate file by adding it as a prerequisite of the .NOTINTERMEDIATE special target, which causes conf to always be rebuilt if it does not exist. Thus, on the initial clean compile, config.h will be updated after building conf as a prerequisite, preventing config.h from being marked out of date on a subsequent rebuild.
[1] https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html [2] https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
Change-Id: I98c49d47f811e5cceebce7b7d54b282c773734e3 Signed-off-by: Nicholas Chin nic.c3.14@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/84385 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Nico Huber nico.h@gmx.de --- M Makefile 1 file changed, 6 insertions(+), 0 deletions(-)
Approvals: Nico Huber: Looks good to me, approved build bot (Jenkins): Verified
diff --git a/Makefile b/Makefile index 810ccb8..491e702 100644 --- a/Makefile +++ b/Makefile @@ -229,6 +229,12 @@ .SECONDEXPANSION: .DELETE_ON_ERROR:
+# conf is treated as an intermediate target and may be built after config.h +# during a clean build due to the way GNU Make handles intermediates when the +# .SECONDARY target is present, forcing config.h and thus every object out of +# date on a subsequent no-op build. Mark it as not intermediate to prevent this +.NOTINTERMEDIATE: $(objutil)/kconfig/conf + $(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG) $(objutil)/kconfig/conf $(MAKE) olddefconfig $(MAKE) syncconfig