@@ -339,9 +339,9 @@ preprocessFile mbWorkDir searchLoc buildLoc forSDist baseFile verbosity builtinS
339339 -- the tarball).
340340 -- TODO: eliminate sdist variant, just supply different handlers
341341 when (not forSDist || forSDist && platformIndependent pp) $ do
342- -- look for existing pre-processed source file in the dest dir to
343- -- see if we really have to re-run the preprocessor .
344-
342+ -- Use file monitoring to only re-run the preprocessor if either the
343+ -- input file or the preprocessor itself have changed .
344+ -- See Note [Preprocessor monitoring].
345345 (runPreProcessor, key) <- configurePreProcessor pp verbosity
346346 let recompile = liftIO $ do
347347 let destDir = i buildLoc </> takeDirectory srcStem
@@ -1003,3 +1003,42 @@ preprocessExtras verbosity comp lbi = case comp of
10031003 ++ map exeName (executables pkg_descr)
10041004 ++ map testName (testSuites pkg_descr)
10051005 ++ map benchmarkName (benchmarks pkg_descr)
1006+
1007+ {-
1008+
1009+ Note [Preprocessor monitoring]
1010+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1011+ In order to decide whether a given pre-processed file must be (re)generated, we
1012+ need to check two things: the input file, and the preprocessor that is used to
1013+ generate it. If either of these changes, *or* if the output file doesn't exist,
1014+ we need to (re-)run the preprocessor.
1015+
1016+ We reuse the existing file monitoring infrastructure for this (see
1017+ "Distribution.Simple.FileMonitor"), which allows us to specify a set of files to
1018+ monitor (our input file), and a /key/, which is an arbitrary value which, when
1019+ changed, will trigger a re-run.
1020+
1021+ That key will be different for each known preprocessor, but it will generally be
1022+ one of two things:
1023+
1024+ - A dummy value to indicate that we're dealing with a built-in preprocessor
1025+ (e.g. @unlit@), which never changes between builds using the same Cabal
1026+ version
1027+ - A set of configured programs ('ConfiguredProgram'), each representing an
1028+ on-disk binary that will handle (part of) the preprocessing, with a full path
1029+ and any arguments and environment variables that will be passed to it.
1030+
1031+ The 'PreProcessorKey' type (defined in "Distribution.Simple.PreProcess.Types")
1032+ represents these keys.
1033+
1034+ Further, to make sure that we can get that key without actually having to run
1035+ the preprocessor (which is the very thing we try to avoid), the 'PreProcessor'
1036+ data structure exposes the 'configurePreProcessor' function, which in turn
1037+ produces the actual preprocessor action together with the corresponding key,
1038+ thus making sure that the two always match.
1039+
1040+ Crucially, the re-run logic here __relies on the fact that all preprocessors
1041+ will be pre-configured__, such that 'lookupProgramVersion' never actually has to
1042+ configure any programs at this point.
1043+
1044+ -}
0 commit comments