summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-12-02 16:39:29 -0500
committerBrad King <brad.king@kitware.com>2019-04-18 08:21:44 -0400
commit1d55d05afd5949a5caa6b41ffa5539f4cbb5a575 (patch)
tree3b792807b3d1aaa2402fe95548920305803cfed6
parent014a5414c4c2301d5572e7cb805416997f35d539 (diff)
downloadninja-1d55d05afd5949a5caa6b41ffa5539f4cbb5a575.tar.gz
Document example dyndep use cases
Show a simple example of Fortran module dependencies (this use case motivated the entire dyndep feature). Also show an example of tarball extraction, a case that few other buildsystems can handle cleanly.
-rw-r--r--doc/manual.asciidoc83
1 files changed, 83 insertions, 0 deletions
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc
index 0e52e1a..c9309ad 100644
--- a/doc/manual.asciidoc
+++ b/doc/manual.asciidoc
@@ -1070,3 +1070,86 @@ The build statements in a dyndep file must have a one-to-one correspondence
to build statements in the <<ref_ninja_file,ninja build file>> that name the
dyndep file in a `dyndep` binding. No dyndep build statement may be omitted
and no extra build statements may be specified.
+
+Dyndep Examples
+~~~~~~~~~~~~~~~
+
+Fortran Modules
+^^^^^^^^^^^^^^^
+
+Consider a Fortran source file `foo.f90` that provides a module
+`foo.mod` (an implicit output of compilation) and another source file
+`bar.f90` that uses the module (an implicit input of compilation). This
+implicit dependency must be discovered before we compile either source
+in order to ensure that `bar.f90` never compiles before `foo.f90`, and
+that `bar.f90` recompiles when `foo.mod` changes. We can achieve this
+as follows:
+
+----
+rule f95
+ command = f95 -o $out -c $in
+rule fscan
+ command = fscan -o $out $in
+
+build foobar.dd: fscan foo.f90 bar.f90
+
+build foo.o: f95 foo.f90 || foobar.dd
+ dyndep = foobar.dd
+build bar.o: f95 bar.f90 || foobar.dd
+ dyndep = foobar.dd
+----
+
+In this example the order-only dependencies ensure that `foobar.dd` is
+generated before either source compiles. The hypothetical `fscan` tool
+scans the source files, assumes each will be compiled to a `.o` of the
+same name, and writes `foobar.dd` with content such as:
+
+----
+ninja_dyndep_version = 1
+build foo.o | foo.mod: dyndep
+build bar.o: dyndep | foo.mod
+----
+
+Ninja will load this file to add `foo.mod` as an implicit output of
+`foo.o` and implicit input of `bar.o`. This ensures that the Fortran
+sources are always compiled in the proper order and recompiled when
+needed.
+
+Tarball Extraction
+^^^^^^^^^^^^^^^^^^
+
+Consider a tarball `foo.tar` that we want to extract. The extraction time
+can be recorded with a `foo.tar.stamp` file so that extraction repeats if
+the tarball changes, but we also would like to re-extract if any of the
+outputs is missing. However, the list of outputs depends on the content
+of the tarball and cannot be spelled out explicitly in the ninja build file.
+We can achieve this as follows:
+
+----
+rule untar
+ command = tar xf $in && touch $out
+rule scantar
+ command = scantar --stamp=$stamp --dd=$out $in
+build foo.tar.dd: scantar foo.tar
+ stamp = foo.tar.stamp
+build foo.tar.stamp: untar foo.tar || foo.tar.dd
+ dyndep = foo.tar.dd
+----
+
+In this example the order-only dependency ensures that `foo.tar.dd` is
+built before the tarball extracts. The hypothetical `scantar` tool
+will read the tarball (e.g. via `tar tf`) and write `foo.tar.dd` with
+content such as:
+
+----
+ninja_dyndep_version = 1
+build foo.tar.stamp | file1.txt file2.txt : dyndep
+ restat = 1
+----
+
+Ninja will load this file to add `file1.txt` and `file2.txt` as implicit
+outputs of `foo.tar.stamp`, and to mark the build statement for `restat`.
+On future builds, if any implicit output is missing the tarball will be
+extracted again. The `restat` binding tells Ninja to tolerate the fact
+that the implicit outputs may not have modification times newer than
+the tarball itself (avoiding re-extraction on every build).