Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ md5CheckGenericPackageDescription proxy = md5Check proxy

md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion
md5CheckLocalBuildInfo proxy = md5Check proxy
0xd9542841ab7584d348aa142053fe934f
0xa7235f257a140c5d1af756c4c81f4aed
3 changes: 2 additions & 1 deletion Cabal/src/Distribution/Simple/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ buildComponent
lib'
lbi
clbi
Nothing
debug verbosity $ "Registering inplace:\n" ++ IPI.showInstalledPackageInfo installedPkgInfo
registerPackage
verbosity
Expand Down Expand Up @@ -860,7 +861,7 @@ testSuiteLibV09AsLibAndExe
, testSuites = []
, subLibraries = [lib]
}
ipi = inplaceInstalledPackageInfo inplaceDir distPref pkg (mkAbiHash "") lib lbi libClbi
ipi = inplaceInstalledPackageInfo inplaceDir distPref pkg (mkAbiHash "") lib lbi libClbi Nothing
testLibDep =
Dependency
pkgName'
Expand Down
1 change: 1 addition & 0 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ buildOptionsFromConfigFlags verbosity cfg comp = do
, exeCoverage = False
, libCoverage = False
, relocatable = fromFlagOrDefault False $ configRelocatable cfg
, relativeBuildTree = fromFlagOrDefault False $ configRelativeBuildTree cfg
, programPrefix = flagToMaybe $ configProgPrefix cfg
, programSuffix = flagToMaybe $ configProgSuffix cfg
}
Expand Down
1 change: 1 addition & 0 deletions Cabal/src/Distribution/Simple/Haddock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ haddock_setupHooks
lib
lbi'
clbi
Nothing

debug verbosity $
"Registering inplace:\n"
Expand Down
69 changes: 48 additions & 21 deletions Cabal/src/Distribution/Simple/Register.hs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ generateOne verbHandles pkg lib lbi clbi regFlags =
clbi
inplace
reloc
relBuildTree
distPref
(registrationPackageDB absPackageDBs)
info verbosity (IPI.showInstalledPackageInfo installedPkgInfo)
Expand All @@ -159,6 +160,7 @@ generateOne verbHandles pkg lib lbi clbi regFlags =
common = registerCommonFlags regFlags
inplace = fromFlag (regInPlace regFlags)
reloc = relocatable lbi
relBuildTree = relativeBuildTree lbi
-- FIXME: there's really no guarantee this will work.
-- registering into a totally different db stack can
-- fail if dependencies cannot be satisfied.
Expand Down Expand Up @@ -270,17 +272,29 @@ generateRegistrationInfo
-> ComponentLocalBuildInfo
-> Bool
-> Bool
-> Bool
-- ^ Relocatable build tree
-> SymbolicPath Pkg (Dir Dist)
-> PackageDB
-> IO InstalledPackageInfo
generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packageDb = do
generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc relBuildTree distPref packageDb = do
inplaceDir <- absoluteWorkingDirLBI lbi
installedPkgInfo <-
if inplace
then -- NB: With an inplace installation, the user may run './Setup
-- build' to update the library files, without reregistering.
-- In this case, it is critical that the ABI hash not flip.

then do
-- NB: With an inplace installation, the user may run './Setup
-- build' to update the library files, without reregistering.
-- In this case, it is critical that the ABI hash not flip.

