Skip to content

Commit

Permalink
Apply local configuration to install targets
Browse files Browse the repository at this point in the history
The target of `cabal install` is not considered to be a local package,
which means local configuration (e.g. in cabal.project, or flags like
--enable-profiling) does not apply to it.

In 76670eb, we changed the behaviour to
applying the local flags to cabal install targets, but it used the
literal target string as a package name to which the flags were
additionally applied.

However, `cabal install` targets are NOT necessarily package names, so,
e.g., if we did `cabal install exe:mycomp`, the local flags would not
apply since "exe:mycomp" is not a recognized /package/.

The solution is to parse the target selectors first, and apply the local
flags to the package of the resolved targets.
  • Loading branch information
alt-romes committed Feb 5, 2024
1 parent 32d9319 commit 80312d7
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 9 deletions.
38 changes: 29 additions & 9 deletions cabal-install/src/Distribution/Client/CmdInstall.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}

-- | cabal-install CLI command: build
module Distribution.Client.CmdInstall
Expand Down Expand Up @@ -104,6 +105,7 @@ import Distribution.Client.Types
, PackageSpecifier (..)
, SourcePackageDb (..)
, UnresolvedSourcePackage
, pkgSpecifierTarget
)
import Distribution.Client.Types.OverwritePolicy
( OverwritePolicy (..)
Expand Down Expand Up @@ -371,7 +373,7 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt

-- First, we need to learn about what's available to be installed.
localBaseCtx <-
establishProjectBaseContext reducedVerbosity cliConfig InstallCommand
establishProjectBaseContext reducedVerbosity baseCliConfig InstallCommand
let localDistDirLayout = distDirLayout localBaseCtx
pkgDb <-
projectConfigWithBuilderRepoContext
Expand Down Expand Up @@ -432,7 +434,7 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt
withoutProject globalConfig = do
tss <- traverse (parseWithoutProjectTargetSelector verbosity) targetStrings'
let
projectConfig = globalConfig <> cliConfig
projectConfig = globalConfig <> baseCliConfig

ProjectConfigBuildOnly
{ projectConfigLogsDir
Expand Down Expand Up @@ -478,10 +480,17 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt

return (packageSpecifiers, uris, packageTargets, projectConfig)

(specs, uris, targetSelectors, config) <-
(specs, uris, targetSelectors, baseConfig) <-
withProjectOrGlobalConfig verbosity ignoreProject globalConfigFlag withProject withoutProject

-- We compute the base context again to determine packages available in the
-- project to be installed, so we can list the available package names when
-- the "all:..." variants of the target selectors are used.
localPkgs <- localPackages <$> establishProjectBaseContext verbosity baseConfig InstallCommand

let
config = addLocalConfigToPkgs baseConfig (map pkgSpecifierTarget specs ++ concatMap (targetPkgNames localPkgs) targetSelectors)

ProjectConfig
{ projectConfigBuildOnly =
ProjectConfigBuildOnly
Expand Down Expand Up @@ -631,8 +640,7 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt
globalFlags
flags{configFlags = configFlags'}
clientInstallFlags'
cliConfig = addLocalConfigToTargets baseCliConfig targetStrings
globalConfigFlag = projectConfigConfigFile (projectConfigShared cliConfig)
globalConfigFlag = projectConfigConfigFile (projectConfigShared baseCliConfig)

-- Do the install action for each executable in the install configuration.
traverseInstall :: InstallAction -> InstallCfg -> IO ()
Expand All @@ -641,17 +649,29 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt
actionOnExe <- action v overwritePolicy <$> prepareExeInstall cfg
traverse_ actionOnExe . Map.toList $ targetsMap buildCtx

-- | Treat all direct targets of install command as local packages: #8637
addLocalConfigToTargets :: ProjectConfig -> [String] -> ProjectConfig
addLocalConfigToTargets config targetStrings =
-- | Treat all direct targets of install command as local packages: #8637 and later #7297, #8909, #7236.
addLocalConfigToPkgs :: ProjectConfig -> [PackageName] -> ProjectConfig
addLocalConfigToPkgs config pkgs =
config
{ projectConfigSpecificPackage =
projectConfigSpecificPackage config
<> MapMappend (Map.fromList targetPackageConfigs)
}
where
localConfig = projectConfigLocalPackages config
targetPackageConfigs = map (\x -> (mkPackageName x, localConfig)) targetStrings
targetPackageConfigs = map (,localConfig) pkgs

targetPkgNames
:: [PackageSpecifier UnresolvedSourcePackage]
-- ^ The local packages, to resolve 'TargetAllPackages' selectors
-> TargetSelector
-> [PackageName]
targetPkgNames localPkgs = \case
TargetPackage _ pkgIds _ -> map pkgName pkgIds
TargetPackageNamed name _ -> [name]
TargetAllPackages _ -> map pkgSpecifierTarget localPkgs
TargetComponent pkgId _ -> [pkgName pkgId]
TargetComponentUnknown name _ -> [name]

-- | Verify that invalid config options were not passed to the install command.
--
Expand Down
5 changes: 5 additions & 0 deletions cabal-testsuite/PackageTests/Install/T7297-8909-7236/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{-# LANGUAGE CPP #-}

#ifdef HELLO
main = putStrLn "hi"
#endif
44 changes: 44 additions & 0 deletions cabal-testsuite/PackageTests/Install/T7297-8909-7236/cabal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- t7297-89097236a-1.0 (exe:my-exe) (requires build)
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Configuring t7297-89097236a-1.0...
Preprocessing executable 'my-exe' for t7297-89097236a-1.0...
Building executable 'my-exe' for t7297-89097236a-1.0...
Installing executable my-exe in <PATH>
Warning: The directory <ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/incoming/new-<RAND><ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/<PACKAGE>-<HASH>/bin is not in the system search path.
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
# cabal install
Wrote tarball sdist to <ROOT>/cabal.dist/work/./dist/sdist/t7297-89097236a-1.0.tar.gz
Resolving dependencies...
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Warning: installdir is not defined. Set it in your cabal config file or use --installdir=<path>. Using default installdir: "<ROOT>/cabal.dist/home/.cabal/bin"
Symlinking 'my-exe' to '<ROOT>/cabal.dist/home/.cabal/bin/my-exe'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: .
12 changes: 12 additions & 0 deletions cabal-testsuite/PackageTests/Install/T7297-8909-7236/cabal.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Test.Cabal.Prelude

main = cabalTest $ do
let commonOpts = ["--ghc-options=-DHELLO", "--overwrite-policy=always"]
installWithTgt tgt = cabal "install" (tgt:commonOpts)

cabal "install" commonOpts -- no target
installWithTgt "t7297-89097236a"
installWithTgt "exe:my-exe"
installWithTgt "my-exe"
installWithTgt "all"
installWithTgt "all:exes"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: t7297-89097236a
version: 1.0
build-type: Simple
cabal-version: >= 1.2

executable my-exe
main-is: Main.hs
build-depends: base

0 comments on commit 80312d7

Please sign in to comment.