Skip to content

Commit d007fb6

Browse files
committed
cabal-install: Be less eager to configure external programs
In configureCompiler the call to configureAllKnownPrograms was too eager. When called it selected the version of tools from PATH (such as alex), and then when a package was configured these tools were passed using `--with-alex` options to configure, which meant that the build-tool-depends versions were not used. (See haskell#10692) Why was this call introduced in the first place? Because configureCompiler would a different result depending on whether: * It is run for the first time, the `ProgramDb` will contain unconfigured programs. * It is run subsequently, `ProgramDb` is read from disk, it does not contain unconfigured programs. A surgical way to fix this is to avoid configuring the programs, and manually adding back the builtinPrograms to the ProgramDb, so the ProgramDb returned by configureCompiler always contains all the unconfigured programs. The testcase is not so easy to write because * The bug only surfaces when the build-tool you are depending on is known (ie alex, happy etc) * But then it is tricky to write a test, as we can't depend on the known tools or bundle the source for them. * So we create a fake "alex", which cabal then invokes on a fake ".x" file. This is maybe a bit fragile if the way cabal invokes alex changes in future, but then the test can be modified as well. Also see haskell#2241 and haskell#9840 Fixes haskell#10692
1 parent 04db7d0 commit d007fb6

File tree

9 files changed

+84
-6
lines changed

9 files changed

+84
-6
lines changed

cabal-install/src/Distribution/Client/ProjectPlanning.hs

+8-6
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ configureCompiler
475475
let fileMonitorCompiler = newFileMonitor $ distProjectCacheFile "compiler"
476476

477477
progsearchpath <- liftIO $ getSystemSearchPath
478-
rerunIfChanged
478+
(recomp_comp, recomp_plat, recomp_progdb) <- rerunIfChanged
479479
verbosity
480480
fileMonitorCompiler
481481
( hcFlavor
@@ -507,12 +507,14 @@ configureCompiler
507507
-- programs it cares about, and those are the ones we monitor here.
508508
monitorFiles (programsMonitorFiles progdb'')
509509

510-
-- Configure the unconfigured programs in the program database,
511-
-- as we can't serialise unconfigured programs.
512-
-- See also #2241 and #9840.
513-
finalProgDb <- liftIO $ configureAllKnownPrograms verbosity progdb''
510+
return (comp, plat, progdb'')
514511

515-
return (comp, plat, finalProgDb)
512+
-- If the above section is not recomputed, ProgramDB will be read from the
513+
-- cache and lacking the knowledge about unconfigured programs.
514+
-- Therefore the builtinPrograms are added here (since we started from the defaultProgramDb,
515+
-- this is the correct list).
516+
let restored_progdb = restoreProgramDb builtinPrograms recomp_progdb
517+
return (recomp_comp, recomp_plat, restored_progdb)
516518
where
517519
hcFlavor = flagToMaybe projectConfigHcFlavor
518520
hcPath = flagToMaybe projectConfigHcPath
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages: client
2+
optional-packages: pre-proc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Main where
2+
3+
main = print 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: client
2+
version: 0.1.0.0
3+
synopsis: Checks build-tool-depends are put in PATH
4+
license: BSD3
5+
category: Testing
6+
build-type: Simple
7+
cabal-version: >=1.10
8+
9+
executable hello-world
10+
main-is: Hello.hs
11+
build-depends: base
12+
build-tool-depends: pre-proc:alex
13+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Main where
2+
3+
import System.Environment
4+
import System.IO
5+
6+
-- This is a "fake" version of alex, so it should take the command line arguments
7+
-- as alex.
8+
main :: IO ()
9+
main = do
10+
(_:"-o":target:source:_) <- getArgs
11+
let f '0' = '1'
12+
f c = c
13+
writeFile target . map f =<< readFile source
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: pre-proc
2+
version: 999.999.999
3+
synopsis: Checks build-tool-depends are put in PATH
4+
license: BSD3
5+
category: Testing
6+
build-type: Simple
7+
cabal-version: >=1.10
8+
9+
executable alex
10+
main-is: MyCustomPreprocessor.hs
11+
build-depends: base, directory
12+
default-language: Haskell2010
13+
14+
executable bad-do-not-build-me
15+
main-is: MyMissingPreprocessor.hs
16+
build-depends: base, directory
17+
default-language: Haskell2010
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#! /usr/bin/env bash
2+
3+
echo "I am not the alex you are looking for"
4+
exit 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# cabal v2-build
2+
Configuration is affected by the following files:
3+
- cabal.project
4+
Resolving dependencies...
5+
Build profile: -w ghc-<GHCVER> -O1
6+
In order, the following will be built:
7+
- pre-proc-999.999.999 (exe:alex) (first run)
8+
- client-0.1.0.0 (exe:hello-world) (first run)
9+
Configuring executable 'alex' for pre-proc-999.999.999...
10+
Preprocessing executable 'alex' for pre-proc-999.999.999...
11+
Building executable 'alex' for pre-proc-999.999.999...
12+
Configuring executable 'hello-world' for client-0.1.0.0...
13+
Preprocessing executable 'hello-world' for client-0.1.0.0...
14+
Building executable 'hello-world' for client-0.1.0.0...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Test.Cabal.Prelude
2+
-- Test build-tool-depends isn't influenced by PATH
3+
-- This test fails with the message
4+
-- +Warning: cannot determine version of scripts/alex :
5+
-- ""
6+
-- If the scripts/alex script is executed rather than the one from the correct package.
7+
8+
main = cabalTest $ do
9+
env <- getTestEnv
10+
addToPath (testTmpDir env </> "scripts/") $ cabal "v2-build" ["client"]

0 commit comments

Comments
 (0)