Skip to content

Commit ee59583

Browse files
angermanandreabedini
authored andcommitted
Allow build-type Configure to work with Components
When components were introduced, cabal had support for build-type: Configure, which allows to run a `configure` script prior to building the package. Upon the introduction of components, it became obvious that we can't just configure each and every component, as this easily runs into the situation where the `configure` script is run potentially concurrently for all components. However, build-type is a global option for cabal files, and is usually used to produce a <pkg>.buildinfo file. This file is then used to augment the Main Library and Executables only. This change now tracks whether or not we are building a main library or executable component, and if we do, retains only for these components the build-type: Configure from the package description. For all other components, we will fall back to the default build-type: Simple. For end users who want to depend on package configured values, they will need to set their sub libraries, testsuites and benchmark components to depend on the main library, and import any configured values from there. For lib:Cabal, which doesn't know about components when configure is invoked, we will continue to execute configure. There is no impact on lib:Cabal in this change.
1 parent cd00d88 commit ee59583

File tree

5 files changed

+56
-7
lines changed

5 files changed

+56
-7
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ configureSetupScript
300300
, useDependenciesExclusive = not defaultSetupDeps && isJust explicitSetupDeps
301301
, useVersionMacros = not defaultSetupDeps && isJust explicitSetupDeps
302302
, isInteractive = False
303+
, isMainLibOrExeComponent = True
303304
}
304305
where
305306
-- When we are compiling a legacy setup script without an explicit

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,14 +1709,18 @@ elaborateInstallPlan
17091709
-- invocation of the same `./configure` script.
17101710
-- See https://github.com/haskell/cabal/issues/4548
17111711
--
1712-
-- Moreover, at this point in time, only non-Custom setup scripts
1713-
-- are supported. Implementing per-component builds with
1714-
-- Custom would require us to create a new 'ElabSetup'
1712+
-- We have to disable per-component at this point in time, only
1713+
-- Simple and Configure build types are supported. Custom and
1714+
-- Hooks are not implemented. Implementing per-component builds
1715+
-- with Custom would require us to create a new 'ElabSetup'
17151716
-- type, and teach all of the code paths how to handle it.
17161717
-- Once you've implemented this, swap it for the code below.
17171718
cuz_buildtype =
17181719
case bt of
1719-
PD.Configure -> [CuzBuildType CuzConfigureBuildType]
1720+
PD.Configure -> []
1721+
-- Configure is supported, but we only support configuring the
1722+
-- main library in cabal. Other components will need to depend
1723+
-- on the main library for configured data.
17201724
PD.Custom -> [CuzBuildType CuzCustomBuildType]
17211725
PD.Hooks -> [CuzBuildType CuzHooksBuildType]
17221726
PD.Make -> [CuzBuildType CuzMakeBuildType]
@@ -3937,6 +3941,16 @@ setupHsScriptOptions
39373941
, forceExternalSetupMethod = isParallelBuild
39383942
, setupCacheLock = Just cacheLock
39393943
, isInteractive = False
3944+
, isMainLibOrExeComponent = case elabPkgOrComp of
3945+
-- if it's a package, it's all together, so we have to assume it's
3946+
-- at least a library or executable.
3947+
ElabPackage _ -> True
3948+
-- if it's a component, we have to check if it's a Main Library or Executable
3949+
-- as opposed to SubLib, FLib, Test, Bench, or Setup component.
3950+
ElabComponent (ElaboratedComponent{compSolverName = CD.ComponentLib}) -> True
3951+
ElabComponent (ElaboratedComponent{compSolverName = CD.ComponentExe _}) -> True
3952+
-- everything else is not a main lib or exe component
3953+
ElabComponent _ -> False
39403954
}
39413955
where
39423956
Toolchain{toolchainCompiler, toolchainPlatform, toolchainProgramDb} =

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ data SetupScriptOptions = SetupScriptOptions
330330
-- ^ Is the task we are going to run an interactive foreground task,
331331
-- or an non-interactive background task? Based on this flag we
332332
-- decide whether or not to delegate ctrl+c to the spawned task
333+
, isMainLibOrExeComponent :: Bool
334+
-- ^ Let the setup script logic know if it is being run to build a main
335+
-- library or executable component. This is used to determine if we should
336+
-- use the configure command, if the build-type is 'Configure'. For
337+
-- configure, only the main library and execomponents have 'configure'
338+
-- support, and thus we can skip running configure for other components.
333339
}
334340
deriving Show
335341

@@ -355,6 +361,7 @@ defaultSetupScriptOptions =
355361
, forceExternalSetupMethod = False
356362
, setupCacheLock = Nothing
357363
, isInteractive = False
364+
, isMainLibOrExeComponent = True
358365
}
359366

360367
instance Pretty SetupScriptOptions where
@@ -415,7 +422,14 @@ getSetup verbosity options mpkg = do
415422
(useCabalVersion options)
416423
(orLaterVersion (mkVersion (cabalSpecMinimumLibraryVersion (specVersion pkg))))
417424
}
418-
buildType' = buildType pkg
425+
-- We retain Configure only for the main library and executable components.
426+
-- For other components, we rewrite the buildType to Simple to skip the
427+
-- configure step. This is because the configure step is not supported for
428+
-- other components. Configure can only impact MainLib and Exe through
429+
-- .buildinfo files.
430+
buildType' = case (buildType pkg, isMainLibOrExeComponent options) of
431+
(Configure, False) -> Simple
432+
(bt, _) -> bt
419433
(version, method, options'') <-
420434
getSetupMethod verbosity options' pkg buildType'
421435
info verbosity $ unlines

cabal-testsuite/PackageTests/Configure/cabal.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Configuration is affected by the following files:
44
Resolving dependencies...
55
Build profile: -w ghc-<GHCVER> -O1
66
In order, the following will be built:
7-
- zlib-1.1 (lib:zlib) (first run)
8-
Configuring zlib-1.1...
7+
- zlib-1.1 (lib) (first run)
8+
Configuring library for zlib-1.1...
99
Warning: Flags 'con_flict', 'con-flict' all map to the same environment variable 'CABAL_FLAG_con_flict' causing a collision. The value first flag 'con_flict' will be used.
1010
Preprocessing library for zlib-1.1...
1111
Building library for zlib-1.1...

changelog.d/pr-10966.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
synopsis: Allow build-type: Configure
2+
packages: cabal-install
3+
prs: #10966
4+
issues: #4548
5+
significance: significant
6+
7+
description: {
8+
9+
This change allows the `build-type: Configure` field to be used in
10+
Cabal packages in conjunction with components. (E.g. public sublibraries).
11+
This is a significant change as it enables the use of the `Configure` build
12+
type, which cabal bailed on previously.
13+
14+
This does change the behaviour of cabal-install for packages that contain
15+
`build-type: Configure`. We now always build them as components with
16+
cabal-install. Previously we would turn packages with main libraries, and
17+
executables/benchmarks/tests-suites into a single package to be built in a
18+
compatibility mode. This is no longer the case.
19+
20+
}

0 commit comments

Comments
 (0)