-- When a relative build tree is requested, emit ${pkgroot}-relative
-- paths (relative to the directory containing the package db) so that
-- the dist tree can be copied/relocated without invalidating the
-- registration. Only GHC understands the ${pkgroot} substitution, so
-- for other compilers we fall back to absolute paths.
maybePkgRoot <-
if relBuildTree && compilerFlavor (compiler lbi) == GHC
then Just <$> GHC.pkgRoot verbosity lbi packageDb
else return Nothing
return
( inplaceInstalledPackageInfo
inplaceDir
Expand All @@ -290,6 +304,7 @@ generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packa
lib
lbi
clbi
maybePkgRoot
)
else do
abi_hash <- abiHash verbosity pkg distPref lbi lib clbi
Expand Down Expand Up @@ -621,8 +636,13 @@ inplaceInstalledPackageInfo
-> Library
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> Maybe (SymbolicPath CWD (Dir Pkg))
-- ^ If @Just pkgroot@, emit paths relative to @pkgroot@ using the
-- @${pkgroot}@ substitution variable (for relocatable inplace builds).
-- @pkgroot@ is the directory containing the package database (see
-- 'Distribution.Simple.GHC.pkgRoot'). If @Nothing@, emit absolute paths.
-> InstalledPackageInfo
inplaceInstalledPackageInfo inplaceDir distPref pkg abi_hash lib lbi clbi =
inplaceInstalledPackageInfo inplaceDir distPref pkg abi_hash lib lbi clbi mb_pkgroot =
generalInstalledPackageInfo
adjustRelativeIncludeDirs
pkg
Expand All @@ -633,25 +653,32 @@ inplaceInstalledPackageInfo inplaceDir distPref pkg abi_hash lib lbi clbi =
installDirs
where
i = interpretSymbolicPathAbsolute inplaceDir -- See Note [Symbolic paths] in Distribution.Utils.Path
-- Make an absolute path relative to ${pkgroot} when a relocatable build
-- was requested; otherwise leave it absolute.
relocate :: FilePath -> FilePath
relocate = case mb_pkgroot of
Nothing -> id
Just pkgroot -> ("${pkgroot}" </>) . shortRelativePath (getSymbolicPath pkgroot)
adjustRelativeIncludeDirs = concatMap $ \d ->
[ i $ makeRelativePathEx d -- local include-dir
, i $ libTargetDir </> makeRelativePathEx d -- autogen include-dir
[ relocate $ i $ makeRelativePathEx d -- local include-dir
, relocate $ i $ libTargetDir </> makeRelativePathEx d -- autogen include-dir
]
libTargetDir = componentBuildDir lbi clbi
installDirs =
(absoluteComponentInstallDirs pkg lbi (componentUnitId clbi) NoCopyDest)
{ libdir = i libTargetDir
, dynlibdir = i libTargetDir
, bytecodelibdir = i libTargetDir
, datadir =
let rawDataDir = dataDir pkg
in if null $ getSymbolicPath rawDataDir
then i sameDirectory
else i rawDataDir
, docdir = i inplaceDocdir
, htmldir = inplaceHtmldir
, haddockdir = inplaceHtmldir
}
fmap relocate $
(absoluteComponentInstallDirs pkg lbi (componentUnitId clbi) NoCopyDest)
{ libdir = i libTargetDir
, dynlibdir = i libTargetDir
, bytecodelibdir = i libTargetDir
, datadir =
let rawDataDir = dataDir pkg
in if null $ getSymbolicPath rawDataDir
then i sameDirectory
else i rawDataDir
, docdir = i inplaceDocdir
, htmldir = inplaceHtmldir
, haddockdir = inplaceHtmldir
}
inplaceDocdir = distPref </> makeRelativePathEx "doc"
inplaceHtmldir =
i $
Expand Down
11 changes: 11 additions & 0 deletions Cabal/src/Distribution/Simple/Setup/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ data ConfigFlags = ConfigFlags
-- ^ Halt and show an error message indicating an error in flag assignment
, configRelocatable :: Flag Bool
-- ^ Enable relocatable package built
, configRelativeBuildTree :: Flag Bool
-- ^ Make the build tree relocatable
, configDebugInfo :: Flag DebugInfoLevel
-- ^ Emit debug info.
, configDumpBuildInfo :: Flag DumpBuildInfo
Expand Down Expand Up @@ -320,6 +322,7 @@ instance Eq ConfigFlags where
&& equal configExactConfiguration
&& equal configFlagError
&& equal configRelocatable
&& equal configRelativeBuildTree
&& equal configDebugInfo
&& equal configDumpBuildInfo
&& equal configUseResponseFiles
Expand Down Expand Up @@ -368,6 +371,7 @@ defaultConfigFlags progDb =
, configExactConfiguration = Flag False
, configFlagError = NoFlag
, configRelocatable = Flag False
, configRelativeBuildTree = Flag False
, configDebugInfo = Flag NoDebugInfo
, configDumpBuildInfo = NoFlag
, configUseResponseFiles = NoFlag
Expand Down Expand Up @@ -838,6 +842,13 @@ configureOptions showOrParseArgs =
configRelocatable
(\v flags -> flags{configRelocatable = v})
(boolOpt [] [])
, option
""
["relative-build-tree"]
"recording project-local paths relative to the build tree root, so the build tree can be relocated. (GHC only)"
configRelativeBuildTree
(\v flags -> flags{configRelativeBuildTree = v})
(boolOpt' ([], ["relative-build-tree"]) ([], ["no-relative-build-tree"]))
, option
""
["response-files"]
Expand Down
3 changes: 3 additions & 0 deletions Cabal/src/Distribution/Types/LocalBuildConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ data BuildOptions = BuildOptions
-- ^ Whether to enable library program coverage
, relocatable :: Bool
-- ^ Whether to build a relocatable package
, relativeBuildTree :: Bool
-- ^ Whether to make the build tree relocatable
, programPrefix :: Maybe PathTemplate
-- ^ Installed executable prefix
, programSuffix :: Maybe PathTemplate
Expand Down Expand Up @@ -224,6 +226,7 @@ buildOptionsConfigFlags (BuildOptions{..}) =
, configCoverage = toFlag exeCoverage
, configLibCoverage = mempty
, configRelocatable = toFlag relocatable
, configRelativeBuildTree = toFlag relativeBuildTree
, configOptimization = toFlag withOptimization
, configSplitSections = toFlag splitSections
, configSplitObjs = toFlag splitObjs
Expand Down
4 changes: 4 additions & 0 deletions Cabal/src/Distribution/Types/LocalBuildInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Distribution.Types.LocalBuildInfo
, libCoverage
, extraCoverageFor
, relocatable
, relativeBuildTree
, programPrefix
, programSuffix
, ..
Expand Down Expand Up @@ -186,6 +187,7 @@ pattern LocalBuildInfo
-> Bool
-> [UnitId]
-> Bool
-> Bool
-> Maybe PathTemplate
-> Maybe PathTemplate
-> LocalBuildInfo
Expand Down Expand Up @@ -227,6 +229,7 @@ pattern LocalBuildInfo
, libCoverage
, extraCoverageFor
, relocatable
, relativeBuildTree
, programPrefix
, programSuffix
} =
Expand Down Expand Up @@ -281,6 +284,7 @@ pattern LocalBuildInfo
, exeCoverage
, libCoverage
, relocatable
, relativeBuildTree
, programPrefix
, programSuffix
}
Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ instance Semigroup SavedConfig where
, configExactConfiguration = combine configExactConfiguration
, configFlagError = combine configFlagError
, configRelocatable = combine configRelocatable
, configRelativeBuildTree = combine configRelativeBuildTree
, configUseResponseFiles = combine configUseResponseFiles
, configDumpBuildInfo = combine configDumpBuildInfo
, configAllowDependingOnPrivateLibs =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ import Distribution.Client.Types hiding
)

