summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-09-22 14:11:36 (GMT)
committerBrad King <brad.king@kitware.com>2016-09-22 17:52:03 (GMT)
commit8eca59a175b551c2d4c98fd9523e6aca6c51a82b (patch)
treec9e22d13c177fcdca0c1f15be9ff0f6a72fc05b7 /Source
parenta57d1bb7122be79101cc17a4b8a04bd0ac5a041e (diff)
downloadCMake-8eca59a175b551c2d4c98fd9523e6aca6c51a82b.zip
CMake-8eca59a175b551c2d4c98fd9523e6aca6c51a82b.tar.gz
CMake-8eca59a175b551c2d4c98fd9523e6aca6c51a82b.tar.bz2
Ninja: Add comment with Fortran dependency design documentation
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx78
1 files changed, 78 insertions, 0 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 42ce622..6da6617 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1408,3 +1408,81 @@ void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
EnsureTrailingSlash(path);
cmStripSuffixIfExists(path, this->OutputPathPrefix);
}
+
+/*
+
+We use the following approach to support Fortran. Each target already
+has a <target>.dir/ directory used to hold intermediate files for CMake.
+For each target, a FortranDependInfo.json file is generated by CMake with
+information about include directories, module directories, and the locations
+the per-target directories for target dependencies.
+
+Compilation of source files within a target is split into the following steps:
+
+1. Preprocess all sources, scan preprocessed output for module dependencies.
+ This step is done with independent build statements for each source,
+ and can therefore be done in parallel.
+
+ rule Fortran_PREPROCESS
+ depfile = $DEP_FILE
+ command = gfortran -cpp $DEFINES $INCLUDES $FLAGS -E $in -o $out &&
+ cmake -E cmake_ninja_depends \
+ --tdi=FortranDependInfo.json --pp=$out --dep=$DEP_FILE \
+ --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE
+
+ build src.f90-pp.f90 | src.f90-pp.f90.ddi: Fortran_PREPROCESS src.f90
+ OBJ_FILE = src.f90.o
+ DEP_FILE = src.f90-pp.f90.d
+ DYNDEP_INTERMEDIATE_FILE = src.f90-pp.f90.ddi
+
+ The ``cmake -E cmake_ninja_depends`` tool reads the preprocessed output
+ and generates the ninja depfile for preprocessor dependencies. It also
+ generates a "ddi" file (in a format private to CMake) that lists the
+ object file that compilation will produce along with the module names
+ it provides and/or requires. The "ddi" file is an implicit output
+ because it should not appear in "$out" but is generated by the rule.
+
+2. Consolidate the per-source module dependencies saved in the "ddi"
+ files from all sources to produce a ninja "dyndep" file, ``Fortran.dd``.
+
+ rule Fortran_DYNDEP
+ command = cmake -E cmake_ninja_dyndep \
+ --tdi=FortranDependInfo.json --dd=$out $in
+
+ build Fortran.dd: Fortran_DYNDEP src1.f90-pp.f90.ddi src2.f90-pp.f90.ddi
+
+ The ``cmake -E cmake_ninja_dyndep`` tool reads the "ddi" files from all
+ sources in the target and the ``FortranModules.json`` files from targets
+ on which the target depends. It computes dependency edges on compilations
+ that require modules to those that provide the modules. This information
+ is placed in the ``Fortran.dd`` file for ninja to load later. It also
+ writes the expected location of modules provided by this target into
+ ``FortranModules.json`` for use by dependent targets.
+
+3. Compile all sources after loading dynamically discovered dependencies
+ of the compilation build statements from their ``dyndep`` bindings.
+
+ rule Fortran_COMPILE
+ command = gfortran $INCLUDES $FLAGS -c $in -o $out
+
+ build src1.f90.o: Fortran_COMPILE src1.f90-pp.f90 || Fortran.dd
+ dyndep = Fortran.dd
+
+ The "dyndep" binding tells ninja to load dynamically discovered
+ dependency information from ``Fortran.dd``. This adds information
+ such as:
+
+ build src1.f90.o | mod1.mod: dyndep
+ restat = 1
+
+ This tells ninja that ``mod1.mod`` is an implicit output of compiling
+ the object file ``src1.f90.o``. The ``restat`` binding tells it that
+ the timestamp of the output may not always change. Additionally:
+
+ build src2.f90.o: dyndep | mod1.mod
+
+ This tells ninja that ``mod1.mod`` is a dependency of compiling the
+ object file ``src2.f90.o``. This ensures that ``src1.f90.o`` and
+ ``mod1.mod`` will always be up to date before ``src2.f90.o`` is built
+ (because the latter consumes the module).
+*/