Skip to content

Allow build-type Configure to work with Components #10966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ configureSetupScript
, useDependenciesExclusive = not defaultSetupDeps && isJust explicitSetupDeps
, useVersionMacros = not defaultSetupDeps && isJust explicitSetupDeps
, isInteractive = False
, isMainLibOrExeComponent = True
}
where
-- When we are compiling a legacy setup script without an explicit
Expand Down
28 changes: 18 additions & 10 deletions cabal-install/src/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1712,19 +1712,17 @@ elaborateInstallPlan
why_not_per_component g =
cuz_buildtype ++ cuz_spec ++ cuz_length ++ cuz_flag
where
-- We have to disable per-component for now with
-- Configure-type scripts in order to prevent parallel
-- invocation of the same `./configure` script.
-- See https://github.com/haskell/cabal/issues/4548
--
-- Moreover, at this point in time, only non-Custom setup scripts
-- are supported. Implementing per-component builds with
-- Custom would require us to create a new 'ElabSetup'
-- type, and teach all of the code paths how to handle it.
-- Custom and Hooks are not implemented. Implementing
-- per-component builds with Custom would require us to create a
-- new 'ElabSetup' type, and teach all of the code paths how to
-- handle it.
-- Once you've implemented this, swap it for the code below.
cuz_buildtype =
case bt of
PD.Configure -> [CuzBuildType CuzConfigureBuildType]
PD.Configure -> []
-- Configure is supported, but we only support configuring the
-- main library in cabal. Other components will need to depend
-- on the main library for configured data.
PD.Custom -> [CuzBuildType CuzCustomBuildType]
PD.Hooks -> [CuzBuildType CuzHooksBuildType]
PD.Make -> [CuzBuildType CuzMakeBuildType]
Expand Down Expand Up @@ -3879,6 +3877,16 @@ setupHsScriptOptions
, forceExternalSetupMethod = isParallelBuild
, setupCacheLock = Just cacheLock
, isInteractive = False
, isMainLibOrExeComponent = case elabPkgOrComp of
-- if it's a package, it's all together, so we have to assume it's
-- at least a library or executable.
ElabPackage _ -> True
-- if it's a component, we have to check if it's a Main Library or Executable
-- as opposed to SubLib, FLib, Test, Bench, or Setup component.
ElabComponent (ElaboratedComponent{compSolverName = CD.ComponentLib}) -> True
ElabComponent (ElaboratedComponent{compSolverName = CD.ComponentExe _}) -> True
-- everything else is not a main lib or exe component
ElabComponent _ -> False
}

-- | To be used for the input for elaborateInstallPlan.
Expand Down
16 changes: 15 additions & 1 deletion cabal-install/src/Distribution/Client/SetupWrapper.hs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ data SetupScriptOptions = SetupScriptOptions
-- ^ Is the task we are going to run an interactive foreground task,
-- or an non-interactive background task? Based on this flag we
-- decide whether or not to delegate ctrl+c to the spawned task
, isMainLibOrExeComponent :: Bool
-- ^ Let the setup script logic know if it is being run to build a main
-- library or executable component. This is used to determine if we should
-- use the configure command, if the build-type is 'Configure'. For
-- configure, only the main library and execomponents have 'configure'
-- support, and thus we can skip running configure for other components.
}

defaultSetupScriptOptions :: SetupScriptOptions
Expand All @@ -339,6 +345,7 @@ defaultSetupScriptOptions =
, forceExternalSetupMethod = False
, setupCacheLock = Nothing
, isInteractive = False
, isMainLibOrExeComponent = True
}

workingDir :: SetupScriptOptions -> FilePath
Expand Down Expand Up @@ -375,7 +382,14 @@ getSetup verbosity options mpkg = do
(useCabalVersion options)
(orLaterVersion (mkVersion (cabalSpecMinimumLibraryVersion (specVersion pkg))))
}
buildType' = buildType pkg
-- We retain Configure only for the main library and executable components.
-- For other components, we rewrite the buildType to Simple to skip the
-- configure step. This is because the configure step is not supported for
-- other components. Configure can only impact MainLib and Exe through
-- .buildinfo files.
buildType' = case (buildType pkg, isMainLibOrExeComponent options) of
(Configure, False) -> Simple
(bt, _) -> bt
(version, method, options'') <-
getSetupMethod verbosity options' pkg buildType'
return
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# cabal build
Configuration is affected by the following files:
- cabal.project
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- test-pkg-0.1.0.0 (lib) (first run)
Configuring library for test-pkg-0.1.0.0...
Preprocessing library for test-pkg-0.1.0.0...
Building library for test-pkg-0.1.0.0...
# cabal v2-build
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- test-pkg-0.1.0.0 (exe:exe) (first run)
Configuring executable 'exe' for test-pkg-0.1.0.0...
Preprocessing executable 'exe' for test-pkg-0.1.0.0...
Building executable 'exe' for test-pkg-0.1.0.0...
# cabal v2-run
Configuration is affected by the following files:
- cabal.project
# cabal v2-run
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- test-pkg-0.1.0.0 (exe:exe-dep) (first run)
Configuring executable 'exe-dep' for test-pkg-0.1.0.0...
Preprocessing executable 'exe-dep' for test-pkg-0.1.0.0...
Building executable 'exe-dep' for test-pkg-0.1.0.0...
# cabal v2-build
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- test-pkg-0.1.0.0 (lib:foo) (first run)
Configuring library 'foo' for test-pkg-0.1.0.0...
Preprocessing library 'foo' for test-pkg-0.1.0.0...
Building library 'foo' for test-pkg-0.1.0.0...
# cabal v2-build
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- test-pkg-0.1.0.0 (lib:bar) (first run)
Configuring library 'bar' for test-pkg-0.1.0.0...
Preprocessing library 'bar' for test-pkg-0.1.0.0...
Building library 'bar' for test-pkg-0.1.0.0...
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: test-pkg
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Test.Cabal.Prelude
-- Test build-tool-depends between two packages
main = cabalTest $ do
-- main library, and executable should run configure and generate a
-- buildinfo file.
cabal' "build" ["test-pkg:test-pkg"] >>=
assertOutputContains "config.status: creating test-pkg.buildinfo"
cabal' "v2-build" ["test-pkg:exe"] >>=
assertOutputContains "config.status: creating test-pkg.buildinfo"
-- configure values should not be embeddable in the executable.
cabal' "v2-run" ["test-pkg:exe"] >>=
assertOutputContains "Hi-Exe"
-- configure values should be embeddable in the library.
cabal' "v2-run" ["test-pkg:exe-dep"] >>=
assertOutputContains "Hi-Lib"
-- sublibs should not run configure
cabal' "v2-build" ["test-pkg:lib:foo"] >>=
assertOutputDoesNotContain "config.status: creating test-pkg.buildinfo"
cabal' "v2-build" ["test-pkg:lib:bar"] >>=
assertOutputDoesNotContain "config.status: creating test-pkg.buildinfo"

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Revision history for test-pkg

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Copyright (c) 2025, Moritz Angermann


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Loading
Loading