Skip to content

Commit 8bb538f

Browse files
committed
Per-component cabal_macros.h (haskell#1893) and install paths
This commit is a number of refactorings that I needed to do while fixing bugs with internal libraries support. - With internal libraries, it becomes especially clear that cabal_macros.h and Paths_foo.hs need to be done per-component. It is done! This change breaks BC in an important way: the preprocessor interface now takes a ComponentLocalBuildInfo along with the BuildInfo and LocalBuildInfo. This means that if you implemented a custom preprocessor, or called 'preprocessComponent' in a custom Setup, you will have to make sure you pass the right ComponentLocalBuildInfo. Some sub-notes: - While I was mucking about cabal_macros.h, I updated it to have two new macros: CURRENT_COMPONENT_ID (an alias for CURRENT_PACKAGE_KEY, but using modern terminology) and LOCAL_COMPONENT_ID (which refers to the public library; we use this in Cabal's test suite but it's unclear what the general utility of this is. See the TODO.) - checkForeignDeps has a hack where we hardcode the cabal_macros.h of the main library. If we did the foreign dep check for every component individually that would be better, but I didn't want to roll it into this patch. - The other piece I needed for internal libraries was per-component install directories; otherwise, internal libraries clobber each other. absoluteInstallDirs now takes a ComponentId, which is used to determine what '$libname' expands to. Generally, InstallPaths must be computed per component, c.f. haskell#2836. We're not TRULY per-component install paths, since some files are installed for the "per-package" InstallPaths (the one we computed for the library as a whole), but for libraries we have to compute InstallPaths for each one. - While doing this, ComponentLocalBuildInfo grew a new 'componentId' field for non-library things. This lets us treat InstallPaths expansion uniformly. Signed-off-by: Edward Z. Yang <[email protected]>
1 parent 86cba88 commit 8bb538f

File tree

18 files changed

+262
-215
lines changed

18 files changed

+262
-215
lines changed

Cabal/Distribution/Simple/Build.hs

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,22 @@ build pkg_descr lbi flags suffixes = do
8787
info verbosity $ "Component build order: "
8888
++ intercalate ", " (map showComponentName componentsToBuild)
8989

90-
initialBuildSteps distPref pkg_descr lbi verbosity
9190
when (null targets) $
9291
-- Only bother with this message if we're building the whole package
9392
setupMessage verbosity "Building" (packageId pkg_descr)
9493

9594
internalPackageDB <- createInternalPackageDB verbosity lbi distPref
9695

97-
withComponentsInBuildOrder pkg_descr lbi componentsToBuild $ \comp clbi ->
96+
withComponentsInBuildOrder pkg_descr lbi componentsToBuild $ \comp clbi -> do
97+
initialBuildSteps distPref pkg_descr lbi clbi verbosity
9898
let bi = componentBuildInfo comp
9999
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
100100
lbi' = lbi {
101101
withPrograms = progs',
102102
withPackageDB = withPackageDB lbi ++ [internalPackageDB]
103103
}
104-
in buildComponent verbosity (buildNumJobs flags) pkg_descr
105-
lbi' suffixes comp clbi distPref
104+
buildComponent verbosity (buildNumJobs flags) pkg_descr
105+
lbi' suffixes comp clbi distPref
106106

107107

108108
repl :: PackageDescription -- ^ Mostly information from the .cabal file
@@ -127,8 +127,6 @@ repl pkg_descr lbi flags suffixes args = do
127127
++ intercalate ", "
128128
[ showComponentName c | (c,_) <- componentsToBuild ]
129129

130-
initialBuildSteps distPref pkg_descr lbi verbosity
131-
132130
internalPackageDB <- createInternalPackageDB verbosity lbi distPref
133131

134132
let lbiForComponent comp lbi' =
@@ -140,17 +138,19 @@ repl pkg_descr lbi flags suffixes args = do
140138

