diff options
author | Brad King <brad.king@kitware.com> | 2016-09-22 14:11:36 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-09-22 17:52:03 (GMT) |
commit | 8eca59a175b551c2d4c98fd9523e6aca6c51a82b (patch) | |
tree | c9e22d13c177fcdca0c1f15be9ff0f6a72fc05b7 /Source | |
parent | a57d1bb7122be79101cc17a4b8a04bd0ac5a041e (diff) | |
download | CMake-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.cxx | 78 |
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). +*/ |