2 -- Module : Distribution.PackageDescription.Check.Target
3 -- Copyright : Lennart Kolmodin 2008, Francesco Ariis 2023
6 -- Maintainer : cabal-devel@haskell.org
7 -- Portability : portable
9 -- Fully-realised target (library, executable, …) checking functions.
10 module Distribution
.PackageDescription
.Check
.Target
18 import Distribution
.Compat
.Prelude
21 import Distribution
.CabalSpecVersion
22 import Distribution
.Compat
.Lens
23 import Distribution
.Compiler
24 import Distribution
.ModuleName
(ModuleName
)
25 import Distribution
.Package
26 import Distribution
.PackageDescription
27 import Distribution
.PackageDescription
.Check
.Common
28 import Distribution
.PackageDescription
.Check
.Monad
29 import Distribution
.PackageDescription
.Check
.Paths
30 import Distribution
.Pretty
(prettyShow
)
31 import Distribution
.Simple
.BuildPaths
32 ( autogenPackageInfoModuleName
33 , autogenPathsModuleName
35 import Distribution
.Simple
.Utils
hiding (findPackageDesc
, notice
)
36 import Distribution
.Types
.PackageName
.Magic
37 import Distribution
.Utils
.Path
38 import Distribution
.Version
39 import Language
.Haskell
.Extension
40 import System
.FilePath (takeExtension
)
44 import qualified Distribution
.Types
.BuildInfo
.Lens
as L
48 => Bool -- Is this a sublibrary?
49 -> [AssocDep
] -- “Inherited” dependencies for PVP checks.
65 (libName_
== LMainLibName
&& isSub
)
66 (PackageBuildImpossible UnnamedInternal
)
67 -- TODO: bogus if a required-signature was passed through.
69 (null (explicitLibModules lib
) && null reexportedModules_
)
70 (PackageDistSuspiciousWarn
(NoModulesExposed libName_
))
71 -- TODO parse-caught check, can safely remove.
74 (not . null $ signatures_
)
75 (PackageDistInexcusable SignaturesCabal2
)
76 -- autogen/includes checks.
80 (flip elem (explicitLibModules lib
))
81 (libModulesAutogen lib
)
83 (PackageBuildImpossible AutogenNotExposed
)
84 -- check that all autogen-includes appear on includes or
89 (flip elem (allExplicitIncludes lib
))
90 (view L
.autogenIncludes lib
)
92 $ (PackageBuildImpossible AutogenIncludesNotIncluded
)
97 (explicitLibModules lib
)
102 -- check use of reexported-modules sections
105 (not . null $ reexportedModules_
)
106 (PackageDistInexcusable CVReexported
)
108 allExplicitIncludes
:: L
.HasBuildInfo a
=> a
-> [FilePath]
109 allExplicitIncludes x
=
111 ++ view L
.installIncludes x
113 checkForeignLib
:: Monad m
=> ForeignLib
-> CheckM m
()
120 _foreignLibVersionInfo_
121 _foreignLibVersionLinux_
122 _foreignLibModDefFile_
125 (CETForeignLibrary foreignLibName_
)
132 => [AssocDep
] -- “Inherited” dependencies for PVP checks.
143 -- Target type/name (exe).
144 let cet
= CETExecutable exeName_
146 -- § Exe specific checks
149 (PackageBuildImpossible
(NoMainIs exeName_
))
150 -- This check does not apply to scripts.
151 pid
<- asksCM
(pnPackageId
. ccNames
)
153 ( pid
/= fakePackageId
154 && not (null modulePath_
)
155 && not (fileExtensionSupportedLanguage
$ modulePath_
)
157 (PackageBuildImpossible NoHsLhsMain
)
162 ( fileExtensionSupportedLanguage modulePath_
163 && takeExtension modulePath_ `
notElem`
[".hs", ".lhs"]
165 (PackageDistInexcusable MainCCabal1_18
)
167 -- Alas exeModules ad exeModulesAutogen (exported from
168 -- Distribution.Types.Executable) take `Executable` as a parameter.
170 (not $ all (flip elem (exeModules exe
)) (exeModulesAutogen exe
))
171 (PackageBuildImpossible
$ AutogenNoOther cet
)
175 (flip elem (view L
.includes exe
))
176 (view L
.autogenIncludes exe
)
178 (PackageBuildImpossible AutogenIncludesNotIncludedExe
)
180 -- § Build info checks.
181 checkBuildInfo cet
[] ads buildInfo_
185 => [AssocDep
] -- “Inherited” dependencies for PVP checks.
196 -- Target type/name (test).
197 let cet
= CETTest testName_
199 -- § TS specific checks.
200 -- TODO caught by the parser, can remove safely
201 case testInterface_
of
202 TestSuiteUnsupported tt
@(TestTypeUnknown _ _
) ->
203 tellP
(PackageBuildWarning
$ TestsuiteTypeNotKnown tt
)
204 TestSuiteUnsupported tt
->
205 tellP
(PackageBuildWarning
$ TestsuiteNotSupported tt
)
209 (PackageBuildImpossible NoHsLhsMain
)
213 (flip elem (testModules ts
))
214 (testModulesAutogen ts
)
216 (PackageBuildImpossible
$ AutogenNoOther cet
)
220 (flip elem (view L
.includes ts
))
221 (view L
.autogenIncludes ts
)
223 (PackageBuildImpossible AutogenIncludesNotIncludedExe
)
228 (mainIsNotHsExt
&& not mainIsWrongExt
)
229 (PackageDistInexcusable MainCCabal1_18
)
231 -- § Build info checks.
232 checkBuildInfo cet
[] ads testBuildInfo_
235 case testInterface_
of
236 TestSuiteExeV10 _ f
-> not (fileExtensionSupportedLanguage f
)
240 case testInterface_
of
241 TestSuiteExeV10 _ f
-> takeExtension f `
notElem`
[".hs", ".lhs"]
246 => [AssocDep
] -- “Inherited” dependencies for PVP checks.
256 -- Target type/name (benchmark).
257 let cet
= CETBenchmark benchmarkName_
259 -- § Interface & bm specific tests.
260 case benchmarkInterface_
of
261 BenchmarkUnsupported tt
@(BenchmarkTypeUnknown _ _
) ->
262 tellP
(PackageBuildWarning
$ BenchmarkTypeNotKnown tt
)
263 BenchmarkUnsupported tt
->
264 tellP
(PackageBuildWarning
$ BenchmarkNotSupported tt
)
268 (PackageBuildImpossible NoHsLhsMainBench
)
273 (flip elem (benchmarkModules bm
))
274 (benchmarkModulesAutogen bm
)
276 (PackageBuildImpossible
$ AutogenNoOther cet
)
281 (flip elem (view L
.includes bm
))
282 (view L
.autogenIncludes bm
)
284 (PackageBuildImpossible AutogenIncludesNotIncludedExe
)
286 -- § BuildInfo checks.
287 checkBuildInfo cet
[] ads benchmarkBuildInfo_
289 -- Cannot abstract with similar function in checkTestSuite,
290 -- they are different.
292 case benchmarkInterface_
of
293 BenchmarkExeV10 _ f
-> takeExtension f `
notElem`
[".hs", ".lhs"]
296 -- ------------------------------------------------------------
298 -- ------------------------------------------------------------
300 -- Check a great deal of things in buildInfo.
301 -- With 'checkBuildInfo' we cannot follow the usual “pattern match
302 -- everything” method, for the number of BuildInfo fields (almost 50)
303 -- but more importantly because accessing options, etc. is done
304 -- with functions from 'Distribution.Types.BuildInfo' (e.g. 'hcOptions').
305 -- Duplicating the effort here means risk of diverging definitions for
306 -- little gain (most likely if a field is added to BI, the relevant
307 -- function will be tweaked in Distribution.Types.BuildInfo too).
310 => CEType
-- Name and type of the target.
311 -> [ModuleName
] -- Additional module names which cannot be
312 -- extracted from BuildInfo (mainly: exposed
314 -> [AssocDep
] -- Inherited “internal” (main lib, named
315 -- internal libs) dependencies.
318 checkBuildInfo cet ams ads bi
= do
319 -- For the sake of clarity, we split che checks in various
320 -- (top level) functions, even if we are not actually going
321 -- deeper in the traversal.
323 checkBuildInfoOptions
(cet2bit cet
) bi
324 checkBuildInfoPathsContent bi
325 checkBuildInfoPathsWellFormedness bi
327 sv
<- asksCM ccSpecVersion
328 checkBuildInfoFeatures bi sv
330 checkAutogenModules ams bi
332 -- PVP: we check for base and all other deps.
336 [mkUnqualComponentName
"base"]
337 (mergeDependencies
$ targetBuildDepends bi
)
338 let ick
= const (PackageDistInexcusable BaseNoUpperBounds
)
339 rck
= PackageDistSuspiciousWarn
. MissingUpperBounds cet
342 (isInternalTarget cet
)
345 -- Custom fields well-formedness (ASCII).
346 mapM_ checkCustomField
(customFieldsBI bi
)
349 mapM_ (checkLocalPathExist
"extra-lib-dirs") (extraLibDirs bi
)
351 (checkLocalPathExist
"extra-lib-dirs-static")
352 (extraLibDirsStatic bi
)
354 (checkLocalPathExist
"extra-framework-dirs")
355 (extraFrameworkDirs bi
)
356 mapM_ (checkLocalPathExist
"include-dirs") (includeDirs bi
)
358 (checkLocalPathExist
"hs-source-dirs" . getSymbolicPath
)
361 -- Well formedness of BI contents (no `Haskell2015`, no deprecated
363 checkBuildInfoPathsContent
:: Monad m
=> BuildInfo
-> CheckM m
()
364 checkBuildInfoPathsContent bi
= do
365 mapM_ checkLang
(allLanguages bi
)
366 mapM_ checkExt
(allExtensions bi
)
367 mapM_ checkIntDep
(targetBuildDepends bi
)
368 df
<- asksCM ccDesugar
369 -- This way we can use the same function for legacy&non exedeps.
370 let ds
= buildToolDepends bi
++ catMaybes (map df
$ buildTools bi
)
373 checkLang
:: Monad m
=> Language
-> CheckM m
()
374 checkLang
(UnknownLanguage n
) =
375 tellP
(PackageBuildWarning
(UnknownLanguages
[n
]))
376 checkLang _
= return ()
378 checkExt
:: Monad m
=> Extension
-> CheckM m
()
379 checkExt
(UnknownExtension n
)
380 | n `
elem`
map prettyShow knownLanguages
=
381 tellP
(PackageBuildWarning
(LanguagesAsExtension
[n
]))
383 tellP
(PackageBuildWarning
(UnknownExtensions
[n
]))
385 let dss
= filter (\(a
, _
) -> a
== n
) deprecatedExtensions
388 (PackageDistSuspicious
$ DeprecatedExtensions dss
)
390 checkIntDep
:: Monad m
=> Dependency
-> CheckM m
()
391 checkIntDep d
@(Dependency name vrange _
) = do
394 ( packageNameToUnqualComponentName
399 lns
<- asksCM
(pnSubLibs
. ccNames
)
400 pVer
<- asksCM
(pkgVersion
. pnPackageId
. ccNames
)
401 let allLibNs
= mpn
: lns
403 ( mpn
== packageNameToUnqualComponentName name
404 -- Make sure it is not a library with the
405 -- same name from another package.
406 && packageNameToUnqualComponentName name `
elem` allLibNs
409 (not $ pVer `withinRange` vrange
)
410 (PackageBuildImpossible
$ ImpossibleInternalDep
[d
])
413 checkBTDep
:: Monad m
=> ExeDependency
-> CheckM m
()
414 checkBTDep ed
@(ExeDependency n name vrange
) = do
415 exns
<- asksCM
(pnExecs
. ccNames
)
416 pVer
<- asksCM
(pkgVersion
. pnPackageId
. ccNames
)
417 pNam
<- asksCM
(pkgName
. pnPackageId
. ccNames
)
420 && name `
notElem` exns
-- internal
423 (PackageBuildImpossible
$ MissingInternalExe
[ed
])
427 (not $ pVer `withinRange` vrange
)
428 (PackageBuildImpossible
$ ImpossibleInternalExe
[ed
])
431 -- Paths well-formedness check for BuildInfo.
432 checkBuildInfoPathsWellFormedness
:: Monad m
=> BuildInfo
-> CheckM m
()
433 checkBuildInfoPathsWellFormedness bi
= do
434 mapM_ (checkPath
False "asm-sources" PathKindFile
) (asmSources bi
)
435 mapM_ (checkPath
False "cmm-sources" PathKindFile
) (cmmSources bi
)
436 mapM_ (checkPath
False "c-sources" PathKindFile
) (cSources bi
)
437 mapM_ (checkPath
False "cxx-sources" PathKindFile
) (cxxSources bi
)
438 mapM_ (checkPath
False "js-sources" PathKindFile
) (jsSources bi
)
440 (checkPath
False "install-includes" PathKindFile
)
443 (checkPath
False "hs-source-dirs" PathKindDirectory
. getSymbolicPath
)
445 -- Possibly absolute paths.
446 mapM_ (checkPath
True "includes" PathKindFile
) (includes bi
)
448 (checkPath
True "include-dirs" PathKindDirectory
)
451 (checkPath
True "extra-lib-dirs" PathKindDirectory
)
454 (checkPath
True "extra-lib-dirs-static" PathKindDirectory
)
455 (extraLibDirsStatic bi
)
456 mapM_ checkOptionPath
(perCompilerFlavorToList
$ options bi
)
460 => (CompilerFlavor
, [FilePath])
462 checkOptionPath
(GHC
, paths
) =
467 (PackageDistInexcusable
$ DistPoint Nothing path
)
470 checkOptionPath _
= return ()
472 -- Checks for features that can be present in BuildInfo only with certain
474 checkBuildInfoFeatures
479 checkBuildInfoFeatures bi sv
= do
480 -- Default language can be used only w/ spec ≥ 1.10
483 (isJust $ defaultLanguage bi
)
484 (PackageBuildWarning CVDefaultLanguage
)
487 ( sv
>= CabalSpecV1_10
488 && sv
< CabalSpecV3_4
489 && isNothing (defaultLanguage bi
)
491 (PackageBuildWarning CVDefaultLanguageComponent
)
492 -- Check use of 'extra-framework-dirs' field.
495 (not . null $ extraFrameworkDirs bi
)
496 (PackageDistSuspiciousWarn CVExtraFrameworkDirs
)
497 -- Check use of default-extensions field don't need to do the
498 -- equivalent check for other-extensions.
501 (not . null $ defaultExtensions bi
)
502 (PackageBuildWarning CVDefaultExtensions
)
503 -- Check use of extensions field
505 (sv
>= CabalSpecV1_10
&& (not . null $ oldExtensions bi
))
506 (PackageBuildWarning CVExtensionsDeprecated
)
508 -- asm-sources, cmm-sources and friends only w/ spec ≥ 1.10
509 checkCVSources
(asmSources bi
)
510 checkCVSources
(cmmSources bi
)
511 checkCVSources
(extraBundledLibs bi
)
512 checkCVSources
(extraLibFlavours bi
)
514 -- extra-dynamic-library-flavours requires ≥ 3.0
517 (not . null $ extraDynLibFlavours bi
)
518 (PackageDistInexcusable
$ CVExtraDynamic
[extraDynLibFlavours bi
])
519 -- virtual-modules requires ≥ 2.2
520 checkSpecVer CabalSpecV2_2
(not . null $ virtualModules bi
) $
521 (PackageDistInexcusable CVVirtualModules
)
522 -- Check use of thinning and renaming.
525 (not . null $ mixins bi
)
526 (PackageDistInexcusable CVMixins
)
528 checkBuildInfoExtensions bi
530 checkCVSources
:: Monad m
=> [FilePath] -> CheckM m
()
535 (PackageDistInexcusable CVSources
)
537 -- Tests for extensions usage which can break Cabal < 1.4.
538 checkBuildInfoExtensions
:: Monad m
=> BuildInfo
-> CheckM m
()
539 checkBuildInfoExtensions bi
= do
540 let exts
= allExtensions bi
541 extCabal1_2
= nub $ filter (`
elem` compatExtensionsExtra
) exts
542 extCabal1_4
= nub $ filter (`
notElem` compatExtensions
) exts
543 -- As of Cabal-1.4 we can add new extensions without worrying
544 -- about breaking old versions of cabal.
547 (not . null $ extCabal1_2
)
548 ( PackageDistInexcusable
$
549 CVExtensions CabalSpecV1_2 extCabal1_2
553 (not . null $ extCabal1_4
)
554 ( PackageDistInexcusable
$
555 CVExtensions CabalSpecV1_4 extCabal1_4
558 -- The known extensions in Cabal-1.2.3
559 compatExtensions
:: [Extension
]
563 [ OverlappingInstances
564 , UndecidableInstances
565 , IncoherentInstances
568 , MultiParamTypeClasses
569 , FunctionalDependencies
572 , PolymorphicComponents
573 , ExistentialQuantification
574 , ScopedTypeVariables
581 , TypeSynonymInstances
583 , ForeignFunctionInterface
588 , GeneralizedNewtypeDeriving
590 , RestrictedTypeSynonyms
595 [MonomorphismRestriction
, ImplicitPrelude
]
596 ++ compatExtensionsExtra
598 -- The extra known extensions in Cabal-1.2.3 vs Cabal-1.1.6
599 -- (Cabal-1.1.6 came with ghc-6.6. Cabal-1.2 came with ghc-6.8)
600 compatExtensionsExtra
:: [Extension
]
601 compatExtensionsExtra
=
611 , LiberalTypeSynonyms
615 , DisambiguateRecordFields
619 , ExtendedDefaultRules
622 , ConstrainedClassMethods
628 -- Autogenerated modules (Paths_, PackageInfo_) checks. We could pass this
629 -- function something more specific than the whole BuildInfo, but it would be
630 -- a tuple of [ModuleName] lists, error prone.
633 => [ModuleName
] -- Additional modules not present
634 -- in BuildInfo (e.g. exposed library
638 checkAutogenModules ams bi
= do
639 pkgId
<- asksCM
(pnPackageId
. ccNames
)
641 -- It is an unfortunate reality that autogenPathsModuleName
642 -- and autogenPackageInfoModuleName work on PackageDescription
643 -- while not needing it all, but just the `package` bit.
644 minimalPD
= emptyPackageDescription
{package
= pkgId
}
645 autoPathsName
= autogenPathsModuleName minimalPD
646 autoInfoModuleName
= autogenPackageInfoModuleName minimalPD
648 -- Autogenerated module + some default extension build failure.
649 autogenCheck autoPathsName CVAutogenPaths
650 rebindableClashCheck autoPathsName RebindableClashPaths
652 -- Paths_* module + some default extension build failure.
653 autogenCheck autoInfoModuleName CVAutogenPackageInfo
654 rebindableClashCheck autoInfoModuleName RebindableClashPackageInfo
656 -- PackageInfo_* module + cabal-version < 3.12
657 -- See Mikolaj’s comments on #9481 on why this has to be
658 -- PackageBuildImpossible and not merely PackageDistInexcusable.
661 (elem autoInfoModuleName allModsForAuto
)
662 (PackageBuildImpossible CVAutogenPackageInfoGuard
)
664 allModsForAuto
:: [ModuleName
]
665 allModsForAuto
= ams
++ otherModules bi
672 autogenCheck name warning
= do
673 sv
<- asksCM ccSpecVersion
675 ( sv
>= CabalSpecV2_0
676 && elem name allModsForAuto
677 && notElem name
(autogenModules bi
)
679 (PackageDistInexcusable warning
)
686 rebindableClashCheck name warning
= do
689 ( ( name `
elem` otherModules bi
690 || name `
elem` autogenModules bi
694 (PackageBuildImpossible warning
)
696 -- Do we have some peculiar extensions active which would interfere
697 -- (cabal-version <2.2) with Paths_modules?
700 let exts
= defaultExtensions bi
701 in rebind `
elem` exts
702 && (strings `
elem` exts || lists `
elem` exts
)
704 rebind
= EnableExtension RebindableSyntax
705 strings
= EnableExtension OverloadedStrings
706 lists
= EnableExtension OverloadedLists
710 => String -- .cabal field where we found the error.
713 checkLocalPathExist title dir
=
716 dn
<- not <$> doesDirectoryExist ops dir
717 let rp
= not (isAbsoluteOnAnyPlatform dir
)
720 (PackageBuildWarning
$ UnknownDirectory title dir
)
724 -- Sometimes we read (or end up with) “straddle” deps declarations
727 -- build-depends: base > 3, base < 4
729 -- `mergeDependencies` reduces that to base > 3 && < 4, _while_ maintaining
730 -- dependencies order in the list (better UX).
731 mergeDependencies
:: [Dependency
] -> [Dependency
]
732 mergeDependencies
[] = []
733 mergeDependencies l
@(d
: _
) =
734 let (sames
, diffs
) = partition ((== depName d
) . depName
) l
738 ( foldl intersectVersionRanges anyVersion
$
739 map depVerRange sames
742 in merged
: mergeDependencies diffs
744 depName
:: Dependency
-> String
745 depName wd
= unPackageName
. depPkgName
$ wd
747 -- Is this an internal target? We do not perform PVP checks on those,
748 -- see https://github.com/haskell/cabal/pull/8361#issuecomment-1577547091
749 isInternalTarget
:: CEType
-> Bool
750 isInternalTarget
(CETLibrary
{}) = False
751 isInternalTarget
(CETForeignLibrary
{}) = False
752 isInternalTarget
(CETExecutable
{}) = False
753 isInternalTarget
(CETTest
{}) = True
754 isInternalTarget
(CETBenchmark
{}) = True
755 isInternalTarget
(CETSetup
{}) = False
757 -- ------------------------------------------------------------
759 -- ------------------------------------------------------------
761 -- Target type for option checking.
762 data BITarget
= BITLib | BITTestBench | BITOther
765 cet2bit
:: CEType
-> BITarget
766 cet2bit
(CETLibrary
{}) = BITLib
767 cet2bit
(CETForeignLibrary
{}) = BITLib
768 cet2bit
(CETExecutable
{}) = BITOther
769 cet2bit
(CETTest
{}) = BITTestBench
770 cet2bit
(CETBenchmark
{}) = BITTestBench
771 cet2bit CETSetup
= BITOther
773 -- General check on all options (ghc, C, C++, …) for common inaccuracies.
774 checkBuildInfoOptions
:: Monad m
=> BITarget
-> BuildInfo
-> CheckM m
()
775 checkBuildInfoOptions t bi
= do
776 checkGHCOptions
"ghc-options" t
(hcOptions GHC bi
)
777 checkGHCOptions
"ghc-prof-options" t
(hcProfOptions GHC bi
)
778 checkGHCOptions
"ghc-shared-options" t
(hcSharedOptions GHC bi
)
779 let ldOpts
= ldOptions bi
780 checkCLikeOptions LangC
"cc-options" (ccOptions bi
) ldOpts
781 checkCLikeOptions LangCPlusPlus
"cxx-options" (cxxOptions bi
) ldOpts
782 checkCPPOptions
(cppOptions bi
)
784 -- | Checks GHC options for commonly misused or non-portable flags.
787 => CabalField
-- .cabal field name where we found the error.
788 -> BITarget
-- Target type.
789 -> [String] -- Options (alas in String form).
791 checkGHCOptions title t opts
= do
794 BITLib
-> sequence_ [checkLib
, checkNonTestBench
]
795 BITTestBench
-> checkTestBench
796 BITOther
-> checkNonTestBench
798 checkFlags
:: Monad m
=> [String] -> PackageCheck
-> CheckM m
()
799 checkFlags fs ck
= checkP
(any (`
elem` fs
) opts
) ck
804 -> (String -> PackageCheck
)
807 case filter p opts
of
809 (_
: _
) -> tellP
(ckc title
)
814 (PackageDistInexcusable
$ OptFasm title
)
817 (PackageDistInexcusable
$ OptHpc title
)
820 (PackageBuildWarning
$ OptProf title
)
821 -- Does not apply to scripts.
822 -- Why do we need this? See #8963.
823 pid
<- asksCM
(pnPackageId
. ccNames
)
824 unless (pid
== fakePackageId
) $
827 (PackageBuildWarning
$ OptO title
)
830 (PackageBuildWarning
$ OptHide title
)
833 (PackageBuildWarning
$ OptMake title
)
836 (PackageDistInexcusable
$ OptOOne title
)
839 (PackageDistSuspiciousWarn
$ OptOTwo title
)
842 (PackageBuildWarning
$ OptSplitSections title
)
845 (PackageBuildWarning
$ OptSplitObjs title
)
847 ["-optl-Wl,-s", "-optl-s"]
848 (PackageDistInexcusable
$ OptWls title
)
851 (PackageDistSuspicious
$ OptExts title
)
852 let ghcNoRts
= rmRtsOpts opts
856 [ (flag
, prettyShow extension
)
858 , Just extension
<- [ghcExtension flag
]
864 | flag
@('-' : 'X
' : extension
) <- ghcNoRts
869 ( [(flag
, flag
) | flag
@('-' : 'D
' : _
) <- ghcNoRts
]
870 ++ [(flag
, flag
) | flag
@('-' : 'U
' : _
) <- ghcNoRts
]
875 [(flag
, dir
) | flag
@('-' : 'I
' : dir
) <- ghcNoRts
]
879 [(flag
, lib
) | flag
@('-' : 'l
' : lib
) <- ghcNoRts
]
882 "extra-libraries-static"
883 [(flag
, lib
) | flag
@('-' : 'l
' : lib
) <- ghcNoRts
]
887 [(flag
, dir
) | flag
@('-' : 'L
' : dir
) <- ghcNoRts
]
890 "extra-lib-dirs-static"
891 [(flag
, dir
) | flag
@('-' : 'L
' : dir
) <- ghcNoRts
]
896 |
(flag
@"-framework", fmwk
) <-
897 zip ghcNoRts
(safeTail ghcNoRts
)
901 "extra-framework-dirs"
903 |
(flag
@"-framework-path", dir
) <-
904 zip ghcNoRts
(safeTail ghcNoRts
)
906 -- Old `checkDevelopmentOnlyFlagsOptions` section
909 (PackageDistInexcusable
$ WErrorUnneeded title
)
911 ["-fdefer-type-errors"]
912 (PackageDistInexcusable
$ FDeferTypeErrorsUnneeded title
)
916 , "-fprof-auto-calls"
918 , "-fno-prof-count-entries"
923 (PackageDistSuspicious
$ ProfilingUnneeded title
)
926 "-d" `
isPrefixOf` opt
929 (PackageDistInexcusable
. DynamicUnneeded
)
931 ( \opt
-> case opt
of
933 ('-' : 'j
' : d
: _
) -> isDigit d
936 (PackageDistInexcusable
. JUnneeded
)
940 ("-rtsopts" `
elem` opts
)
941 (PackageBuildWarning
$ OptRts title
)
943 (any (\opt
-> "-with-rtsopts" `
isPrefixOf` opt
) opts
)
944 (PackageBuildWarning
$ OptWithRts title
)
949 (PackageDistSuspiciousWarn
$ OptONot title
)
951 checkNonTestBench
= do
954 (PackageDistSuspicious
$ OptONot title
)
956 ghcExtension
('-' : 'f
' : name
) = case name
of
957 "allow-overlapping-instances" -> enable OverlappingInstances
958 "no-allow-overlapping-instances" -> disable OverlappingInstances
959 "th" -> enable TemplateHaskell
960 "no-th" -> disable TemplateHaskell
961 "ffi" -> enable ForeignFunctionInterface
962 "no-ffi" -> disable ForeignFunctionInterface
963 "fi" -> enable ForeignFunctionInterface
964 "no-fi" -> disable ForeignFunctionInterface
965 "monomorphism-restriction" -> enable MonomorphismRestriction
966 "no-monomorphism-restriction" -> disable MonomorphismRestriction
967 "mono-pat-binds" -> enable MonoPatBinds
968 "no-mono-pat-binds" -> disable MonoPatBinds
969 "allow-undecidable-instances" -> enable UndecidableInstances
970 "no-allow-undecidable-instances" -> disable UndecidableInstances
971 "allow-incoherent-instances" -> enable IncoherentInstances
972 "no-allow-incoherent-instances" -> disable IncoherentInstances
973 "arrows" -> enable Arrows
974 "no-arrows" -> disable Arrows
975 "generics" -> enable Generics
976 "no-generics" -> disable Generics
977 "implicit-prelude" -> enable ImplicitPrelude
978 "no-implicit-prelude" -> disable ImplicitPrelude
979 "implicit-params" -> enable ImplicitParams
980 "no-implicit-params" -> disable ImplicitParams
981 "bang-patterns" -> enable BangPatterns
982 "no-bang-patterns" -> disable BangPatterns
983 "scoped-type-variables" -> enable ScopedTypeVariables
984 "no-scoped-type-variables" -> disable ScopedTypeVariables
985 "extended-default-rules" -> enable ExtendedDefaultRules
986 "no-extended-default-rules" -> disable ExtendedDefaultRules
988 ghcExtension
"-cpp" = enable CPP
989 ghcExtension _
= Nothing
991 enable e
= Just
(EnableExtension e
)
992 disable e
= Just
(DisableExtension e
)
994 rmRtsOpts
:: [String] -> [String]
995 rmRtsOpts
("-with-rtsopts" : _
: xs
) = rmRtsOpts xs
996 rmRtsOpts
(x
: xs
) = x
: rmRtsOpts xs
1001 => WarnLang
-- Language we are warning about (C or C++).
1002 -> CabalField
-- Field where we found the error.
1003 -> [String] -- Options in string form.
1004 -> [String] -- Link options in String form.
1006 checkCLikeOptions label prefix opts ldOpts
= do
1010 [(flag
, dir
) | flag
@('-' : 'I
' : dir
) <- opts
]
1014 [(flag
, lib
) | flag
@('-' : 'l
' : lib
) <- opts
]
1018 [(flag
, dir
) | flag
@('-' : 'L
' : dir
) <- opts
]
1023 [(flag
, lib
) | flag
@('-' : 'l
' : lib
) <- ldOpts
]
1027 [(flag
, dir
) | flag
@('-' : 'L
' : dir
) <- ldOpts
]
1030 (any (`
elem`
["-O", "-Os", "-O0", "-O1", "-O2", "-O3"]) opts
)
1031 (PackageDistSuspicious
$ COptONumber prefix label
)
1035 => CabalField
-- Wrong field.
1036 -> CabalField
-- Appropriate field.
1037 -> [(String, String)] -- List of good and bad flags.
1039 checkAlternatives badField goodField flags
= do
1040 let (badFlags
, _
) = unzip flags
1042 (not $ null badFlags
)
1043 (PackageBuildWarning
$ OptAlternatives badField goodField flags
)
1047 => [String] -- Options in String form.
1049 checkCPPOptions opts
= do
1053 [(flag
, dir
) | flag
@('-' : 'I
' : dir
) <- opts
]
1057 (not $ any (`
isPrefixOf` opt
) ["-D", "-U", "-I"])
1058 (PackageBuildWarning
(COptCPP opt
))