141139
-- build any dependent components
142140
sequence_
143-
[ let comp = getComponent pkg_descr cname
144-
lbi' = lbiForComponent comp lbi
145-
in buildComponent verbosity NoFlag
146-
pkg_descr lbi' suffixes comp clbi distPref
141+
[ do let comp = getComponent pkg_descr cname
142+
lbi' = lbiForComponent comp lbi
143+
initialBuildSteps distPref pkg_descr lbi clbi verbosity
144+
buildComponent verbosity NoFlag
145+
pkg_descr lbi' suffixes comp clbi distPref
147146
| (cname, clbi) <- init componentsToBuild ]
148147

149148
-- REPL for target components
150149
let (cname, clbi) = componentForRepl
151150
comp = getComponent pkg_descr cname
152151
lbi' = lbiForComponent comp lbi
153-
in replComponent verbosity pkg_descr lbi' suffixes comp clbi distPref
152+
initialBuildSteps distPref pkg_descr lbi clbi verbosity
153+
replComponent verbosity pkg_descr lbi' suffixes comp clbi distPref
154154

155155

156156
-- | Start an interpreter without loading any package files.
@@ -173,7 +173,7 @@ buildComponent :: Verbosity
173173
-> IO ()
174174
buildComponent verbosity numJobs pkg_descr lbi suffixes
175175
comp@(CLib lib) clbi distPref = do
176-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
176+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
177177
extras <- preprocessExtras comp lbi
178178
info verbosity $ "Building library " ++ libName lib ++ "..."
179179
let libbi = libBuildInfo lib
@@ -192,7 +192,7 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
192192

193193
buildComponent verbosity numJobs pkg_descr lbi suffixes
194194
comp@(CExe exe) clbi _ = do
195-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
195+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
196196
extras <- preprocessExtras comp lbi
197197
info verbosity $ "Building executable " ++ exeName exe ++ "..."
198198
let ebi = buildInfo exe
@@ -204,7 +204,7 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
204204
comp@(CTest test@TestSuite { testInterface = TestSuiteExeV10{} })
205205
clbi _distPref = do
206206
let exe = testSuiteExeV10AsExe test
207-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
207+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
208208
extras <- preprocessExtras comp lbi
209209
info verbosity $ "Building test suite " ++ testName test ++ "..."
210210
let ebi = buildInfo exe
@@ -224,7 +224,7 @@ buildComponent verbosity numJobs pkg_descr lbi0 suffixes
224224
pwd <- getCurrentDirectory
225225
let (pkg, lib, libClbi, lbi, ipi, exe, exeClbi) =
226226
testSuiteLibV09AsLibAndExe pkg_descr test clbi lbi0 distPref pwd
227-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
227+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
228228
extras <- preprocessExtras comp lbi
229229
info verbosity $ "Building test suite " ++ testName test ++ "..."
230230
buildLib verbosity numJobs pkg lbi lib libClbi
@@ -248,7 +248,7 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
248248
comp@(CBench bm@Benchmark { benchmarkInterface = BenchmarkExeV10 {} })
249249
clbi _ = do
250250
let (exe, exeClbi) = benchmarkExeV10asExe bm clbi
251-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
251+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
252252
extras <- preprocessExtras comp lbi
253253
info verbosity $ "Building benchmark " ++ benchmarkName bm ++ "..."
254254
let ebi = buildInfo exe
@@ -281,15 +281,15 @@ replComponent :: Verbosity
281281
-> IO ()
282282
replComponent verbosity pkg_descr lbi suffixes
283283
comp@(CLib lib) clbi _ = do
284-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
284+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
285285
extras <- preprocessExtras comp lbi
286286
let libbi = libBuildInfo lib
287287
lib' = lib { libBuildInfo = libbi { cSources = cSources libbi ++ extras } }
288288
replLib verbosity pkg_descr lbi lib' clbi
289289

290290
replComponent verbosity pkg_descr lbi suffixes
291291
comp@(CExe exe) clbi _ = do
292-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
292+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
293293
extras <- preprocessExtras comp lbi
294294
let ebi = buildInfo exe
295295
exe' = exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
@@ -300,7 +300,7 @@ replComponent verbosity pkg_descr lbi suffixes
300300
comp@(CTest test@TestSuite { testInterface = TestSuiteExeV10{} })
301301
clbi _distPref = do
302302
let exe = testSuiteExeV10AsExe test
303-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
303+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
304304
extras <- preprocessExtras comp lbi
305305
let ebi = buildInfo exe
306306
exe' = exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
@@ -314,7 +314,7 @@ replComponent verbosity pkg_descr lbi0 suffixes
314314
pwd <- getCurrentDirectory
315315
let (pkg, lib, libClbi, lbi, _, _, _) =
316316
testSuiteLibV09AsLibAndExe pkg_descr test clbi lbi0 distPref pwd
317-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
317+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
318318
extras <- preprocessExtras comp lbi
319319
let libbi = libBuildInfo lib
320320
lib' = lib { libBuildInfo = libbi { cSources = cSources libbi ++ extras } }
@@ -331,7 +331,7 @@ replComponent verbosity pkg_descr lbi suffixes
331331
comp@(CBench bm@Benchmark { benchmarkInterface = BenchmarkExeV10 {} })
332332
clbi _ = do
333333
let (exe, exeClbi) = benchmarkExeV10asExe bm clbi
334-
preprocessComponent pkg_descr comp lbi False verbosity suffixes
334+
preprocessComponent pkg_descr comp lbi clbi False verbosity suffixes
335335
extras <- preprocessExtras comp lbi
336336
let ebi = buildInfo exe
337337
exe' = exe { buildInfo = ebi { cSources = cSources ebi ++ extras } }
@@ -384,21 +384,13 @@ testSuiteLibV09AsLibAndExe pkg_descr
384384
libExposed = True,
385385
libBuildInfo = bi
386386
}
387-
-- NB: temporary hack; I have a refactor which solves this
388-
cid = computeComponentId NoFlag
389-
(package pkg_descr)
390-
(CTestName (testName test))
391-
(map ((\(SimpleUnitId cid0) -> cid0) . fst)
392-
(componentPackageDeps clbi))
393-
(flagAssignment lbi)
394-
uid = SimpleUnitId cid
395387
(compat_name, compat_key) = computeCompatPackageKey
396388
(compiler lbi) (package pkg_descr)
397-
(CTestName (testName test)) uid
389+
(CTestName (testName test)) (componentUnitId clbi)
398390
libClbi = LibComponentLocalBuildInfo
399391
{ componentPackageDeps = componentPackageDeps clbi
400392
, componentPackageRenaming = componentPackageRenaming clbi
401-
, componentUnitId = uid
393+
, componentUnitId = componentUnitId clbi
402394
, componentCompatPackageName = compat_name
403395
, componentCompatPackageKey = compat_key
404396
, componentExposedModules = [IPI.ExposedModule m Nothing]
@@ -427,6 +419,9 @@ testSuiteLibV09AsLibAndExe pkg_descr
427419
-- | The stub executable needs a new 'ComponentLocalBuildInfo'
428420
-- that exposes the relevant test suite library.
429421
exeClbi = ExeComponentLocalBuildInfo {
422+
-- TODO: this is a hack, but as long as this is unique
423+
-- (doesn't clobber something) we won't run into trouble
424+
componentUnitId = mkUnitId (stubName test),
430425
componentPackageDeps =
431426
(IPI.installedUnitId ipi, packageId ipi)
432427
: (filter (\(_, x) -> let PackageName name = pkgName x
@@ -450,6 +445,7 @@ benchmarkExeV10asExe bm@Benchmark { benchmarkInterface = BenchmarkExeV10 _ f }
450445
buildInfo = benchmarkBuildInfo bm
451446
}
452447
exeClbi = ExeComponentLocalBuildInfo {
448+
componentUnitId = componentUnitId clbi,
453449
componentPackageDeps = componentPackageDeps clbi,
454450
componentPackageRenaming = componentPackageRenaming clbi
455451
}
@@ -534,9 +530,10 @@ replExe verbosity pkg_descr lbi exe clbi =
534530
initialBuildSteps :: FilePath -- ^"dist" prefix
535531
-> PackageDescription -- ^mostly information from the .cabal file
536532
-> LocalBuildInfo -- ^Configuration information
533+
-> ComponentLocalBuildInfo
537534
-> Verbosity -- ^The verbosity to use
538535
-> IO ()
539-
initialBuildSteps _distPref pkg_descr lbi verbosity = do
536+
initialBuildSteps _distPref pkg_descr lbi clbi verbosity = do
540537
-- check that there's something to build
541538
unless (not . null $ allBuildInfo pkg_descr) $ do
542539
let name = display (packageId pkg_descr)
@@ -545,23 +542,24 @@ initialBuildSteps _distPref pkg_descr lbi verbosity = do
545542

546543
createDirectoryIfMissingVerbose verbosity True (buildDir lbi)
547544

548-
writeAutogenFiles verbosity pkg_descr lbi
545+
writeAutogenFiles verbosity pkg_descr lbi clbi
549546

550547
-- | Generate and write out the Paths_<pkg>.hs and cabal_macros.h files
551548
--
552549
writeAutogenFiles :: Verbosity
553550
-> PackageDescription
554551
-> LocalBuildInfo
552+
-> ComponentLocalBuildInfo
555553
-> IO ()
556-
writeAutogenFiles verbosity pkg lbi = do
557-
createDirectoryIfMissingVerbose verbosity True (autogenModulesDir lbi)
554+
writeAutogenFiles verbosity pkg lbi clbi = do
555+
createDirectoryIfMissingVerbose verbosity True (autogenModulesDir lbi clbi)
558556

559-
let pathsModulePath = autogenModulesDir lbi
557+
let pathsModulePath = autogenModulesDir lbi clbi
560558
</> ModuleName.toFilePath (autogenModuleName pkg) <.> "hs"
561-
rewriteFile pathsModulePath (Build.PathsModule.generate pkg lbi)
559+
rewriteFile pathsModulePath (Build.PathsModule.generate pkg lbi clbi)
562560

563-
let cppHeaderPath = autogenModulesDir lbi </> cppHeaderName
564-
rewriteFile cppHeaderPath (Build.Macros.generate pkg lbi)
561+
let cppHeaderPath = autogenModulesDir lbi clbi </> cppHeaderName
562+
rewriteFile cppHeaderPath (Build.Macros.generate pkg lbi clbi)
565563

566564
-- | Check that the given build targets are valid in the current context.
567565
--

Cabal/Distribution/Simple/Build/Macros.hs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,30 @@ module Distribution.Simple.Build.Macros (
2222
generatePackageVersionMacros,
2323
) where
2424

25-
import Data.Maybe
26-
( isJust )
2725
import Distribution.Package
28-
( PackageIdentifier(PackageIdentifier) )
2926
import Distribution.Version
30-
( Version(versionBranch) )
3127
import Distribution.PackageDescription
32-
( PackageDescription )
28+
import Distribution.Simple.Compiler
3329
import Distribution.Simple.LocalBuildInfo
34-
( LocalBuildInfo(withPrograms), externalPackageDeps
35-
, localComponentId, localCompatPackageKey )
3630
import Distribution.Simple.Program.Db
37-
( configuredPrograms )
3831
import Distribution.Simple.Program.Types
39-
( ConfiguredProgram(programId, programVersion) )
4032
import Distribution.Text
41-
( display )
33+
34+
import Data.Maybe
35+
( isJust )
4236

4337
-- ------------------------------------------------------------
4438
-- * Generate cabal_macros.h
4539
-- ------------------------------------------------------------
4640

4741
-- | The contents of the @cabal_macros.h@ for the given configured package.
4842
--
49-
generate :: PackageDescription -> LocalBuildInfo -> String
50-
generate _pkg_descr lbi =
43+
generate :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
44+
generate _pkg_descr lbi clbi =
5145
"/* DO NOT EDIT: This file is automatically generated by Cabal */\n\n" ++
52-
generatePackageVersionMacros (map snd (externalPackageDeps lbi)) ++
46+
generatePackageVersionMacros (map snd (componentPackageDeps clbi)) ++
5347
generateToolVersionMacros (configuredPrograms . withPrograms $ lbi) ++
54-
generateComponentIdMacro lbi
48+
generateComponentIdMacro lbi clbi
5549

5650
-- | Helper function that generates just the @VERSION_pkg@ and @MIN_VERSION_pkg@
5751
-- macros for a list of package ids (usually used with the specific deps of
@@ -83,10 +77,10 @@ generateToolVersionMacros progs = concat
8377
-- 'generateToolVersionMacros'.
8478
--
8579
generateMacros :: String -> String -> Version -> String
86-
generateMacros prefix name version =
80+
generateMacros macro_prefix name version =
8781
concat
88-
["#define ", prefix, "VERSION_",name," ",show (display version),"\n"
89-
,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n"
82+
["#define ", macro_prefix, "VERSION_",name," ",show (display version),"\n"
83+
,"#define MIN_", macro_prefix, "VERSION_",name,"(major1,major2,minor) (\\\n"
9084
," (major1) < ",major1," || \\\n"
9185
," (major1) == ",major1," && (major2) < ",major2," || \\\n"
9286
," (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")"
@@ -95,14 +89,21 @@ generateMacros prefix name version =
9589
where
9690
(major1:major2:minor:_) = map show (versionBranch version ++ repeat 0)
9791

98-
-- | Generate the @CURRENT_COMPONENT_ID@ definition for the component ID
99-
-- of the current package.
100-
generateComponentIdMacro :: LocalBuildInfo -> String
101-
generateComponentIdMacro lbi =
102-
concat
103-
[ "#define CURRENT_COMPONENT_ID \"" ++ display (localComponentId lbi) ++ "\"\n\n"
104-
, "#define CURRENT_PACKAGE_KEY \"" ++ localCompatPackageKey lbi ++ "\"\n\n"
105-
]
92+
-- | Generate the @CURRENT_PACKAGE_KEY@ definition for the package key
93+
-- of the current package, if supported by the compiler.
94+
-- NB: this only makes sense for definite packages.
95+
generateComponentIdMacro :: LocalBuildInfo -> ComponentLocalBuildInfo -> String
96+
generateComponentIdMacro lbi clbi
97+
| packageKeySupported (compiler lbi) =
98+
concat
99+
-- Has to be the local one, since it's not guaranteed to be
100+
-- present for non-libraries (TODO: maybe we should store those?)
101+
["#define CURRENT_PACKAGE_KEY \"" ++ localCompatPackageKey lbi ++ "\"\n"
102+
,"#define CURRENT_COMPONENT_ID \"" ++ display (componentComponentId clbi) ++ "\"\n"
103+
-- TODO: maybe just give component IDs for all dependents? Hmm...
104+
,"#define LOCAL_COMPONENT_ID \"" ++ display (localComponentId lbi) ++ "\"\n"
105+
,"\n"]
106+
| otherwise = ""
106107

107108
fixchar :: Char -> Char
108109
fixchar '-' = '_'

Cabal/Distribution/Simple/Build/PathsModule.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ import Data.Maybe
3737
-- * Building Paths_<pkg>.hs
3838
-- ------------------------------------------------------------
3939

40-
generate :: PackageDescription -> LocalBuildInfo -> String
41-
generate pkg_descr lbi =
40+
generate :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
41+
generate pkg_descr lbi clbi =
4242
let pragmas = cpp_pragma ++ ffi_pragmas ++ warning_pragmas
4343

4444
cpp_pragma | supports_cpp = "{-# LANGUAGE CPP #-}\n"
@@ -169,21 +169,23 @@ generate pkg_descr lbi =
169169
in header++body
170170

171171
where
172+
cid = componentUnitId clbi
173+
172174
InstallDirs {
173175
prefix = flat_prefix,
174176
bindir = flat_bindir,
175177
libdir = flat_libdir,
176178
datadir = flat_datadir,
177179
libexecdir = flat_libexecdir,
178180
sysconfdir = flat_sysconfdir
179-
} = absoluteInstallDirs pkg_descr lbi NoCopyDest
181+
} = absoluteInstallDirs pkg_descr lbi cid NoCopyDest
180182
InstallDirs {
181183
bindir = flat_bindirrel,
182184
libdir = flat_libdirrel,
183185
datadir = flat_datadirrel,
184186
libexecdir = flat_libexecdirrel,
185187
sysconfdir = flat_sysconfdirrel
186-
} = prefixRelativeInstallDirs (packageId pkg_descr) lbi
188+
} = prefixRelativeInstallDirs (packageId pkg_descr) lbi cid
187189

188190
flat_bindirreloc = shortRelativePath flat_prefix flat_bindir
189191
flat_libdirreloc = shortRelativePath flat_prefix flat_libdir

Cabal/Distribution/Simple/BuildPaths.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ haddockPref distPref pkg_descr
5656
= distPref </> "doc" </> "html" </> display (packageName pkg_descr)
5757

5858
-- |The directory in which we put auto-generated modules
59-
autogenModulesDir :: LocalBuildInfo -> String
60-
autogenModulesDir lbi = buildDir lbi </> "autogen"
59+
autogenModulesDir :: LocalBuildInfo -> ComponentLocalBuildInfo -> String
60+
autogenModulesDir lbi clbi = libBuildDir lbi clbi </> "autogen"
61+
-- NB: Look at 'checkForeignDeps' for where a simplified version of this
62+
-- has been copy-pasted.
6163

6264
cppHeaderName :: String
6365
cppHeaderName = "cabal_macros.h"

0 commit comments

Comments
 (0)