import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import Distribution.Simple.Compiler (PackageDBX (..))
import Distribution.Simple.LocalBuildInfo
( ComponentName (..)
)
import Distribution.Simple.Utils (removeFileForcibly)
import Distribution.Simple.Utils (removeFileForcibly, shortRelativePath)
import qualified Distribution.Types.LocalBuildConfig as LBC

import qualified Data.Map as Map
import qualified Data.Set as Set

import System.FilePath (isAbsolute, normalise)

-----------------------------
-- Package change detection
--
Expand Down Expand Up @@ -60,13 +65,17 @@ newPackageFileMonitor
-> PackageFileMonitor
newPackageFileMonitor
shared
DistDirLayout{distPackageCacheFile}
DistDirLayout{distPackageCacheFile, distDirectory}
dparams =
PackageFileMonitor
{ pkgFileMonitorConfig =
FileMonitor
{ fileMonitorCacheFile = distPackageCacheFile dparams "config"
, fileMonitorKeyValid = (==) `on` normaliseConfiguredPackage shared
, -- #12137: The config monitor key is compared after relativising
-- project-local paths, so that relocating the whole tree
-- does not spuriously invalidate it.
fileMonitorKeyValid =
(==) `on` (relativiseElabConfigPaths distDirectory . normaliseConfiguredPackage shared)
, fileMonitorCheckIfOnlyValueChanged = False
}
, pkgFileMonitorBuild =
Expand All @@ -80,6 +89,47 @@ newPackageFileMonitor
newFileMonitor (distPackageCacheFile dparams "registration")
}

