Skip to content

Commit 945f88c

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 #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 #2241 and #9840 Fixes #10692
1 parent 04db7d0 commit 945f88c

File tree

11 files changed

+100
-8
lines changed

11 files changed

+100
-8
lines changed

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

Lines changed: 8 additions & 6 deletions
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
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages: client
2+
optional-packages: pre-proc
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Main where
2+
3+
main = print 0
Lines changed: 13 additions & 0 deletions
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
Lines changed: 13 additions & 0 deletions
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
Lines changed: 17 additions & 0 deletions
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
Lines changed: 4 additions & 0 deletions
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
Lines changed: 14 additions & 0 deletions
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...
Lines changed: 10 additions & 0 deletions
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"]

cabal-testsuite/PackageTests/ExtraProgPath/setup.out

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# cabal v2-build
2-
Warning: cannot determine version of <ROOT>/pkg-config :
3-
""
42
Configuration is affected by the following files:
53
- cabal.project
4+
Warning: cannot determine version of <ROOT>/pkg-config :
5+
""
6+
Warning: cannot determine version of <ROOT>/pkg-config :
7+
""
68
Resolving dependencies...
79
Error: [Cabal-7107]
810
Could not resolve dependencies:

changelog.d/pr-10731

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
synopsis: Fix regression where build-tool-depends are not used
2+
packages: cabal-install
3+
prs: #10731
4+
5+
description: {
6+
7+
Fix a bug where an executable
8+
used from your system rather than one built and provided by cabal-install would
9+
be used to satisfy a build-tool-depends field.
10+
11+
}
12+

0 commit comments

Comments
 (0)