Unix Makefiles: do not use recursive calls to build *.provides.build targets
Makefiles generated by cmake use a series of recursive calls to build *.provides.build targets that are used when the "requires step" is needed. It seems that currently only Fortran targets use "requires step", thus the example provided is Fortran-specific, but the described issue would affect any language that needs "requires step".
In case of Fortran project and Unix Makefile generator, cmake generates the following structure of targets to be built during the "requires step":
build.make:
foo.F90.o.provides: foo.F90.o.requires
$(MAKE) -f build.make foo.F90.o.provides.build
foo.F90.o.provides.build: foo.F90.o
depend.make:
foo.F90.o.provides.build:
$(CMAKE_COMMAND) -E cmake_copy_f90_mod moda_foo moda_foo.mod.stamp GNU
$(CMAKE_COMMAND) -E cmake_copy_f90_mod modb_foo modb_foo.mod.stamp GNU
$(CMAKE_COMMAND) -E cmake_copy_f90_mod modc_foo modc_foo.mod.stamp GNU
$(CMAKE_COMMAND) -E touch foo.F90.o.provides.build
That leads to significant degradation of the build time for incremental builds, especially for medium and large-size projects, because for each source file a new instance of make would be invoked and start from parsing of the build.make file, that is quite large, again and again. As result, for a medium-size project with approx 1500 Fortran modules a simple call to the make
command requires more than 5 minutes to tell that all sources are up-to-date.
To speed-up these builds recursive make calls for *.provides.build targets could be eliminated by re-arranging target dependencies in the following way:
build.make:
foo.F90.o.provides: foo.F90.o.requires
foo.F90.o.provides: foo.F90.o.provides.build
foo.F90.o.provides.build: foo.F90.o
depend.make:
foo.F90.o.provides.build: moda_foo.mod.stamp
moda_foo.mod.stamp: foo.F90.o
$(CMAKE_COMMAND) -E cmake_copy_f90_mod moda_foo moda_foo.mod.stamp GNU
foo.F90.o.provides.build: modb_foo.mod.stamp
modb_foo.mod.stamp: foo.F90.o
$(CMAKE_COMMAND) -E cmake_copy_f90_mod modb_foo modb_foo.mod.stamp GNU
foo.F90.o.provides.build: modc_foo.mod.stamp
modc_foo.mod.stamp: foo.F90.o
$(CMAKE_COMMAND) -E cmake_copy_f90_mod modc_foo modc_foo.mod.stamp GNU
foo.F90.o.provides.build:
$(CMAKE_COMMAND) -E touch foo.F90.o.provides.build
That results in a significant speed-up of incremental builds for the Fortran projects. In our case, time required for make
to tell that all sources are up-to-date went from 5 minutes to 2 seconds.
This merge request eliminates recursive calls and re-arranges dependencies of *.provides.build targets for the Fortran projects to speed-up incremental builds.
Topic-rename: makefile-simplify-fortran