-- | Rewrite the absolute paths in an 'ElaboratedConfiguredPackage' that live
-- under the build tree root so that they become relative to it. This makes the
-- package-configuration file monitor /key/ location-independent.
relativiseElabConfigPaths :: FilePath -> ElaboratedConfiguredPackage -> ElaboratedConfiguredPackage
relativiseElabConfigPaths buildDir elab =
elab
{ elabPkgSourceLocation = relLocation (elabPkgSourceLocation elab)
, elabPackageDbs = map (fmap relDB) (elabPackageDbs elab)
, elabSetupPackageDBStack = map relDB (elabSetupPackageDBStack elab)
, elabBuildPackageDBStack = map relDB (elabBuildPackageDBStack elab)
, elabRegisterPackageDBStack = map relDB (elabRegisterPackageDBStack elab)
, elabInplaceSetupPackageDBStack = map relDB (elabInplaceSetupPackageDBStack elab)
, elabInplaceBuildPackageDBStack = map relDB (elabInplaceBuildPackageDBStack elab)
, elabInplaceRegisterPackageDBStack = map relDB (elabInplaceRegisterPackageDBStack elab)
, elabInstallDirs = fmap rel (elabInstallDirs elab)
, elabExtraLibDirs = map rel (elabExtraLibDirs elab)
, elabExtraLibDirsStatic = map rel (elabExtraLibDirsStatic elab)
, elabExtraFrameworkDirs = map rel (elabExtraFrameworkDirs elab)
, elabExtraIncludeDirs = map rel (elabExtraIncludeDirs elab)
, elabProgramPaths = Map.map rel (elabProgramPaths elab)
, elabProgramPathExtra = map rel (elabProgramPathExtra elab)
, elabHaddockCss = fmap rel (elabHaddockCss elab)
, elabHaddockHscolourCss = fmap rel (elabHaddockHscolourCss elab)
, elabHaddockOutputDir = fmap rel (elabHaddockOutputDir elab)
, elabTestWrapper = fmap rel (elabTestWrapper elab)
}
where
rel :: FilePath -> FilePath
rel p
| isAbsolute p = shortRelativePath (normalise buildDir) (normalise p)
| otherwise = p

relDB :: PackageDBX FilePath -> PackageDBX FilePath
relDB (SpecificPackageDB fp) = SpecificPackageDB (rel fp)
relDB db = db

relLocation :: PackageLocation (Maybe FilePath) -> PackageLocation (Maybe FilePath)
relLocation (LocalUnpackedPackage fp) = LocalUnpackedPackage (rel fp)
relLocation (LocalTarballPackage fp) = LocalTarballPackage (rel fp)
relLocation loc = loc

-- | Helper function for 'checkPackageFileMonitorChanged',
-- 'updatePackageConfigFileMonitor' and 'updatePackageBuildFileMonitor'.
--
Expand Down Expand Up @@ -119,6 +169,9 @@ packageFileMonitorKeyValues elab =
, elabTestKeepTix = False
, elabTestTestOptions = []
, elabBenchmarkOptions = []
, -- Whether a relative build tree was requested only affects how paths
-- are recorded in generated metadata, not what is compiled, so null it here.
elabBuildOptions = (elabBuildOptions elab){LBC.relativeBuildTree = False}
}

-- The second part is the value used to guard the build step. So this is
Expand Down Expand Up @@ -209,11 +262,14 @@ checkPackageFileMonitorChanged
changedToMaybe (MonitorUnchanged x _) = Just x

updatePackageConfigFileMonitor
:: PackageFileMonitor
:: FilePath
-- ^ The build directory
-> PackageFileMonitor
-> FilePath
-> ElaboratedConfiguredPackage
-> IO ()
updatePackageConfigFileMonitor
buildDir
PackageFileMonitor{pkgFileMonitorConfig}
srcdir
pkg =
Expand All @@ -222,7 +278,7 @@ updatePackageConfigFileMonitor
srcdir
Nothing
[]
pkgconfig
(relativiseElabConfigPaths buildDir pkgconfig)
()
where
(pkgconfig, _buildComponents) = packageFileMonitorKeyValues pkg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,11 @@ buildInplaceUnpackedPackage
whenReconfigure $ do
mbLBI <- runConfigure
invalidatePackageRegFileMonitor packageFileMonitor
updatePackageConfigFileMonitor packageFileMonitor (getSymbolicPath srcdir) pkg
updatePackageConfigFileMonitor
distDirectory
packageFileMonitor
(getSymbolicPath srcdir)
pkg
return mbLBI
PBBuildPhase{runBuild} ->
whenRebuild $ withFileMonitor runBuild
Expand Down
Loading