1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE RankNTypes #-}
4 -----------------------------------------------------------------------------
7 -- Module : Distribution.Simple.PreProcess
8 -- Copyright : (c) 2003-2005, Isaac Jones, Malcolm Wallace
11 -- Maintainer : cabal-devel@haskell.org
12 -- Portability : portable
14 -- This module defines 'PPSuffixHandler', which is a combination of a file
15 -- extension and a function for configuring a 'PreProcessor'. It also defines
16 -- a bunch of known built-in preprocessors like @cpp@, @cpphs@, @c2hs@,
17 -- @hsc2hs@, @happy@, @alex@ etc and lists them in 'knownSuffixHandlers'.
18 -- On top of this it provides a function for actually preprocessing some sources
19 -- given a bunch of known suffix handlers.
20 -- This module is not as good as it could be, it could really do with a rewrite
21 -- to address some of the problems we have with pre-processors.
22 module Distribution
.Simple
.PreProcess
29 , builtinHaskellSuffixes
30 , builtinHaskellBootSuffixes
32 , mkSimplePreProcessor
33 , runSimplePreProcessor
47 import Distribution
.Compat
.Prelude
48 import Distribution
.Compat
.Stack
51 import Distribution
.Backpack
.DescribeUnitId
52 import qualified Distribution
.InstalledPackageInfo
as Installed
53 import Distribution
.ModuleName
(ModuleName
)
54 import qualified Distribution
.ModuleName
as ModuleName
55 import Distribution
.Package
56 import Distribution
.PackageDescription
as PD
57 import Distribution
.Simple
.BuildPaths
58 import Distribution
.Simple
.CCompiler
59 import Distribution
.Simple
.Compiler
60 import Distribution
.Simple
.Errors
61 import Distribution
.Simple
.LocalBuildInfo
62 import qualified Distribution
.Simple
.PackageIndex
as PackageIndex
63 import Distribution
.Simple
.PreProcess
.Types
64 import Distribution
.Simple
.PreProcess
.Unlit
65 import Distribution
.Simple
.Program
66 import Distribution
.Simple
.Program
.ResponseFile
67 import Distribution
.Simple
.Test
.LibV09
68 import Distribution
.Simple
.Utils
69 import Distribution
.System
70 import Distribution
.Types
.PackageName
.Magic
71 import Distribution
.Utils
.Path
72 import Distribution
.Verbosity
73 import Distribution
.Version
74 import System
.Directory
(doesDirectoryExist, doesFileExist)
75 import System
.FilePath
85 import System
.Info
(arch
, os
)
87 -- | Just present the modules in the order given; this is the default and it is
88 -- appropriate for preprocessors which do not have any sort of dependencies
95 unsorted _ _ ms
= pure ms
97 -- | Function to determine paths to possible extra C sources for a
98 -- preprocessor: just takes the path to the build directory and uses
99 -- this to search for C sources with names that match the
100 -- preprocessor's output name format.
101 type PreProcessorExtras
= FilePath -> IO [FilePath]
104 :: (FilePath -> FilePath -> Verbosity
-> IO ())
105 -> (FilePath, FilePath)
106 -> (FilePath, FilePath)
111 (inBaseDir
, inRelativeFile
)
112 (outBaseDir
, outRelativeFile
)
113 verbosity
= simplePP inFile outFile verbosity
115 inFile
= normalise
(inBaseDir
</> inRelativeFile
)
116 outFile
= normalise
(outBaseDir
</> outRelativeFile
)
118 runSimplePreProcessor
124 runSimplePreProcessor pp inFile outFile verbosity
=
125 runPreProcessor pp
(".", inFile
) (".", outFile
) verbosity
127 -- | A preprocessor for turning non-Haskell files with the given 'Suffix'
128 -- (i.e. file extension) into plain Haskell source files.
129 type PPSuffixHandler
=
130 (Suffix
, BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
)
132 -- | Apply preprocessors to the sources from 'hsSourceDirs' for a given
133 -- component (lib, exe, or test suite).
135 -- XXX: This is terrible
137 :: PackageDescription
140 -> ComponentLocalBuildInfo
145 preprocessComponent pd comp lbi clbi isSrcDist verbosity handlers
=
146 -- Skip preprocessing for scripts since they should be regular Haskell files,
147 -- but may have no or unknown extensions.
148 when (package pd
/= fakePackageId
) $ do
149 -- NB: never report instantiation here; we'll report it properly when
155 (componentLocalName clbi
)
156 (Nothing
:: Maybe [(ModuleName
, Module
)])
158 (CLib lib
@Library
{libBuildInfo
= bi
}) -> do
160 map getSymbolicPath
(hsSourceDirs bi
)
161 ++ [autogenComponentModulesDir lbi clbi
, autogenPackageModulesDir lbi
]
162 let hndlrs
= localHandlers bi
163 mods
<- orderingFromHandlers verbosity dirs hndlrs
(allLibModules lib clbi
)
164 for_
(map ModuleName
.toFilePath mods
) $
165 pre dirs
(componentBuildDir lbi clbi
) hndlrs
166 (CFLib flib
@ForeignLib
{foreignLibBuildInfo
= bi
, foreignLibName
= nm
}) -> do
167 let nm
' = unUnqualComponentName nm
168 let flibDir
= buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
170 map getSymbolicPath
(hsSourceDirs bi
)
171 ++ [ autogenComponentModulesDir lbi clbi
172 , autogenPackageModulesDir lbi
174 let hndlrs
= localHandlers bi
175 mods
<- orderingFromHandlers verbosity dirs hndlrs
(foreignLibModules flib
)
176 for_
(map ModuleName
.toFilePath mods
) $
177 pre dirs flibDir hndlrs
178 (CExe exe
@Executable
{buildInfo
= bi
, exeName
= nm
}) -> do
179 let nm
' = unUnqualComponentName nm
180 let exeDir
= buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
182 map getSymbolicPath
(hsSourceDirs bi
)
183 ++ [ autogenComponentModulesDir lbi clbi
184 , autogenPackageModulesDir lbi
186 let hndlrs
= localHandlers bi
187 mods
<- orderingFromHandlers verbosity dirs hndlrs
(otherModules bi
)
188 for_
(map ModuleName
.toFilePath mods
) $
189 pre dirs exeDir hndlrs
190 pre
(map getSymbolicPath
(hsSourceDirs bi
)) exeDir
(localHandlers bi
) $
191 dropExtensions
(modulePath exe
)
192 CTest test
@TestSuite
{testName
= nm
} -> do
193 let nm
' = unUnqualComponentName nm
194 case testInterface test
of
195 TestSuiteExeV10 _ f
->
196 preProcessTest test f
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
197 TestSuiteLibV09 _ _
-> do
203 writeSimpleTestStub test testDir
204 preProcessTest test
(stubFilePath test
) testDir
205 TestSuiteUnsupported tt
->
206 dieWithException verbosity
$ NoSupportForPreProcessingTest tt
207 CBench bm
@Benchmark
{benchmarkName
= nm
} -> do
208 let nm
' = unUnqualComponentName nm
209 case benchmarkInterface bm
of
210 BenchmarkExeV10 _ f
->
211 preProcessBench bm f
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
212 BenchmarkUnsupported tt
->
213 dieWithException verbosity
$ NoSupportForPreProcessingBenchmark tt
215 orderingFromHandlers v d hndlrs mods
=
216 foldM (\acc
(_
, pp
) -> ppOrdering pp v d acc
) mods hndlrs
217 builtinCSuffixes
= map Suffix cSourceExtensions
218 builtinSuffixes
= builtinHaskellSuffixes
++ builtinCSuffixes
219 localHandlers bi
= [(ext
, h bi lbi clbi
) |
(ext
, h
) <- handlers
]
220 pre dirs dir lhndlrs fp
=
221 preprocessFile
(map unsafeMakeSymbolicPath dirs
) dir isSrcDist fp verbosity builtinSuffixes lhndlrs
True
222 preProcessTest test
=
228 (benchmarkBuildInfo bm
)
229 (benchmarkModules bm
)
237 preProcessComponent bi modules exePath dir
= do
238 let biHandlers
= localHandlers bi
240 map getSymbolicPath
(hsSourceDirs bi
)
241 ++ [ autogenComponentModulesDir lbi clbi
242 , autogenPackageModulesDir lbi
246 (map unsafeMakeSymbolicPath sourceDirs
)
249 (ModuleName
.toFilePath modu
)
256 -- XXX: what we do here (re SymbolicPath dir)
257 -- XXX: 2020-10-15 do we rely here on CWD being the PackageDir?
258 -- Note we don't fail on missing in this case, because the main file may be generated later (i.e. by a test code generator)
260 (unsafeMakeSymbolicPath dir
: hsSourceDirs bi
)
263 (dropExtensions
$ exePath
)
269 -- TODO: try to list all the modules that could not be found
270 -- not just the first one. It's annoying and slow due to the need
271 -- to reconfigure after editing the .cabal file each time.
273 -- | Find the first extension of the file that exists, and preprocess it
276 :: [SymbolicPath PackageDir SourceDir
]
277 -- ^ source directories
281 -- ^ preprocess for sdist
283 -- ^ module file name
287 -- ^ builtin suffixes
288 -> [(Suffix
, PreProcessor
)]
289 -- ^ possible preprocessors
291 -- ^ fail on missing file
293 preprocessFile searchLoc buildLoc forSDist baseFile verbosity builtinSuffixes handlers failOnMissing
= do
294 -- look for files in the various source dirs with this module name
295 -- and a file extension of a known preprocessor
296 psrcFiles
<- findFileWithExtension
' (map fst handlers
) (map getSymbolicPath searchLoc
) baseFile
298 -- no preprocessor file exists, look for an ordinary source file
299 -- just to make sure one actually exists at all for this module.
300 -- Note: by looking in the target/output build dir too, we allow
301 -- source files to appear magically in the target build dir without
302 -- any corresponding "real" source file. This lets custom Setup.hs
303 -- files generate source modules directly into the build dir without
304 -- the rest of the build system being aware of it (somewhat dodgy)
306 bsrcFiles
<- findFileWithExtension builtinSuffixes
(buildLoc
: map getSymbolicPath searchLoc
) baseFile
307 case (bsrcFiles
, failOnMissing
) of
309 dieWithException verbosity
$
310 CantFindSourceForPreProcessFile
$
311 "can't find source for "
314 ++ intercalate
", " (map getSymbolicPath searchLoc
)
316 -- found a pre-processable file in one of the source dirs
317 Just
(psrcLoc
, psrcRelFile
) -> do
318 let (srcStem
, ext
) = splitExtension psrcRelFile
319 psrcFile
= psrcLoc
</> psrcRelFile
322 (error "Distribution.Simple.PreProcess: Just expected")
323 (lookup (Suffix
$ safeTail ext
) handlers
)
324 -- Preprocessing files for 'sdist' is different from preprocessing
325 -- for 'build'. When preprocessing for sdist we preprocess to
326 -- avoid that the user has to have the preprocessors available.
327 -- ATM, we don't have a way to specify which files are to be
328 -- preprocessed and which not, so for sdist we only process
329 -- platform independent files and put them into the 'buildLoc'
330 -- (which we assume is set to the temp. directory that will become
332 -- TODO: eliminate sdist variant, just supply different handlers
333 when (not forSDist || forSDist
&& platformIndependent pp
) $ do
334 -- look for existing pre-processed source file in the dest dir to
335 -- see if we really have to re-run the preprocessor.
336 ppsrcFiles
<- findFileWithExtension builtinSuffixes
[buildLoc
] baseFile
337 recomp
<- case ppsrcFiles
of
338 Nothing
-> return True
340 psrcFile `moreRecentFile` ppsrcFile
342 let destDir
= buildLoc
</> dirName srcStem
343 createDirectoryIfMissingVerbose verbosity
True destDir
344 runPreProcessorWithHsBootHack
346 (psrcLoc
, psrcRelFile
)
347 (buildLoc
, srcStem
<.> "hs")
349 dirName
= takeDirectory
351 -- FIXME: This is a somewhat nasty hack. GHC requires that hs-boot files
352 -- be in the same place as the hs files, so if we put the hs file in dist/
353 -- then we need to copy the hs-boot file there too. This should probably be
354 -- done another way. Possibly we should also be looking for .lhs-boot
355 -- files, but I think that preprocessors only produce .hs files.
356 runPreProcessorWithHsBootHack
358 (inBaseDir
, inRelativeFile
)
359 (outBaseDir
, outRelativeFile
) = do
362 (inBaseDir
, inRelativeFile
)
363 (outBaseDir
, outRelativeFile
)
366 exists
<- doesFileExist inBoot
367 when exists
$ copyFileVerbose verbosity inBoot outBoot
369 inBoot
= replaceExtension inFile
"hs-boot"
370 outBoot
= replaceExtension outFile
"hs-boot"
372 inFile
= normalise
(inBaseDir
</> inRelativeFile
)
373 outFile
= normalise
(outBaseDir
</> outRelativeFile
)
375 -- ------------------------------------------------------------
377 -- * known preprocessors
379 -- ------------------------------------------------------------
381 ppGreenCard
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
382 ppGreenCard _ lbi _
=
384 { platformIndependent
= False
385 , ppOrdering
= unsorted
386 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
->
391 (["-tffi", "-o" ++ outFile
, inFile
])
394 -- This one is useful for preprocessors that can't handle literate source.
395 -- We also need a way to chain preprocessors.
396 ppUnlit
:: PreProcessor
399 { platformIndependent
= True
400 , ppOrdering
= unsorted
401 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
->
402 withUTF8FileContents inFile
$ \contents
->
403 either (writeUTF8File outFile
) (dieWithException verbosity
) (unlit inFile contents
)
406 ppCpp
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
409 ppCpp
' :: [String] -> BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
410 ppCpp
' extraArgs bi lbi clbi
=
411 case compilerFlavor
(compiler lbi
) of
412 GHC
-> ppGhcCpp ghcProgram
(const True) args bi lbi clbi
413 GHCJS
-> ppGhcCpp ghcjsProgram
(const True) args bi lbi clbi
414 _
-> ppCpphs args bi lbi clbi
416 cppArgs
= getCppOptions bi lbi
417 args
= cppArgs
++ extraArgs
425 -> ComponentLocalBuildInfo
427 ppGhcCpp program xHs extraArgs _bi lbi clbi
=
429 { platformIndependent
= False
430 , ppOrdering
= unsorted
431 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
-> do
432 (prog
, version
, _
) <-
433 requireProgramVersion
438 runProgram verbosity prog
$
440 -- This is a bit of an ugly hack. We're going to
441 -- unlit the file ourselves later on if appropriate,
442 -- so we need GHC not to unlit it now or it'll get
443 -- double-unlitted. In the future we might switch to
444 -- using cpphs --unlit instead.
445 ++ (if xHs version
then ["-x", "hs"] else [])
446 ++ ["-optP-include", "-optP" ++ (autogenComponentModulesDir lbi clbi
</> cppHeaderName
)]
447 ++ ["-o", outFile
, inFile
]
451 ppCpphs
:: [String] -> BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
452 ppCpphs extraArgs _bi lbi clbi
=
454 { platformIndependent
= False
455 , ppOrdering
= unsorted
456 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
-> do
457 (cpphsProg
, cpphsVersion
, _
) <-
458 requireProgramVersion
463 runProgram verbosity cpphsProg
$
468 : ( if cpphsVersion
>= mkVersion
[1, 6]
469 then ["--include=" ++ (autogenComponentModulesDir lbi clbi
</> cppHeaderName
)]
475 ppHsc2hs
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
476 ppHsc2hs bi lbi clbi
=
478 { platformIndependent
= False
479 , ppOrdering
= unsorted
480 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
-> do
481 (gccProg
, _
) <- requireProgram verbosity gccProgram
(withPrograms lbi
)
482 (hsc2hsProg
, hsc2hsVersion
, _
) <-
483 requireProgramVersion
488 -- See Trac #13896 and https://github.com/haskell/cabal/issues/3122.
489 let isCross
= hostPlatform lbi
/= buildPlatform
490 prependCrossFlags
= if isCross
then ("-x" :) else id
491 let hsc2hsSupportsResponseFiles
= hsc2hsVersion
>= mkVersion
[0, 68, 4]
492 pureArgs
= genPureArgs hsc2hsVersion gccProg inFile outFile
493 if hsc2hsSupportsResponseFiles
497 defaultTempFileOptions
498 (takeDirectory outFile
)
499 "hsc2hs-response.txt"
502 ( \responseFileName
->
503 runProgram verbosity hsc2hsProg
(prependCrossFlags
["@" ++ responseFileName
])
505 else runProgram verbosity hsc2hsProg
(prependCrossFlags pureArgs
)
508 -- Returns a list of command line arguments that can either be passed
509 -- directly, or via a response file.
510 genPureArgs
:: Version
-> ConfiguredProgram
-> String -> String -> [String]
511 genPureArgs hsc2hsVersion gccProg inFile outFile
=
512 -- Additional gcc options
515 programDefaultArgs gccProg
516 ++ programOverrideArgs gccProg
518 ++ [ "--lflag=" ++ opt
520 programDefaultArgs gccProg
521 ++ programOverrideArgs gccProg
524 ++ [ what
++ "=-F" ++ opt
526 , opt
<- nub (concatMap Installed
.frameworkDirs pkgs
)
527 , what
<- ["--cflag", "--lflag"]
529 ++ [ "--lflag=" ++ arg
531 , opt
<- PD
.frameworks bi
++ concatMap Installed
.frameworks pkgs
532 , arg
<- ["-framework", opt
]
534 -- Note that on ELF systems, wherever we use -L, we must also use -R
535 -- because presumably that -L dir is not on the normal path for the
536 -- system's dynamic linker. This is needed because hsc2hs works by
537 -- compiling a C program and then running it.
539 ++ ["--cflag=" ++ opt | opt
<- platformDefines lbi
]
540 -- Options from the current package:
541 ++ ["--cflag=-I" ++ dir | dir
<- PD
.includeDirs bi
]
542 ++ ["--cflag=-I" ++ buildDir lbi
</> dir | dir
<- PD
.includeDirs bi
]
543 ++ [ "--cflag=" ++ opt
547 -- hsc2hs uses the C ABI
548 -- We assume that there are only C sources
549 -- and C++ functions are exported via a C
550 -- interface and wrapped in a C source file.
551 -- Therefore we do not supply C++ flags
552 -- because there will not be C++ sources.
554 -- DO NOT add PD.cxxOptions unless this changes!
556 ++ [ "--cflag=" ++ opt
558 [ "-I" ++ autogenComponentModulesDir lbi clbi
559 , "-I" ++ autogenPackageModulesDir lbi
561 , autogenComponentModulesDir lbi clbi
</> cppHeaderName
564 ++ [ "--lflag=-L" ++ opt
566 if withFullyStaticExe lbi
567 then PD
.extraLibDirsStatic bi
568 else PD
.extraLibDirs bi
570 ++ [ "--lflag=-Wl,-R," ++ opt
573 if withFullyStaticExe lbi
574 then PD
.extraLibDirsStatic bi
575 else PD
.extraLibDirs bi
577 ++ ["--lflag=-l" ++ opt | opt
<- PD
.extraLibs bi
]
578 ++ ["--lflag=" ++ opt | opt
<- PD
.ldOptions bi
]
579 -- Options from dependent packages
580 ++ [ "--cflag=" ++ opt
583 ["-I" ++ opt | opt
<- Installed
.includeDirs pkg
]
584 ++ Installed
.ccOptions pkg
586 ++ [ "--lflag=" ++ opt
589 ["-L" ++ opt | opt
<- Installed
.libraryDirs pkg
]
590 ++ [ "-Wl,-R," ++ opt | isELF
, opt
<- Installed
.libraryDirs pkg
594 if withFullyStaticExe lbi
595 then Installed
.extraLibrariesStatic pkg
596 else Installed
.extraLibraries pkg
598 ++ Installed
.ldOptions pkg
603 ++ ["-o", outFile
, inFile
]
605 -- hsc2hs flag parsing was wrong
606 -- (see -- https://github.com/haskell/hsc2hs/issues/35)
607 -- so we need to put -- --cc/--ld *after* hsc2hsOptions,
608 -- for older hsc2hs (pre 0.68.8) so that they can be overridden.
610 [ "--cc=" ++ programPath gccProg
611 , "--ld=" ++ programPath gccProg
614 (preccldFlags
, postccldFlags
)
615 | hsc2hsVersion
>= mkVersion
[0, 68, 8] = (ccldFlags
, [])
616 |
otherwise = ([], ccldFlags
)
618 hacked_index
= packageHacks
(installedPkgs lbi
)
619 -- Look only at the dependencies of the current component
620 -- being built! This relies on 'installedPkgs' maintaining
621 -- 'InstalledPackageInfo' for internal deps too; see #2971.
622 pkgs
= PackageIndex
.topologicalOrder
$
623 case PackageIndex
.dependencyClosure
625 (map fst (componentPackageDeps clbi
)) of
626 Left
index' -> index'
628 error ("ppHsc2hs: broken closure: " ++ show inf
)
629 isOSX
= case buildOS
of OSX
-> True; _
-> False
630 isELF
= case buildOS
of OSX
-> False; Windows
-> False; AIX
-> False; _
-> True
631 packageHacks
= case compilerFlavor
(compiler lbi
) of
632 GHC
-> hackRtsPackage
633 GHCJS
-> hackRtsPackage
635 -- We don't link in the actual Haskell libraries of our dependencies, so
636 -- the -u flags in the ldOptions of the rts package mean linking fails on
637 -- OS X (its ld is a tad stricter than gnu ld). Thus we remove the
638 -- ldOptions for GHC's rts package:
639 hackRtsPackage
index =
640 case PackageIndex
.lookupPackageName
index (mkPackageName
"rts") of
642 PackageIndex
.insert rts
{Installed
.ldOptions
= []} index
643 _
-> error "No (or multiple) ghc rts package is registered!!"
645 ppHsc2hsExtras
:: PreProcessorExtras
646 ppHsc2hsExtras buildBaseDir
=
647 filter ("_hsc.c" `
isSuffixOf`
)
648 `
fmap` getDirectoryContentsRecursive buildBaseDir
650 ppC2hs
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
653 { platformIndependent
= False
654 , ppOrdering
= unsorted
656 \(inBaseDir
, inRelativeFile
)
657 (outBaseDir
, outRelativeFile
)
660 requireProgramVersion
663 (orLaterVersion
(mkVersion
[0, 15]))
665 (gccProg
, _
) <- requireProgram verbosity gccProgram
(withPrograms lbi
)
666 runProgram verbosity c2hsProg
$
667 -- Options from the current package:
668 ["--cpp=" ++ programPath gccProg
, "--cppopts=-E"]
669 ++ ["--cppopts=" ++ opt | opt
<- getCppOptions bi lbi
]
670 ++ ["--cppopts=-include" ++ (autogenComponentModulesDir lbi clbi
</> cppHeaderName
)]
671 ++ ["--include=" ++ outBaseDir
]
672 -- Options from dependent packages
673 ++ [ "--cppopts=" ++ opt
676 ["-I" ++ opt | opt
<- Installed
.includeDirs pkg
]
677 ++ [ opt | opt
@('-' : c
: _
) <- Installed
.ccOptions pkg
,
678 -- c2hs uses the C ABI
679 -- We assume that there are only C sources
680 -- and C++ functions are exported via a C
681 -- interface and wrapped in a C source file.
682 -- Therefore we do not supply C++ flags
683 -- because there will not be C++ sources.
686 -- DO NOT add Installed.cxxOptions unless this changes!
690 -- TODO: install .chi files for packages, so we can --include
691 -- those dirs here, for the dependencies
693 -- input and output files
694 ++ [ "--output-dir=" ++ outBaseDir
695 , "--output=" ++ outRelativeFile
696 , inBaseDir
</> inRelativeFile
700 pkgs
= PackageIndex
.topologicalOrder
(installedPkgs lbi
)
702 ppC2hsExtras
:: PreProcessorExtras
704 filter (\p
-> takeExtensions p
== ".chs.c")
705 `
fmap` getDirectoryContentsRecursive d
707 -- TODO: perhaps use this with hsc2hs too
708 -- TODO: remove cc-options from cpphs for cabal-version: >= 1.10
709 -- TODO: Refactor and add separate getCppOptionsForHs, getCppOptionsForCxx, & getCppOptionsForC
710 -- instead of combining all these cases in a single function. This blind combination can
711 -- potentially lead to compilation inconsistencies.
712 getCppOptions
:: BuildInfo
-> LocalBuildInfo
-> [String]
713 getCppOptions bi lbi
=
716 ++ ["-I" ++ dir | dir
<- PD
.includeDirs bi
]
717 ++ [opt | opt
@('-' : c
: _
) <- PD
.ccOptions bi
++ PD
.cxxOptions bi
, c `
elem`
"DIU"]
719 platformDefines
:: LocalBuildInfo
-> [String]
720 platformDefines lbi
=
721 case compilerFlavor comp
of
723 ["-D__GLASGOW_HASKELL__=" ++ versionInt version
]
724 ++ ["-D" ++ os
++ "_BUILD_OS=1"]
725 ++ ["-D" ++ arch
++ "_BUILD_ARCH=1"]
726 ++ map (\os
' -> "-D" ++ os
' ++ "_HOST_OS=1") osStr
727 ++ map (\arch
' -> "-D" ++ arch
' ++ "_HOST_ARCH=1") archStr
730 ++ ["-D__GHCJS__=" ++ versionInt version
]
731 ++ ["-D" ++ os
++ "_BUILD_OS=1"]
732 ++ ["-D" ++ arch
++ "_BUILD_ARCH=1"]
733 ++ map (\os
' -> "-D" ++ os
' ++ "_HOST_OS=1") osStr
734 ++ map (\arch
' -> "-D" ++ arch
' ++ "_HOST_ARCH=1") archStr
736 ["-D__HASKELL_SUITE__"]
737 ++ map (\os
' -> "-D" ++ os
' ++ "_HOST_OS=1") osStr
738 ++ map (\arch
' -> "-D" ++ arch
' ++ "_HOST_ARCH=1") archStr
742 Platform hostArch hostOS
= hostPlatform lbi
743 version
= compilerVersion comp
744 compatGlasgowHaskell
=
747 (\v -> ["-D__GLASGOW_HASKELL__=" ++ versionInt v
])
748 (compilerCompatVersion GHC comp
)
749 -- TODO: move this into the compiler abstraction
750 -- FIXME: this forces GHC's crazy 4.8.2 -> 408 convention on all
751 -- the other compilers. Check if that's really what they want.
752 versionInt
:: Version
-> String
753 versionInt v
= case versionNumbers v
of
764 in s1
++ middle
++ s2
766 osStr
= case hostOS
of
768 Windows
-> ["mingw32"]
770 FreeBSD
-> ["freebsd"]
771 OpenBSD
-> ["openbsd"]
773 DragonFly
-> ["dragonfly"]
774 Solaris
-> ["solaris2"]
780 Android
-> ["android"]
786 archStr
= case hostArch
of
790 PPC64
-> ["powerpc64"]
791 PPC64LE
-> ["powerpc64le"]
793 Sparc64
-> ["sparc64"]
795 AArch64
-> ["aarch64"]
806 RISCV64
-> ["riscv64"]
807 LoongArch64
-> ["loongarch64"]
808 JavaScript
-> ["javascript"]
812 ppHappy
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
813 ppHappy _ lbi _
= pp
{platformIndependent
= True}
815 pp
= standardPP lbi happyProgram
(hcFlags hc
)
816 hc
= compilerFlavor
(compiler lbi
)
817 hcFlags GHC
= ["-agc"]
818 hcFlags GHCJS
= ["-agc"]
821 ppAlex
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> PreProcessor
822 ppAlex _ lbi _
= pp
{platformIndependent
= True}
824 pp
= standardPP lbi alexProgram
(hcFlags hc
)
825 hc
= compilerFlavor
(compiler lbi
)
827 hcFlags GHCJS
= ["-g"]
830 standardPP
:: LocalBuildInfo
-> Program
-> [String] -> PreProcessor
831 standardPP lbi prog args
=
833 { platformIndependent
= False
834 , ppOrdering
= unsorted
835 , runPreProcessor
= mkSimplePreProcessor
$ \inFile outFile verbosity
->
840 (args
++ ["-o", outFile
, inFile
])
843 -- | Convenience function; get the suffixes of these preprocessors.
844 ppSuffixes
:: [PPSuffixHandler
] -> [Suffix
]
847 -- | Standard preprocessors: GreenCard, c2hs, hsc2hs, happy, alex and cpphs.
848 knownSuffixHandlers
:: [PPSuffixHandler
]
849 knownSuffixHandlers
=
850 [ (Suffix
"gc", ppGreenCard
)
851 , (Suffix
"chs", ppC2hs
)
852 , (Suffix
"hsc", ppHsc2hs
)
853 , (Suffix
"x", ppAlex
)
854 , (Suffix
"y", ppHappy
)
855 , (Suffix
"ly", ppHappy
)
856 , (Suffix
"cpphs", ppCpp
)
859 -- | Standard preprocessors with possible extra C sources: c2hs, hsc2hs.
860 knownExtrasHandlers
:: [PreProcessorExtras
]
861 knownExtrasHandlers
= [ppC2hsExtras
, ppHsc2hsExtras
]
863 -- | Find any extra C sources generated by preprocessing that need to
864 -- be added to the component (addresses issue #238).
870 preprocessExtras verbosity comp lbi
= case comp
of
871 CLib _
-> pp
$ buildDir lbi
872 (CExe Executable
{exeName
= nm
}) -> do
873 let nm
' = unUnqualComponentName nm
874 pp
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
875 (CFLib ForeignLib
{foreignLibName
= nm
}) -> do
876 let nm
' = unUnqualComponentName nm
877 pp
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
879 let nm
' = unUnqualComponentName
$ testName test
880 case testInterface test
of
881 TestSuiteExeV10 _ _
->
882 pp
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
883 TestSuiteLibV09 _ _
->
884 pp
$ buildDir lbi
</> stubName test
</> stubName test
++ "-tmp"
885 TestSuiteUnsupported tt
->
886 dieWithException verbosity
$ NoSupportPreProcessingTestExtras tt
888 let nm
' = unUnqualComponentName
$ benchmarkName bm
889 case benchmarkInterface bm
of
890 BenchmarkExeV10 _ _
->
891 pp
$ buildDir lbi
</> nm
' </> nm
' ++ "-tmp"
892 BenchmarkUnsupported tt
->
893 dieWithException verbosity
$ NoSupportPreProcessingBenchmarkExtras tt
895 pp
:: FilePath -> IO [FilePath]
897 b
<- doesDirectoryExist dir
900 (map (dir
</>) . filter not_sub
. concat)
903 (withLexicalCallStack
(\f -> f dir
))
905 -- TODO: This is a terrible hack to work around #3545 while we don't
906 -- reorganize the directory layout. Basically, for the main
907 -- library, we might accidentally pick up autogenerated sources for
908 -- our subcomponents, because they are all stored as subdirectories
909 -- in dist/build. This is a cheap and cheerful check to prevent
910 -- this from happening. It is not particularly correct; for example
911 -- if a user has a test suite named foobar and puts their C file in
912 -- foobar/foo.c, this test will incorrectly exclude it. But I
913 -- didn't want to break BC...
914 not_sub p
= and [not (pre `
isPrefixOf` p
) | pre
<- component_dirs
]
915 component_dirs
= component_names
(localPkgDescr lbi
)
917 component_names pkg_descr
=
918 fmap unUnqualComponentName
$
919 mapMaybe (libraryNameString
. libName
) (subLibraries pkg_descr
)
920 ++ map exeName
(executables pkg_descr
)
921 ++ map testName
(testSuites pkg_descr
)
922 ++ map benchmarkName
(benchmarks pkg_descr
)