Skip to content

Commit 67f85b0

Browse files
authored
Merge pull request #11791 from sheaf/T7684
Build dynamic sublibraries when needed
2 parents 231b81f + 0b35e3a commit 67f85b0

7 files changed

Lines changed: 93 additions & 5 deletions

File tree

Cabal/src/Distribution/Simple/GHC/Build.hs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module Distribution.Simple.GHC.Build where
55
import Distribution.Compat.Prelude
66
import Prelude ()
77

8-
import Control.Monad.IO.Class
8+
import qualified Distribution.Compat.Graph as Graph
9+
910
import Distribution.PackageDescription as PD hiding (buildInfo)
1011
import Distribution.Simple.Build.Inputs
1112
import Distribution.Simple.Flag (Flag)
@@ -25,6 +26,8 @@ import Distribution.Utils.NubList (fromNubListR)
2526
import Distribution.Utils.Path
2627

2728
import Distribution.Verbosity (VerbosityHandles, mkVerbosity, verbosityHandles)
29+
30+
import Control.Monad.IO.Class
2831
import System.FilePath (splitDirectories)
2932

3033
{- Note [Build Target Dir vs Target Dir]
@@ -75,7 +78,7 @@ build numJobs verbHandles pkg_descr pbci = do
7578
verbosity = mkVerbosity verbHandles $ buildVerbosity pbci
7679
isLib = buildIsLib pbci
7780
lbi = localBuildInfo pbci
78-
bi = buildBI pbci
81+
comp = buildComponent pbci
7982
clbi = buildCLBI pbci
8083
isIndef = componentIsIndefinite clbi
8184
mbWorkDir = mbWorkDirLBI lbi
@@ -118,9 +121,35 @@ build numJobs verbHandles pkg_descr pbci = do
118121
let wantedWays@(wantedLibWays, wantedFLibWay, wantedExeWay) = buildWays lbi
119122

120123
-- Ways which are needed due to the compiler configuration
121-
let doingTH = usesTemplateHaskellOrQQ bi
124+
let doingTH =
125+
-- Does this component, or another component that (transitively) depends
126+
-- on this component, use TemplateHaskell or QuasiQuotes?
127+
--
128+
-- Ticket #7684 showed that we need to take into account intra-package
129+
-- dependencies.
130+
any usesTemplateHaskellOrQQ thisCompAndReverseDepsBuildInfos
131+
132+
-- The BuildInfos for this component and all of the components that
133+
-- transitively depend on it (its reverse dependencies).
134+
thisCompAndReverseDepsBuildInfos =
135+
[ componentBuildInfo revDepComp
136+
| let compUnitId = componentUnitId clbi
137+
, -- 'revClosure' retrieves components that depend on this component.
138+
revDepCLBI <- fromMaybe [clbi] $ Graph.revClosure (componentGraph lbi) [compUnitId]
139+
, -- Use 'lookupComponent' here; don't use any function that goes via
140+
-- 'getComponent' (e.g. mkTargetInfo or unitIdTarget'), as that will
141+
-- tiresomely cause an error for 'detailed-0.9' test-suites because
142+
-- 'testSuiteLibV09AsLibAndExe' creates a stub PackageDescription with
143+
-- most components zeroed out.
144+
--
145+
-- The implementation below means we will get 'Nothing' when the
146+
-- current component is a 'detailed-0.9' test-suite, which is fine
147+
-- as nothing can depend on a test-suite.
148+
Just revDepComp <- [lookupComponent pkg_descr $ componentLocalName revDepCLBI]
149+
]
150+
122151
defaultGhcWay = compilerBuildWay (buildCompiler pbci)
123-
wantedModBuildWays = case buildComponent pbci of
152+
wantedModBuildWays = case comp of
124153
CLib _ -> wantedLibWays isIndef
125154
CFLib fl -> [wantedFLibWay (withDynFLib fl)]
126155
CExe _ -> [wantedExeWay]
@@ -129,7 +158,7 @@ build numJobs verbHandles pkg_descr pbci = do
129158
finalModBuildWays =
130159
wantedModBuildWays
131160
++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedModBuildWays]
132-
compNameStr = showComponentName $ componentName $ buildComponent pbci
161+
compNameStr = showComponentName $ componentName comp
133162

134163
liftIO $ info verbosity ("Wanted module build ways(" ++ compNameStr ++ "): " ++ show wantedModBuildWays)
135164
liftIO $ info verbosity ("Final module build ways(" ++ compNameStr ++ "): " ++ show finalModBuildWays)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
cabal-version: 2.2
2+
name: T7684
3+
version: 0.1.0.0
4+
license: BSD-3-Clause
5+
author: Matthew Pickering
6+
maintainer: The Cabal team
7+
build-type: Simple
8+
synopsis: Test for Cabal bug #7684
9+
description:
10+
Check that we compile sublibraries in the dynamic way when that is needed
11+
due to TemplateHaskell or QuasiQuotes in another component that depends on it.
12+
13+
library library-a
14+
hs-source-dirs: lib-a
15+
exposed-modules: A
16+
build-depends: base, template-haskell
17+
18+
default-language: Haskell2010
19+
20+
library
21+
hs-source-dirs: lib
22+
exposed-modules: B
23+
build-depends: base, library-a
24+
default-language: Haskell2010
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
packages: .
2+
3+
shared: False
4+
executable-dynamic: False
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Test.Cabal.Prelude
2+
3+
main = setupAndCabalTest $ recordMode DoNotRecord $ do
4+
setup "configure" []
5+
setup "build" []
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{-# LANGUAGE TemplateHaskellQuotes #-}
2+
3+
module A where
4+
5+
import Language.Haskell.TH.Syntax ( Q, Exp )
6+
7+
a :: Q Exp
8+
a = [| putStrLn "a" |]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{-# LANGUAGE TemplateHaskell #-}
2+
3+
module B where
4+
5+
import A
6+
7+
main = $(a)

changelog.d/IntraPackageDyn.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
synopsis: Build dynamic libraries when needed for intra-package dependencies
3+
packages: [Cabal]
4+
prs: 11791
5+
issues: 7684
6+
---
7+
8+
When building a package with a sublibrary, Cabal now properly takes into account
9+
intra-package dependencies when deciding whether each sublibrary should be built
10+
in the dynamic way (e.g. because another library that depends on it uses
11+
TemplateHaskell or QuasiQuotes).

0 commit comments

Comments
 (0)