I’d like to display a progress bar during building with GNU make. It works great for clean builds, but it’s inaccurate for incremental builds.
To calculate the actual progress, we need to know the total number of files to compile and that how many were already compiled.
The issue is getting the number of files to build. It’s easy to count ALL the files, but in case of an incremental build, when only a fraction of the targets are out-of-date, the calculation does not work.
Is it somehow possible to count the number of out-of-date targets before starting executing the rules? Alternatively, counting the up-to-date targets would be just as good.
Here is the current code (simplified), showing how the progress is calculated:
define ADD_TO_COMPILE
$1 : $2
$(eval ALL_STEPS+=1)
$$(eval FILES_DONE+=1)
$$(call CALL_CC,$1,$2)
$(1:.$(OBJ_FILE_SUFFIX)=.$(DEP_FILE_SUFFIX)): ;
include $(1:.$(OBJ_FILE_SUFFIX)=.$(DEP_FILE_SUFFIX))
endef
This function is invoked for each C file in the project.
ALL_STEPS is incremented during interpreting the makefile, and when rule execution begins it contains the number of ALL files, both up-to-date and out-of-date ones.
FILES_DONE is incremented as the recipes are executed. It always reflects how many files were compiled during the current run, but not that how many were up-to-date and did not need recompilation.
So I can display files_built_in_the_current_run / total_files, and it’s wildly inaccurate when only 2 files from 100 need to be built. Indicator goes up to 2%, and we’re done!
Any ideas?