hunk ./Distribution/Simple/InstallDirs.hs 437 -platformTemplateEnv (Platform os arch) = +platformTemplateEnv (Platform arch os) = hunk ./doc/Makefile 7 -all: Cabal.xml +.PHONY: all + +all: Cabal.pdf + +Cabal.pdf: Cabal.xml hunk ./doc/Cabal.xml 1360 + + + + manual: + boolean + (default: False) + + + By default, Cabal will first try to satisfy + dependencies with the default flag value and then, + if that is not possible, with the negated value. + However, if the flag is manual, then the default + value (which can be overridden by commandline flags) + will be used. + hunk ./Distribution/Simple/GHC.hs 208 - [ baseDir "gcc.exe", - mingwDir "bin" "gcc.exe" ], + [ if ghcVersion >= Version [6,12] [] + then mingwBinDir "gcc.exe" + else baseDir "gcc.exe" ], hunk ./Distribution/Simple/GHC.hs 215 - [ libDir "ld.exe", - mingwDir "mingw32" "bin" "ld.exe" ], + [ if ghcVersion >= Version [6,12] [] + then mingwBinDir "ld.exe" + else libDir "ld.exe" ], hunk ./Distribution/Simple/GHC.hs 220 + . addKnownProgram arProgram { + programFindLocation = findProg arProgram + [ if ghcVersion >= Version [6,12] [] + then mingwBinDir "ar.exe" + else libDir "ar.exe" ] + } hunk ./Distribution/Simple/GHC.hs 230 - mingwDir = baseDir "mingw" + mingwBinDir = baseDir "mingw" "bin" hunk ./Distribution/Simple/Build.hs 71 +import qualified Distribution.InstalledPackageInfo as IPI hunk ./Distribution/Simple/Build.hs 80 - , ComponentLocalBuildInfo, withLibLBI, withExeLBI ) + , ComponentLocalBuildInfo, withLibLBI, withExeLBI + , inplacePackageId ) hunk ./Distribution/Simple/Build.hs 85 - ( registerPackage, generateRegistrationInfo ) + ( registerPackage, inplaceInstalledPackageInfo ) hunk ./Distribution/Simple/Build.hs 101 +import System.Directory + ( getCurrentDirectory ) hunk ./Distribution/Simple/Build.hs 124 - installedPkgInfo <- generateRegistrationInfo verbosity pkg_descr lib - lbi clbi True{-inplace-} distPref - hunk ./Distribution/Simple/Build.hs 126 + pwd <- getCurrentDirectory + let installedPkgInfo = + (inplaceInstalledPackageInfo pwd distPref pkg_descr lib lbi clbi) { + -- The inplace registration uses the "-inplace" suffix, + -- not an ABI hash. + IPI.installedPackageId = inplacePackageId (packageId installedPkgInfo) + } hunk ./Distribution/Simple/Configure.hs 102 - , absoluteInstallDirs, prefixRelativeInstallDirs ) + , absoluteInstallDirs, prefixRelativeInstallDirs, inplacePackageId ) hunk ./Distribution/Simple/Configure.hs 444 - ++ [ (InstalledPackageId (display pkgid), pkgid) + ++ [ (inplacePackageId pkgid, pkgid) hunk ./Distribution/Simple/LocalBuildInfo.hs 50 + inplacePackageId, hunk ./Distribution/Simple/LocalBuildInfo.hs 77 +import Distribution.Text + ( display ) hunk ./Distribution/Simple/LocalBuildInfo.hs 136 +-- | The installed package Id we use for local packages registered in the local +-- package db. This is what is used for intra-package deps between components. +-- +inplacePackageId :: PackageId -> InstalledPackageId +inplacePackageId pkgid = InstalledPackageId (display pkgid ++ "-inplace") + hunk ./Distribution/PackageDescription/Check.hs 199 + + , check (not (null exeDuplicates)) $ + PackageBuildImpossible $ "Duplicate executable sections " + ++ commaSep exeDuplicates hunk ./Distribution/PackageDescription/Check.hs 215 - - where requiredCabalVersion = descCabalVersion pkg + where + exeDuplicates = dups (map exeName (executables pkg)) + requiredCabalVersion = descCabalVersion pkg hunk ./Distribution/PackageDescription/Check.hs 225 - "Duplicate modules in library: " ++ commaSep moduleDuplicates + "Duplicate modules in library: " + ++ commaSep (map display moduleDuplicates) hunk ./Distribution/PackageDescription/Check.hs 229 - where moduleDuplicates = [ display module_ - | let modules = exposedModules lib - ++ otherModules (libBuildInfo lib) - , (module_:_:_) <- group (sort modules) ] + where + moduleDuplicates = dups (libModules lib) hunk ./Distribution/PackageDescription/Check.hs 249 - ++ commaSep moduleDuplicates + ++ commaSep (map display moduleDuplicates) hunk ./Distribution/PackageDescription/Check.hs 251 - - where moduleDuplicates = [ display module_ - | let modules = otherModules (buildInfo exe) - , (module_:_:_) <- group (sort modules) ] + where + moduleDuplicates = dups (exeModules exe) hunk ./Distribution/PackageDescription/Check.hs 1128 + +dups :: Ord a => [a] -> [a] +dups xs = [ x | (x:_:_) <- group (sort xs) ] hunk ./Distribution/ModuleName.hs 89 --- FIXME This is used in Distribution/Simple/PreProcess.hs, so we can't --- deprecate it yet without getting warnings, and thus build failures hunk ./Distribution/Simple/Haddock.hs 201 - withLibLBI pkg_descr lbi $ \lib clbi -> do - let bi = libBuildInfo lib - libArgs <- fromLibrary lbi lib clbi - prepareSources verbosity lbi isVersion2 bi (args `mappend` libArgs) $ - runHaddock verbosity confHaddock + withLibLBI pkg_descr lbi $ \lib clbi -> + withTempDirectory verbosity (buildDir lbi) "tmp" $ \tmp -> do + let bi = libBuildInfo lib + libArgs <- fromLibrary tmp lbi lib clbi + libArgs' <- prepareSources verbosity tmp + lbi isVersion2 bi (args `mappend` libArgs) + runHaddock verbosity confHaddock libArgs' hunk ./Distribution/Simple/Haddock.hs 210 - withExeLBI pkg_descr lbi $ \exe clbi -> do - let bi = buildInfo exe - exeArgs <- fromExecutable lbi exe clbi - prepareSources verbosity lbi isVersion2 bi (args `mappend` exeArgs) $ - runHaddock verbosity confHaddock + withExeLBI pkg_descr lbi $ \exe clbi -> + withTempDirectory verbosity (buildDir lbi) "tmp" $ \tmp -> do + let bi = buildInfo exe + exeArgs <- fromExecutable tmp lbi exe clbi + exeArgs' <- prepareSources verbosity tmp + lbi isVersion2 bi (args `mappend` exeArgs) + runHaddock verbosity confHaddock exeArgs' hunk ./Distribution/Simple/Haddock.hs 225 + -> FilePath hunk ./Distribution/Simple/Haddock.hs 230 - -> (HaddockArgs -> IO a) - -> IO a -prepareSources verbosity lbi isVersion2 bi args@HaddockArgs{argTargets=files} k = - withTempDirectory verbosity (buildDir lbi) "tmp" $ \tmp -> - mapM (mockPP tmp) files >>= \targets -> k args {argTargets=targets} + -> IO HaddockArgs +prepareSources verbosity tmp lbi isVersion2 bi args@HaddockArgs{argTargets=files} = + mapM (mockPP tmp) files >>= \targets -> return args {argTargets=targets} hunk ./Distribution/Simple/Haddock.hs 293 -fromLibrary :: LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO HaddockArgs -fromLibrary lbi lib clbi = +fromLibrary :: FilePath + -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo + -> IO HaddockArgs +fromLibrary tmp lbi lib clbi = hunk ./Distribution/Simple/Haddock.hs 300 - argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi), + argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi) + -- Noooooooooo!!!!!111 + -- haddock stomps on our precious .hi + -- and .o files. Workaround by telling + -- haddock to write them elsewhere. + ++ [ "-odir", tmp, "-hidir", tmp ], hunk ./Distribution/Simple/Haddock.hs 311 -fromExecutable :: LocalBuildInfo -> Executable -> ComponentLocalBuildInfo -> IO HaddockArgs -fromExecutable lbi exe clbi = +fromExecutable :: FilePath + -> LocalBuildInfo -> Executable -> ComponentLocalBuildInfo + -> IO HaddockArgs +fromExecutable tmp lbi exe clbi = hunk ./Distribution/Simple/Haddock.hs 317 - argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi), + argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi) + -- Noooooooooo!!!!!111 + -- haddock stomps on our precious .hi + -- and .o files. Workaround by telling + -- haddock to write them elsewhere. + ++ [ "-odir", tmp, "-hidir", tmp ], addfile ./doc/Cabal.markdown hunk ./doc/Cabal.markdown 1 +% Cabal User Guide + +Cabal aims to simplify the distribution of +[Haskell](http://www.haskell.org/) software. It does this by specifying +a number of interfaces between package authors, builders and users, as +well as providing a library implementing these interfaces. + + * [Introduction](#introduction) + * [Packages](#packages) + * [Creating a package](#creating-a-package) + - [Package descriptions](#package-descriptions) + + [Package properties](#package-properties) + + [Library](#library) + + [Executables](#executables) + + [Build information](#build-information) + + [Configurations](#configurations) + + [Source Repositories](#source-repositories) + - [Accessing data files from package code](#accessing-data-files-from-package-code) + - [System-dependent parameters](#system-dependent-parameters) + - [Conditional compilation](#conditional-compilation) + - [More complex packages](#more-complex-packages) + * [Building and installing a package](#building-and-installing-a-package) + - [Building and installing a system package](#building-and-installing-a-system-package) + - [Building and installing a user package](#building-and-installing-a-user-package) + - [Creating a binary package](#creating-a-binary-package) + - [setup configure](#setup-configure) + + [Programs used for building](#programs-used-for-building) + + [Installation paths](#installation-paths) + + [Controlling Flag Assignments](#controlling-flag-assignments) + + [Miscellaneous options](#miscellaneous-options) + - [setup build](#setup-build) + - [setup haddock](#setup-haddock) + - [setup hscolour](#setup-hscolour) + - [setup install](#setup-install) + - [setup copy](#setup-copy) + - [setup register](#setup-register) + - [setup unregister](#setup-unregister) + - [setup clean](#setup-clean) + - [setup test](#setup-test) + - [setup sdist](#setup-sdist) + * [Reporting bugs and deficiencies](#reporting-bugs-and-deficiencies) + * [Stability of Cabal interfaces](#stability-of-cabal-interfaces) + - [Cabal file format](#cabal-file-format) + - [Command-line interface](#command-line-interface) + + [Very Stable Command-line interfaces](#very-stable-command-line-interfaces) + + [Stable Command-line interfaces](#stable-command-line-interfaces) + + [Unstable command-line](#unstable-command-line) + - [Functions and Types](#functions-and-types) + + [Very Stable API](#very-stable-api) + + [Semi-stable API](#semi-stable-api) + + [Unstable API](#unstable-api) + - [Hackage](#hackage) + +# Introduction # + +Developers write Cabal packages. These can be for libraries or +executables. This involves writing the code obviously and also creating +a `.cabal` file. The .cabal file contains some information about the +package. Some of this information is needed to actually build the +package and some is just useful for identifying the package when it +comes to distribution. + +~~~~~~~~~~~~~~~~ +name: Foo +version: 1.0 + +library + build-depends: base + exposed-modules: Foo +~~~~~~~~~~~~~~~~ + +Users install Cabal packages so they can use them. It is not expected +that users will have to modify any of the information in the `.cabal` +file. Cabal does provide a number of ways for a user to customise how +and where a package is installed. They can decide where a package will +be installed, which Haskell implementation to use and whether to build +optimised code or build with the ability to profile code. + +~~~~~~~~~~~~~~~~ +tar -xzf Foo-1.0.tar.gz +cd Foo-1.0 +runhaskell Setup configure --with-compiler=ghc-6.4.2 --user +runhaskell Setup build +runhaskell Setup install +~~~~~~~~~~~~~~~~ + +One of the purposes of Cabal is to make it easier to build a package +with different Haskell implementations. So it provides abstractions of +features present in different Haskell implementations and wherever +possible it is best to take advantage of these to increase portability. +Where necessary however it is possible to use specific features of +specific implementations. For example one of the pieces of information a +package author can put in the package's `.cabal` file is what language +extensions the code uses. This is far preferable to specifying flags for +a specific compiler as it allows Cabal to pick the right flags for the +Haskell implementation that the user picks. It also allows Cabal to +figure out if the language extension is even supported by the Haskell +implementation that the user picks. Where compiler-specific options are +needed however, there is an "escape hatch" available. The developer can +specify implementation-specific options and more generally there is a +configuration mechanism to customise many aspects of how a package is +built depending on the Haskell implementation, the Operating system, +computer architecture and user-specified configuration flags. + +~~~~~~~~~~~~~~~~ +name: Foo +version: 1.0 + +library + build-depends: base + exposed-modules: Foo + extensions: ForeignFunctionInterface + ghc-options: -Wall + nhc98-options: -K4m + if os(windows) + build-depends: Win32 +~~~~~~~~~~~~~~~~ + +# Packages # + +A _package_ is the unit of distribution for the Cabal. Its purpose, +when installed, is to make available either or both of: + +* One or more Haskell programs. + +* A library, exposing a number of Haskell modules. A library may also + contain _hidden_ modules, which are used internally but not + available to clients.[^hugs] + +[^hugs]: Hugs doesn't support module hiding. + +However having both a library and executables in a package does not work +very well; if the executables depend on the library, they must +explicitly list all the modules they directly or indirectly import from +that library. + +Internally, the package may consist of much more than a bunch of Haskell +modules: it may also have C source code and header files, source code +meant for preprocessing, documentation, test cases, auxiliary tools etc. + +A package is identified by a globally-unique _package name_, which +consists of one or more alphanumeric words separated by hyphens. To +avoid ambiguity, each of these words should contain at least one letter. +Chaos will result if two distinct packages with the same name are +installed on the same system, but there is not yet a mechanism for +allocating these names. A particular version of the package is +distinguished by a _version number_, consisting of a sequence of one or +more integers separated by dots. These can be combined to form a single +text string called the _package ID_, using a hyphen to separate the name +from the version, e.g. "`HUnit-1.1`". + +Note: Packages are not part of the Haskell language; they simply +populate the hierarchical space of module names. In GHC 6.6 and later a +program may contain multiple modules with the same name if they come +from separate packages; in all other current Haskell systems packages +may not overlap in the modules they provide, including hidden modules. + +# Creating a package # + +Suppose you have a directory hierarchy containing the source files that +make up your package. You will need to add two more files to the root +directory of the package: + +_package_`.cabal` + +: a Unicode UTF-8 text file containing a package description (for + details of the syntax of this file, see the [package description + section](#package-descriptions)) + +`Setup.hs` or `Setup.lhs` + +: a single-module Haskell program to perform various setup tasks (with + the interface described in the section on [building and installing + packages](#building-and-installing-a-package)). This module should + import only modules that will be present in all Haskell + implementations, including modules of the Cabal library. In most + cases it will be trivial, calling on the Cabal library to do most of + the work. + +Once you have these, you can create a source bundle of this directory +for distribution. Building of the package is discussed in the section on +[building and installing packages](#building-and-installing-a-package). + +#### Example: A package containing a simple library #### + +The HUnit package contains a file `HUnit.cabal` containing: + +~~~~~~~~~~~~~~~~ +Name:HUnit +Version:1.1.1 +Cabal-Version: >= 1.2 +License:BSD3 +License-File:LICENSE +Author:Dean Herington +Homepage:http://hunit.sourceforge.net/ +Category:Testing +Synopsis:A unit testing framework for Haskell + +Library + Build-Depends:base + Exposed-modules: + Test.HUnit.Base, Test.HUnit.Lang, Test.HUnit.Terminal, + Test.HUnit.Text, Test.HUnit + Extensions:CPP +~~~~~~~~~~~~~~~~ + +and the following `Setup.hs`: + +~~~~~~~~~~~~~~~~ +import Distribution.Simple +main = defaultMain +~~~~~~~~~~~~~~~~ + +#### Example: A package containing executable programs #### + +~~~~~~~~~~~~~~~~ +Name: TestPackage +Version: 0.0 +Cabal-Version: >= 1.2 +License: BSD3 +Author: Angela Author +Synopsis: Small package with two programs +Build-Type: Simple + +Executable program1 + Build-Depends: HUnit + Main-Is: Main.hs + Hs-Source-Dirs: prog1 + +Executable program2 + Main-Is: Main.hs + Build-Depends: HUnit + Hs-Source-Dirs: prog2 + Other-Modules: Utils +~~~~~~~~~~~~~~~~ + +with `Setup.hs` the same as above. + +#### Example: A package containing a library and executable programs #### + +~~~~~~~~~~~~~~~~ +Name: TestPackage +Version: 0.0 +Cabal-Version: >= 1.2 +License: BSD3 +Author: Angela Author +Synopsis: Package with library and two programs +Build-Type: Simple + +Library + Build-Depends: HUnit + Exposed-Modules: A, B, C + +Executable program1 + Main-Is: Main.hs + Hs-Source-Dirs: prog1 + Other-Modules: A, B + +Executable program2 + Main-Is: Main.hs + Hs-Source-Dirs: prog2 + Other-Modules: A, C, Utils +~~~~~~~~~~~~~~~~ + +with `Setup.hs` the same as above. Note that any library modules +required (directly or indirectly) by an executable must be listed again. + +The trivial setup script used in these examples uses the _simple build +infrastructure_ provided by the Cabal library (see +[Distribution.Simple][dist-simple]). The simplicity lies in its +interface rather that its implementation. It automatically handles +preprocessing with standard preprocessors, and builds packages for all +the Haskell implementations (except nhc98, for now). + +The simple build infrastructure can also handle packages where building +is governed by system-dependent parameters, if you specify a little more +(see the section on [system-dependent +parameters](#system-dependent-parameters)). A few packages require [more +elaborate solutions](#complex-packages). + +## Package descriptions ## + +The package description file must have a name ending in "`.cabal`". It +must be a Unicode text file encoded using valid UTF-8. There must be +exactly one such file in the directory. The first part of the name is +usually the package name, and some of the tools that operate on Cabal +packages require this. + +In the package description file, lines whose first non-whitespace characters +are "`--`" are treated as comments and ignored. + +This file should contain of a number global property descriptions and +several sections. + +* The [global properties](#package-properties) describe the package as a + whole, such as name, license, author, etc. + +* Optionally, a number of _configuration flags_ can be declared. These + can be used to enable or disable certain features of a package. (see + the section on [configurations](#configurations)). + +* The (optional) library section specifies the [library + properties](#library) and relevant [build + information](#build-information). + +* Following is an arbitrary number of executable sections + which describe an [executable program](#executable) and relevant + [build information](#build-information). + +Each section consists of a number of property descriptions +in the form of field/value pairs, with a syntax roughly like mail +message headers. + +* Case is not significant in field names, but is significant in field + values. + +* To continue a field value, indent the next line relative to the field + name. + +* Field names may be indented, but all field values in the same section + must use the same indentation. + +* Tabs are *not* allowed as indentation characters due to a missing + standard interpretation of tab width. + +* To get a blank line in a field value, use an indented "`.`" + +The syntax of the value depends on the field. Field types include: + +_token_, _filename_, _directory_ +: Either a sequence of one or more non-space non-comma characters, or + a quoted string in Haskell 98 lexical syntax. Unless otherwise + stated, relative filenames and directories are interpreted from the + package root directory. + +_freeform_, _URL_, _address_ +: An arbitrary, uninterpreted string. + +_identifier_ +: A letter followed by zero or more alphanumerics or underscores. + +_compiler_ +: A compiler flavor (one of: `GHC`, `NHC`, `YHC`, `Hugs`, `HBC`, + `Helium`, `JHC`, or `LHC`) followed by a version range. For + example, `GHC ==6.10.3`, or `LHC >=0.6 && <0.8`. + +### Modules and preprocessors ### + +Haskell module names listed in the `exposed-modules` and `other-modules` +fields may correspond to Haskell source files, i.e. with names ending in +"`.hs`" or "`.lhs`", or to inputs for various Haskell preprocessors. The +simple build infrastructure understands the extensions: + +* `.gc` ([greencard][]) +* `.chs` ([c2hs][]) +* `.hsc` (`hsc2hs`) +* `.y` and `.ly` ([happy][]) +* `.x` ([alex][]) +* `.cpphs` ([cpphs][]) + +When building, Cabal will automatically run the appropriate preprocessor +and compile the Haskell module it produces. + +Some fields take lists of values, which are optionally separated by commas, except for the +`build-depends` field, where the commas are mandatory. + +Some fields are marked as required. All others are optional, and unless +otherwise specified have empty default values. + +### Package properties ### + +These fields may occur in the first top-level properties section and +describe the package as a whole: + +`name:` _package-name_ (required) +: The unique name of the [package](#packages), without the version + number. + +`version:` _numbers_ (required) +: The package version number, usually consisting of a sequence of + natural numbers separated by dots. + +`cabal-version:` _<, >=, etc. & numbers_ +: The version of Cabal required for this package. Since, with Cabal + version 1.2 the syntax of package descriptions has changed, this is + now a required field. List the field early in your `.cabal` file so + that it will appear as a syntax error before any others, since old + versions of Cabal unfortunately do not recognize this field. + + For compatibility, files written in the old syntax are still + recognized. Thus if you don't require features introduced with or + after Cabal version 1.2, you may write your package description file + using the old syntax. Please consult the user's guide of that Cabal + version for a description of that syntax. + +`build-type:` _identifier_ +: The type of build used by this package. Build types are the + constructors of the [BuildType][] type, defaulting to `Custom`. If + this field is given a value other than `Custom`, some tools such as + `cabal-install` will be able to build the package without using the + setup script. So if you are just using the default `Setup.hs` then + set the build type as `Simple`. + +`license:` _identifier_ (default: `AllRightsReserved`) +: The type of license under which this package is distributed. + License names are the constants of the [License][dist-license] type. + +`license-file:` _filename_ +: The name of a file containing the precise license for this package. + It will be installed with the package. + +`copyright:` _freeform_ +: The content of a copyright notice, typically the name of the holder + of the copyright on the package and the year(s) from which copyright + is claimed. For example: `Copyright: (c) 2006-2007 Joe Bloggs` + +`author:` _freeform_ +: The original author of the package. + + Remember that `.cabal` files are Unicode, using the UTF-8 encoding. + +`maintainer:` _address_ +: The current maintainer or maintainers of the package. This is an e-mail address to which users should send bug + reports, feature requests and patches. + +`stability:` _freeform_ +: The stability level of the package, e.g. `alpha`, `experimental`, `provisional`, + `stable`. + +`homepage:` _URL_ +: The package homepage. + +`bug-reports:` _URL_ +: The URL where users should direct bug reports. This would normally be either: + + * A `mailto:` URL, eg for a person or a mailing list. + + * An `http:` (or `https:`) URL for an online bug tracking system. + + For example Cabal itself uses a web-based bug tracking system + + ~~~~~~~~~~~~~~~~ + bug-reports: http://hackage.haskell.org/trac/hackage/ + ~~~~~~~~~~~~~~~~ + +`package-url:` _URL_ +: The location of a source bundle for the package. The distribution + should be a Cabal package. + +`synopsis:` _freeform_ +: A very short description of the package, for use in a table of + packages. This is your headline, so keep it short (one line) but as + informative as possible. Save space by not including the package + name or saying it's written in Haskell. + +`description:` _freeform_ +: Description of the package. This may be several paragraphs, and + should be aimed at a Haskell programmer who has never heard of your + package before. + + For library packages, this field is used as prologue text by [`setup + haddock`](#setup-haddock), and thus may contain the same markup as + [haddock][] documentation comments. + +`category:` _freeform_ +: A classification category for future use by the package catalogue _Hackage_. These + categories have not yet been specified, but the upper levels of the + module hierarchy make a good start. + +`tested-with:` _compiler list_ +: A list of compilers and versions against which the package has been + tested (or at least built). + +`data-files:` _filename list_ +: A list of files to be installed for run-time use by the package. + This is useful for packages that use a large amount of static data, + such as tables of values or code templates. Cabal provides a way to + [find these files at + run-time](#accessing-data-files-from-package-code). + + A limited form of `*` wildcards in file names, for example + `data-files: images/*.png` matches all the `.png` files in the + `images` directory. + + The limitation is that `*` wildcards are only allowed in place of + the file name, not in the directory name or file extension. In + particular, wildcards do not include directories contents + recursively. Furthermore, if a wildcard is used it must be used with + an extension, so `data-files: data/*` is not allowed. When matching + a wildcard plus extension, a file's full extension must match + exactly, so `*.gz` matches `foo.gz` but not `foo.tar.gz`. A wildcard + that does not match any files is an error. + + The reason for providing only a very limited form of wildcard is to + concisely express the common case of a large number of related files + of the same file type without making it too easy to accidentally + include unwanted files. + +`data-dir:` _directory_ +: The directory where Cabal looks for data files to install, relative + to the source directory. By default, Cabal will look in the source + directory itself. + +`extra-source-files:` _filename list_ +: A list of additional files to be included in source distributions + built with [`setup sdist`](#setup-sdist). As with `data-files` it + can use a limited form of `*` wildcards in file names. + +`extra-tmp-files:` _filename list_ +: A list of additional files or directories to be removed by [`setup + clean`](#setup-clean). These would typically be additional files + created by additional hooks, such as the scheme described in the + section on [system-dependent parameters](#system-dependent-parameters). + +### Library ### + +The library section should contain the following fields: + +`exposed-modules:` _identifier list_ (required if this package contains a library) +: A list of modules added by this package. + +`exposed:` _boolean_ (default: `True`) +: Some Haskell compilers (notably GHC) support the notion of packages + being "exposed" or "hidden" which means the modules they provide can + be easily imported without always having to specify which package + they come from. However this only works effectively if the modules + provided by all exposed packages do not overlap (otherwise a module + import would be ambiguous). + + Almost all new libraries use hierarchical module names that do not + clash, so it is very uncommon to have to use this field. However it + may be necessary to set `exposed: False` for some old libraries that + use a flat module namespace or where it is known that the exposed + modules would clash with other common modules. + +The library section may also contain build information fields (see the +section on [build information](#build-information)). + + +### Executables ### + +Executable sections (if present) describe executable programs contained +in the package and must have an argument after the section label, which +defines the name of the executable. This is a freeform argument but may +not contain spaces. + +The executable may be described using the following fields, as well as +build information fields (see the section on [build +information](#build-information)). + +`main-is:` _filename_ (required) +: The name of the `.hs` or `.lhs` file containing the `Main` module. Note that it is the + `.hs` filename that must be listed, even if that file is generated + using a preprocessor. The source file must be relative to one of the + directories listed in `hs-source-dirs`. + +### Build information ### + +The following fields may be optionally present in a library or +executable section, and give information for the building of the +corresponding library or executable. See also the sections on +[system-dependent parameters](#system-dependent-parameters) and +[configurations](#configurations) for a way to supply system-dependent +values for these fields. + +`build-depends:` _package list_ +: A list of packages needed to build this one. Each package can be + annotated with a version constraint. + + Version constraints use the operators `==, >=, >, <, <=` and a + version number. Multiple constraints can be combined using `&&` or + `||`. If no version constraint is specified, any version is assumed + to be acceptable. For example: + + ~~~~~~~~~~~~~~~~ + library + build-depends: + base >= 2, + foo >= 1.2 && < 1.3, + bar + ~~~~~~~~~~~~~~~~ + + Dependencies like `foo >= 1.2 && < 1.3` turn out to be very common + because it is recommended practise for package versions to + correspond to API versions. There is a special syntax to support this use: + + ~~~~~~~~~~~~~~~~ + build-depends: foo ==1.2.* + ~~~~~~~~~~~~~~~~ + + It is only syntactic sugar. It is exactly equivalent to `foo >= 1.2 && < 1.3`. + +`other-modules:` _identifier list_ +: A list of modules used by the component but not exposed to users. + For a library component, these would be hidden modules of the + library. For an executable, these would be auxiliary modules to be + linked with the file named in the `main-is` field. + + Note: Every module in the package *must* be listed in one of + `other-modules`, `exposed-modules` or `main-is` fields. + +`hs-source-dirs:` _directory list_ (default: "`.`") +: Root directories for the module hierarchy. + + For backwards compatibility, the old variant `hs-source-dir` is also + recognized. + +`extensions:` _identifier list_ +: A list of Haskell extensions used by every module. Extension names + are the constructors of the [Extension][extension] type. These + determine corresponding compiler options. In particular, `CPP` specifies that + Haskell source files are to be preprocessed with a C preprocessor. + + Extensions used only by one module may be specified by placing a + `LANGUAGE` pragma in the source file affected, e.g.: + + ~~~~~~~~~~~~~~~~ + {-# LANGUAGE CPP, MultiParamTypeClasses #-} + ~~~~~~~~~~~~~~~~ + + Note: GHC versions prior to 6.6 do not support the `LANGUAGE` pragma. + +`build-tools:` _program list_ +: A list of programs, possibly annotated with versions, needed to + build this package, e.g. `c2hs >= 0.15, cpphs`.If no version + constraint is specified, any version is assumed to be acceptable. + +`buildable:` _boolean_ (default: `True`) +: Is the component buildable? Like some of the other fields below, + this field is more useful with the slightly more elaborate form of + the simple build infrastructure described in the section on + [system-dependent parameters](#system-dependent-parameters). + +`ghc-options:` _token list_ +: Additional options for GHC. You can often achieve the same effect + using the `extensions` field, which is preferred. + + Options required only by one module may be specified by placing an + `OPTIONS_GHC` pragma in the source file affected. + +`ghc-prof-options:` _token list_ +: Additional options for GHC when the package is built with profiling + enabled. + +`ghc-shared-options:` _token list_ +: Additional options for GHC when the package is built as shared library. + +`hugs-options:` _token list_ +: Additional options for Hugs. You can often achieve the same effect + using the `extensions` field, which is preferred. + + Options required only by one module may be specified by placing an + `OPTIONS_HUGS` pragma in the source file affected. + +`nhc98-options:` _token list_ +: Additional options for nhc98. You can often achieve the same effect + using the `extensions` field, which is preferred. + + Options required only by one module may be specified by placing an + `OPTIONS_NHC98` pragma in the source file affected. + +`includes:` _filename list_ +: A list of header files to be included in any compilations via C. + This field applies to both header files that are already installed + on the system and to those coming with the package to be installed. + These files typically contain function prototypes for foreign + imports used by the package. + +`install-includes:` _filename list_ +: A list of header files from this package to be installed into + `$libdir/includes` when the package is installed. Files listed in + `install-includes:` should be found in relative to the top of the + source tree or relative to one of the directories listed in + `include-dirs`. + + `install-includes` is typically used to name header files that + contain prototypes for foreign imports used in Haskell code in this + package, for which the C implementations are also provided with the + package. Note that to include them when compiling the package + itself, they need to be listed in the `includes:` field as well. + +`include-dirs:` _directory list_ +: A list of directories to search for header files, when preprocessing + with `c2hs`, `hsc2hs`, `ffihugs`, `cpphs` or the C preprocessor, and + also when compiling via C. + +`c-sources:` _filename list_ +: A list of C source files to be compiled and linked with the Haskell files. + + If you use this field, you should also name the C files in `CFILES` + pragmas in the Haskell source files that use them, e.g.: `{-# CFILES + dir/file1.c dir/file2.c #-}` These are ignored by the compilers, but + needed by Hugs. + +`extra-libraries:` _token list_ +: A list of extra libraries to link with. + +`extra-lib-dirs:` _directory list_ +: A list of directories to search for libraries. + +`cc-options:` _token list_ +: Command-line arguments to be passed to the C compiler. Since the + arguments are compiler-dependent, this field is more useful with the + setup described in the section on [system-dependent + parameters](#system-dependent-parameters). + +`ld-options:` _token list_ +: Command-line arguments to be passed to the linker. Since the + arguments are compiler-dependent, this field is more useful with the + setup described in the section on [system-dependent + parameters](#system-dependent-parameters)>. + +`pkgconfig-depends:` _package list_ +: A list of [pkg-config][] packages, needed to build this package. + They can be annotated with versions, e.g. `gtk+-2.0 >= 2.10, cairo + >= 1.0`. If no version constraint is specified, any version is + assumed to be acceptable. Cabal uses `pkg-config` to find if the + packages are available on the system and to find the extra + compilation and linker options needed to use the packages. + + If you need to bind to a C library that supports `pkg-config` (use + `pkg-config --list-all` to find out if it is supported) then it is + much preferable to use this field rather than hard code options into + the other fields. + +`frameworks:` _token list_ +: On Darwin/MacOS X, a list of frameworks to link to. See Apple's + developer documentation for more details on frameworks. This entry + is ignored on all other platforms. + +### Configurations ### + +Library and executable sections may include conditional +blocks, which test for various system parameters and +configuration flags. The flags mechanism is rather generic, +but most of the time a flag represents certain feature, that +can be switched on or off by the package user. +Here is an example package description file using +configurations: + +#### Example: A package containing a library and executable programs #### + +~~~~~~~~~~~~~~~~ +Name: Test1 +Version: 0.0.1 +Cabal-Version: >= 1.2 +License: BSD3 +Author: Jane Doe +Synopsis: Test package to test configurations +Category: Example + +Flag Debug + Description: Enable debug support + Default: False + +Flag WebFrontend + Description: Include API for web frontend. + -- Cabal checks if the configuration is possible, first + -- with this flag set to True and if not it tries with False + +Library + Build-Depends: base + Exposed-Modules: Testing.Test1 + Extensions: CPP + + if flag(debug) + GHC-Options: -DDEBUG + if !os(windows) + CC-Options: "-DDEBUG" + else + CC-Options: "-DNDEBUG" + + if flag(webfrontend) + Build-Depends: cgi > 0.42 + Other-Modules: Testing.WebStuff + +Executable test1 + Main-is: T1.hs + Other-Modules: Testing.Test1 + Build-Depends: base + + if flag(debug) + CC-Options: "-DDEBUG" + GHC-Options: -DDEBUG +~~~~~~~~~~~~~~~~ + +#### Layout #### + +Flags, conditionals, library and executable sections use layout to +indicate structure. This is very similar to the Haskell layout rule. +Entries in a section have to all be indented to the same level which +must be more than the section header. Tabs are not allowed to be used +for indentation. + +As an alternative to using layout you can also use explicit braces `{}`. +In this case the indentation of entries in a section does not matter, +though different fields within a block must be on different lines. Here +is a bit of the above example again, using braces: + +#### Example: Using explicit braces rather than indentation for layout #### + +~~~~~~~~~~~~~~~~ +Name: Test1 +Version: 0.0.1 +Cabal-Version: >= 1.2 +License: BSD3 +Author: Jane Doe +Synopsis: Test package to test configurations +Category: Example + +Flag Debug { + Description: Enable debug support + Default: False +} + +Library { + Build-Depends: base + Exposed-Modules: Testing.Test1 + Extensions: CPP + if flag(debug) { + GHC-Options: -DDEBUG + if !os(windows) { + CC-Options: "-DDEBUG" + } else { + CC-Options: "-DNDEBUG" + } + } +} +~~~~~~~~~~~~~~~~ + +#### Configuration Flags #### + +A flag section takes the flag name as an argument and may contain the +following fields. + +`description:` _freeform_ +: The description of this flag. + +`default:` _boolean_ (default: `True`) +: The default value of this flag. + + Note that this value may be [overridden in several + ways](#controlling-flag-assignments"). The rationale for having + flags default to True is that users usually want new features as + soon as they are available. Flags representing features that are not + (yet) recommended for most users (such as experimental features or + debugging support) should therefore explicitly override the default + to False. + +`manual:` _boolean_ (default: `False`) +: By default, Cabal will first try to satisfy dependencies with the + default flag value and then, if that is not possible, with the + negated value. However, if the flag is manual, then the default + value (which can be overridden by commandline flags) will be used. + +#### Conditional Blocks #### + +Conditional blocks may appear anywhere inside a library or executable +section. They have to follow rather strict formatting rules. +Conditional blocks must always be of the shape + +~~~~~~~~~~~~~~~~ + `if `_condition_ + _property-descriptions-or-conditionals*_ +~~~~~~~~~~~~~~~~ + +or + +~~~~~~~~~~~~~~~~ + `if `_condition_ + _property-descriptions-or-conditionals*_ + `else` + _property-descriptions-or-conditionals*_ +~~~~~~~~~~~~~~~~ + +Note that the `if` and the condition have to be all on the same line. + +#### Conditions #### + +Conditions can be formed using boolean tests and the boolean operators +`||` (disjunction / logical "or"), `&&` (conjunction / logical "and"), +or `!` (negation / logical "not"). The unary `!` takes highest +precedence, `||` takes lowest. Precedence levels may be overridden +through the use of parentheses. For example, `os(darwin) && !arch(i386) +|| os(freebsd)` is equivalent to `(os(darwin) && !(arch(i386))) || +os(freebsd)`. + +The following tests are currently supported. + +`os(`_name_`)` +: Tests if the current operating system is _name_. The argument is + tested against `System.Info.os` on the target system. There is + unfortunately some disagreement between Haskell implementations + about the standard values of `System.Info.os`. Cabal canonicalises + it so that in particular `os(windows)` works on all implementations. + If the canonicalised os names match, this test evaluates to true, + otherwise false. The match is case-insensitive. + +`arch(`_name_`)` +: Tests if the current architecture is _name_. The argument is + matched against `System.Info.arch` on the target system. If the arch + names match, this test evaluates to true, otherwise false. The match + is case-insensitive. + +`impl(`_compiler_`)` +: Tests for the configured Haskell implementation. An optional version + constraint may be specified (for example `impl(ghc >= 6.6.1)`). If + the configured implementation is of the right type and matches the + version constraint, then this evaluates to true, otherwise false. + The match is case-insensitive. + +`flag(`_name_`)` +: Evaluates to the current assignment of the flag of the given name. + Flag names are case insensitive. Testing for flags that have not + been introduced with a flag section is an error. + +`true` +: Constant value true. + +`false` +: Constant value false. + +#### Resolution of Conditions and Flags #### + +If a package descriptions specifies configuration flags the package user +can [control these in several ways](#controlling-flag-assignments). If +the user does not fix the value of a flag, Cabal will try to find a flag +assignment in the following way. + + * For each flag specified, it will assign its default value, evaluate + all conditions with this flag assignment, and check if all + dependencies can be satisfied. If this check succeeded, the package + will be configured with those flag assignments. + + * If dependencies were missing, the last flag (as by the order in + which the flags were introduced in the package description) is tried + with its alternative value and so on. This continues until either + an assignment is found where all dependencies can be satisfied, or + all possible flag assignments have been tried. + +To put it another way, Cabal does a complete backtracking search to find +a satisfiable package configuration. It is only the dependencies +specified in the `build-depends` field in conditional blocks that +determine if a particular flag assignment is satisfiable (`build-tools` +are not considered). The order of the declaration and the default value +of the flags determines the search order. Flags overridden on the +command line fix the assignment of that flag, so no backtracking will be +tried for that flag. + +If no suitable flag assignment could be found, the configuration phase +will fail and a list of missing dependencies will be printed. Note that +this resolution process is exponential in the worst case (i.e., in the +case where dependencies cannot be satisfied). There are some +optimizations applied internally, but the overall complexity remains +unchanged. + +### Meaning of field values when using conditionals ### + +During the configuration phase, a flag assignment is chosen, all +conditionals are evaluated, and the package description is combined into +a flat package descriptions. If the same field both inside a conditional +and outside then they are combined using the following rules. + + + * Boolean fields are combined using conjunction (logical "and"). + + * List fields are combined by appending the inner items to the outer + items, for example + + ~~~~~~~~~~~~~~~~ + Extensions: CPP + if impl(ghc) || impl(hugs) + Extensions: MultiParamTypeClasses + ~~~~~~~~~~~~~~~~ + + when compiled using Hugs or GHC will be combined to + + ~~~~~~~~~~~~~~~~ + Extensions: CPP, MultiParamTypeClasses + ~~~~~~~~~~~~~~~~ + + Similarly, if two conditional sections appear at the same nesting + level, properties specified in the latter will come after properties + specified in the former. + + * All other fields must not be specified in ambiguous ways. For + example + + ~~~~~~~~~~~~~~~~ + Main-is: Main.hs + if flag(useothermain) + Main-is: OtherMain.hs + ~~~~~~~~~~~~~~~~ + + will lead to an error. Instead use + + ~~~~~~~~~~~~~~~~ + if flag(useothermain) + Main-is: OtherMain.hs + else + Main-is: Main.hs + ~~~~~~~~~~~~~~~~ + +### Source Repositories ### + +It is often useful to be able to specify a source revision control +repository for a package. Cabal lets you specifying this information in +a relatively structured form which enables other tools to interpret and +make effective use of the information. For example the information +should be sufficient for an automatic tool to checkout the sources. + +Cabal supports specifying different information for various common +source control systems. Obviously not all automated tools will support +all source control systems. + +Cabal supports specifying repositories for different use cases. By +declaring which case we mean automated tools can be more useful. There +are currently two kinds defined: + + * The `head` kind refers to the latest development branch of the + package. This may be used for example to track activity of a project + or as an indication to outside developers what sources to get for + making new contributions. + + * The `this` kind refers to the branch and tag of a repository that + contains the sources for this version or release of a package. For most + source control systems this involves specifying a tag, id or hash of + some form and perhaps a branch. The purpose is to be able to + reconstruct the sources corresponding to a particular package + version. This might be used to indicate what sources to get if + someone needs to fix a bug in an older branch that is no longer an + active head branch. + +You can specify one kind or the other or both. As an example here are +the repositories for the Cabal library. Note that the `this` kind of +repo specifies a tag. + +~~~~~~~~~~~~~~~~ +source-repository head + type: darcs + location: http://darcs.haskell.org/cabal/ + +source-repository this + type: darcs + location: http://darcs.haskell.org/cabal-branches/cabal-1.6/ + tag: 1.6.1 +~~~~~~~~~~~~~~~~ + +The exact fields are as follows: + +`type:` _token_ +: The name of the source control system used for this repository. The + currently recognised types are: + + * `darcs` + * `git` + * `svn` + * `cvs` + * `mercurial` (or alias `hg`) + * `bazaar` (or alias `bzr`) + * `arch` + * `monotone` + + This field is required. + +`location:` _URL_ +: The location of the repository. The exact form of this field depends + on the repository type. For example: + + * for darcs: `http://code.haskell.org/foo/` + * for git: `git://github.com/foo/bar.git` + * for CVS: `anoncvs@cvs.foo.org:/cvs` + + This field is required. + +`module:` _token_ +: CVS requires a named module, as each CVS server can host multiple + named repositories. + + This field is required for the CVS repo type and should not be used + otherwise. + +`branch:` _token_ +: Many source control systems support the notion of a branch, as a + distinct concept from having repositories in separate locations. For + example CVS, SVN and git use branches while for darcs uses different + locations for different branches. If you need to specify a branch to + identify a your repository then specify it in this field. + + This field is optional. + +`tag:` _token_ +: A tag identifies a particular state of a source repository. The tag + can be used with a `this` repo kind to identify the state of a repo + corresponding to a particular package version or release. The exact + form of the tag depends on the repository type. + + This field is required for the `this` repo kind. + +`subdir:` _directory_ +: Some projects put the sources for multiple packages under a single + source repository. This field lets you specify the relative path + from the root of the repository to the top directory for the + package, ie the directory containing the package's `.cabal` file. + + This field is optional. It default to empty which corresponds to the + root directory of the repository. + +## Accessing data files from package code ## + +The placement on the target system of files listed in the `data-files` +field varies between systems, and in some cases one can even move +packages around after installation (see [prefix +independence](#prefix-independence)). To enable packages to find these +files in a portable way, Cabal generates a module called +`Paths_`_pkgname_ (with any hyphens in _pkgname_ replaced by +underscores) during building, so that it may be imported by modules of +the package. This module defines a function + +~~~~~~~~~~~~~~~ +getDataFileName :: FilePath -> IO FilePath +~~~~~~~~~~~~~~~ + +If the argument is a filename listed in the `data-files` field, the +result is the name of the corresponding file on the system on which the +program is running. + +Note: If you decide to import the `Paths_`_pkgname_ module then it +*must* be listed in the `other-modules` field just like any other module +in your package. + +The `Paths_`_pkgname_ module is not platform independent so it does not +get included in the source tarballs generated by `sdist`. + +## System-dependent parameters ## + +For some packages, especially those interfacing with C libraries, +implementation details and the build procedure depend on the build +environment. A variant of the simple build infrastructure (the +`build-type` `Configure`) handles many such situations using a slightly +longer `Setup.hs`: + +~~~~~~~~~~~~~~~~ +import Distribution.Simple +main = defaultMainWithHooks autoconfUserHooks +~~~~~~~~~~~~~~~~ + +Most packages, however, would probably do better with +[configurations](#configurations). + +This program differs from `defaultMain` in two ways: + +* The package root directory must contain a shell script called + `configure`. The configure step will run the script. This `configure` + script may be produced by [autoconf][] or may be hand-written. The + `configure` script typically discovers information about the system + and records it for later steps, e.g. by generating system-dependent + header files for inclusion in C source files and preprocessed Haskell + source files. (Clearly this won't work for Windows without MSYS or + Cygwin: other ideas are needed.) + +* If the package root directory contains a file called + _package_`.buildinfo` after the configuration step, subsequent steps + will read it to obtain additional settings for [build + information](#build-information) fields,to be merged with the ones + given in the `.cabal` file. In particular, this file may be generated + by the `configure` script mentioned above, allowing these settings to + vary depending on the build environment. + + The build information file should have the following structure: + + > _buildinfo_ + > + > `executable:` _name_ + > _buildinfo_ + > + > `executable:` _name_ + > _buildinfo_ + > ... + + where each _buildinfo_ consists of settings of fields listed in the + section on [build information](#build-information). The first one (if + present) relates to the library, while each of the others relate to + the named executable. (The names must match the package description, + but you don't have to have entries for all of them.) + +Neither of these files is required. If they are absent, this setup +script is equivalent to `defaultMain`. + +#### Example: Using autoconf #### + +This example is for people familiar with the [autoconf][] tools. + +In the X11 package, the file `configure.ac` contains: + +~~~~~~~~~~~~~~~~ +AC_INIT([Haskell X11 package], [1.1], [libraries@haskell.org], [X11]) + +# Safety check: Ensure that we are in the correct source directory. +AC_CONFIG_SRCDIR([X11.cabal]) + +# Header file to place defines in +AC_CONFIG_HEADERS([include/HsX11Config.h]) + +# Check for X11 include paths and libraries +AC_PATH_XTRA +AC_TRY_CPP([#include ],,[no_x=yes]) + +# Build the package if we found X11 stuff +if test "$no_x" = yes +then BUILD_PACKAGE_BOOL=False +else BUILD_PACKAGE_BOOL=True +fi +AC_SUBST([BUILD_PACKAGE_BOOL]) + +AC_CONFIG_FILES([X11.buildinfo]) +AC_OUTPUT +~~~~~~~~~~~~~~~~ + +Then the setup script will run the `configure` script, which checks for +the presence of the X11 libraries and substitutes for variables in the +file `X11.buildinfo.in`: + +~~~~~~~~~~~~~~~~ +buildable: @BUILD_PACKAGE_BOOL@ +cc-options: @X_CFLAGS@ +ld-options: @X_LIBS@ +~~~~~~~~~~~~~~~~ + +This generates a file `X11.buildinfo` supplying the parameters needed by +later stages: + +~~~~~~~~~~~~~~~~ +buildable: True +cc-options: -I/usr/X11R6/include +ld-options: -L/usr/X11R6/lib +~~~~~~~~~~~~~~~~ + +The `configure` script also generates a header file +`include/HsX11Config.h` containing C preprocessor defines recording the +results of various tests. This file may be included by C source files +and preprocessed Haskell source files in the package. + +Note: Packages using these features will also need to list +additional files such as `configure`, +templates for `.buildinfo` files, files named +only in `.buildinfo` files, header files and +so on in the `extra-source-files` field, +to ensure that they are included in source distributions. +They should also list files and directories generated by +`configure` in the +`extra-tmp-files` field to ensure that they +are removed by `setup clean`. + +## Conditional compilation ## + +Sometimes you want to write code that works with more than one version +of a dependency. You can specify a range of versions for the depenency +in the `build-depends`, but how do you then write the code that can use +different versions of the API? + +Haskell lets you preprocess your code using the C preprocessor (either +the real C preprocessor, or `cpphs`). To enable this, add `extensions: +CPP` to your package description. When using CPP, Cabal provides some +pre-defined macros to let you test the version of dependent packages; +for example, suppose your package works with either version 3 or version +4 of the `base` package, you could select the available version in your +Haskell modules like this: + +~~~~~~~~~~~~~~~~ +#if MIN_VERSION_base(4,0,0) +... code that works with base-4 ... +#else +... code that works with base-3 ... +#endif +~~~~~~~~~~~~~~~~ + +In general, Cabal supplies a macro `MIN_VERSION_`_`package`_`_(A,B,C)` +for each package depended on via `build-depends`. This macro is true if +the actual version of the package in use is greater than or equal to +`A.B.C` (using the conventional ordering on version numbers, which is +lexicographic on the sequence, but numeric on each component, so for +example 1.2.0 is greater than 1.0.3). + +Cabal places the definitions of these macros into an +automatically-generated header file, which is included when +preprocessing Haskell source code by passing options to the C +preprocessor. + +## More complex packages ## + +For packages that don't fit the simple schemes described above, you have +a few options: + + * You can customize the simple build infrastructure using _hooks_. + These allow you to perform additional actions before and after each + command is run, and also to specify additional preprocessors. See + `UserHooks` in [Distribution.Simple][dist-simple] for the details, + but note that this interface is experimental, and likely to change + in future releases. + + * You could delegate all the work to `make`, though this is unlikely + to be very portable. Cabal supports this with the `build-type` + `Make` and a trivial setup library [Distribution.Make][dist-make], + which simply parses the command line arguments and invokes `make`. + Here `Setup.hs` looks like + + ~~~~~~~~~~~~~~~~ + import Distribution.Make + main = defaultMain + ~~~~~~~~~~~~~~~~ + + The root directory of the package should contain a `configure` + script, and, after that has run, a `Makefile` with a default target + that builds the package, plus targets `install`, `register`, + `unregister`, `clean`, `dist` and `docs`. Some options to commands + are passed through as follows: + + * The `--with-hc-pkg`, `--prefix`, `--bindir`, `--libdir`, + `--datadir` and `--libexecdir` options to the `configure` + command are passed on to the `configure` script. In addition the + value of the `--with-compiler` option is passed in a `--with-hc` + option and all options specified with `--configure-option=` are + passed on. + + * The `--destdir` option to the `copy` command becomes a setting + of a `destdir` variable on the invocation of `make copy`. The + supplied `Makefile` should provide a `copy` target, which will + probably look like this: + + ~~~~~~~~~~~~~~~~ + copy : + $(MAKE) install prefix=$(destdir)/$(prefix) \ + bindir=$(destdir)/$(bindir) \ + libdir=$(destdir)/$(libdir) \ + datadir=$(destdir)/$(datadir) \ + libexecdir=$(destdir)/$(libexecdir) + ~~~~~~~~~~~~~~~~ + + * You can write your own setup script conforming to the interface + described in the section on [building and installing + packages](#building-and-installing-a-package), possibly using the + Cabal library for part of the work. One option is to copy the + source of `Distribution.Simple`, and alter it for your needs. + Good luck. + +# Building and installing a package # + +After you've unpacked a Cabal package, you can build it by moving into +the root directory of the package and using the `Setup.hs` or +`Setup.lhs` script there: + +> `_runhaskell_ Setup.hs` [_command_] [_option_...] + +The _command_ argument selects a particular step in the build/install +process. You can also get a summary of the command syntax with + +> `runhaskell Setup.hs --help` + +## Building and installing a system package ## + +~~~~~~~~~~~~~~~~ +runhaskell Setup.hs configure --ghc +runhaskell Setup.hs build +runhaskell Setup.hs install +~~~~~~~~~~~~~~~~ + +The first line readies the system to build the tool using GHC; for +example, it checks that GHC exists on the system. The second line +performs the actual building, while the last both copies the build +results to some permanent place and registers the package with GHC. + +## Building and installing a user package ## + +~~~~~~~~~~~~~~~~ +runhaskell Setup.hs configure --user +runhaskell Setup.hs build +runhaskell Setup.hs install +~~~~~~~~~~~~~~~~ + +The package is installed under the user's home directory and is +registered in the user's package database (`--user`). + +## Creating a binary package ## + +When creating binary packages (e.g. for RedHat or Debian) one needs to +create a tarball that can be sent to another system for unpacking in the +root directory: + +~~~~~~~~~~~~~~~~ +runhaskell Setup.hs configure --prefix=/usr +runhaskell Setup.hs build +runhaskell Setup.hs copy --destdir=/tmp/mypkg +tar -czf mypkg.tar.gz /tmp/mypkg/ +~~~~~~~~~~~~~~~~ + +If the package contains a library, you need two additional steps: + +~~~~~~~~~~~~~~~~ +runhaskell Setup.hs register --gen-script +runhaskell Setup.hs unregister --gen-script +~~~~~~~~~~~~~~~~ + +This creates shell scripts `register.sh` and `unregister.sh`, which must +also be sent to the target system. After unpacking there, the package +must be registered by running the `register.sh` script. The +`unregister.sh` script would be used in the uninstall procedure of the +package. Similar steps may be used for creating binary packages for +Windows. + + +The following options are understood by all commands: + +`--help`, `-h` or `-?` +: List the available options for the command. + +`--verbose=`_n_ or `-v`_n_ +: Set the verbosity level (0-3). The normal level is 1; a missing _n_ + defaults to 2. + +The various commands and the additional options they support are +described below. In the simple build infrastructure, any other options +will be reported as errors. + +## setup configure ## + +Prepare to build the package. Typically, this step checks that the +target platform is capable of building the package, and discovers +platform-specific features that are needed during the build. + +The user may also adjust the behaviour of later stages using the options +listed in the following subsections. In the simple build +infrastructure, the values supplied via these options are recorded in a +private file read by later stages. + +If a user-supplied `configure` script is run (see the section on +[system-dependent parameters](#system-dependent-parameters) or on +[complex packages](#complex-packages)), it is passed the +`--with-hc-pkg`, `--prefix`, `--bindir`, `--libdir`, `--datadir` and +`--libexecdir` options. In addition the value of the `--with-compiler` +option is passed in a `--with-hc` option and all options specified with +`--configure-option=` are passed on. + +### Programs used for building ### + +The following options govern the programs used to process the source +files of a package: + +`--ghc` or `-g`, `--nhc`, `--jhc`, `--hugs` +: Specify which Haskell implementation to use to build the package. + At most one of these flags may be given. If none is given, the + implementation under which the setup script was compiled or + interpreted is used. + +`--with-compiler=`_path_ or `-w`_path_ +: Specify the path to a particular compiler. If given, this must match + the implementation selected above. The default is to search for the + usual name of the selected implementation. + + This flag also sets the default value of the `--with-hc-pkg` option + to the package tool for this compiler. Check the output of `setup + configure -v` to ensure that it finds the right package tool (or use + `--with-hc-pkg` explicitly). + + +`--with-hc-pkg=`_path_ +: Specify the path to the package tool, e.g. `ghc-pkg`. The package + tool must be compatible with the compiler specified by + `--with-compiler`. If this option is omitted, the default value is + determined from the compiler selected. + +`--with-`_`prog`_`=`_path_ +: Specify the path to the program _prog_. Any program known to Cabal + can be used in place of _prog_. It can either be a fully path or the + name of a program that can be found on the program search path. For + example: `--with-ghc=ghc-6.6.1` or + `--with-cpphs=/usr/local/bin/cpphs`. + +`--`_`prog`_`-options=`_options_ +: Specify additional options to the program _prog_. Any program known + to Cabal can be used in place of _prog_. For example: + `--alex-options="--template=mytemplatedir/"`. The _options_ is split + into program options based on spaces. Any options containing embeded + spaced need to be quoted, for example + `--foo-options='--bar="C:\Program File\Bar"'`. As an alternative + that takes only one option at a time but avoids the need to quote, + use `--`_`prog`_`-option` instead. + +`--`_`prog`_`-option=`_option_ +: Specify a single additional option to the program _prog_. For + passing an option that contain embeded spaces, such as a file name + with embeded spaces, using this rather than `--`_`prog`_`-options` + means you do not need an additional level of quoting. Of course if + you are using a command shell you may still need to quote, for + example `--foo-options="--bar=C:\Program File\Bar"`. + +All of the options passed with either `--`_`prog`_`-options` or +`--`_`prog`_`-option` are passed in the order they were specified on the +configure command line. + +### Installation paths ### + +The following options govern the location of installed files from a +package: + +`--prefix=`_dir_ +: The root of the installation. For example for a global install you + might use `/usr/local` on a Unix system, or `C:\Program Files` on a + Windows system. The other installation paths are usually + subdirectories of _prefix_, but they don't have to be. + + In the simple build system, _dir_ may contain the following path + variables: `$pkgid`, `$pkg`, `$version`, `$compiler`, `$os`, + `$arch` + +`--bindir=`_dir_ +: Executables that the user might invoke are installed here. + + In the simple build system, _dir_ may contain the following path + variables: `$prefix`, `$pkgid`, `$pkg`, `$version`, `$compiler`, + `$os`, `$arch` + +`--libdir=`_dir_ +: Object-code libraries are installed here. + + In the simple build system, _dir_ may contain the following path + variables: `$prefix`, `$bindir`, `$pkgid`, `$pkg`, `$version`, + `$compiler`, `$os`, `$arch` + +`--libexecdir=`_dir_ +: Executables that are not expected to be invoked directly by the user + are installed here. + + In the simple build system, _dir_ may contain the following path + variables: `$prefix`, `$bindir`, `$libdir`, `$libsubdir`, `$pkgid`, + `$pkg`, `$version`, `$compiler`, `$os`, `$arch` + +`--datadir`=_dir_ +: Architecture-independent data files are installed here. + + In the simple build system, _dir_ may contain the following path + variables: `$prefix`, `$bindir`, `$libdir`, `$libsubdir`, `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +In addition the simple build system supports the following installation path options: + +`--libsubdir=`_dir_ +: A subdirectory of _libdir_ in which libraries are actually + installed. For example, in the simple build system on Unix, the + default _libdir_ is `/usr/local/lib`, and _libsubdir_ contains the + package identifier and compiler, e.g. `mypkg-0.2/ghc-6.4`, so + libraries would be installed in `/usr/local/lib/mypkg-0.2/ghc-6.4`. + + _dir_ may contain the following path variables: `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +`--datasubdir=`_dir_ +: A subdirectory of _datadir_ in which data files are actually + installed. + + _dir_ may contain the following path variables: `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +`--docdir=`_dir_ +: Documentation files are installed relative to this directory. + + _dir_ may contain the following path variables: `$prefix`, `$bindir`, + `$libdir`, `$libsubdir`, `$datadir`, `$datasubdir`, `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +`--htmldir=`_dir_ +: HTML documentation files are installed relative to this directory. + + _dir_ may contain the following path variables: `$prefix`, `$bindir`, + `$libdir`, `$libsubdir`, `$datadir`, `$datasubdir`, `$docdir`, `$pkgid`, + `$pkg`, `$version`, `$compiler`, `$os`, `$arch` + +`--program-prefix=`_prefix_ +: Prepend _prefix_ to installed program names. + + _prefix_ may contain the following path variables: `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +`--program-suffix=`_suffix_ +: Append _suffix_ to installed program names. The most obvious use for + this is to append the program's version number to make it possible + to install several versions of a program at once: + `--program-suffix='$version'`. + + _suffix_ may contain the following path variables: `$pkgid`, `$pkg`, + `$version`, `$compiler`, `$os`, `$arch` + +#### Path variables in the simple build system #### + +For the simple build system, there are a number of variables that can be +used when specifying installation paths. The defaults are also specified +in terms of these variables. A number of the variables are actually for +other paths, like `$prefix`. This allows paths to be specified relative +to each other rather than as absolute paths, which is important for +building relocatable packages (see [prefix +independence](#prefix-independence)). + +`$prefix` +: The path variable that stands for the root of the installation. For + an installation to be relocatable, all other instllation paths must + be relative to the `$prefix` variable. + +`$bindir` +: The path variable that expands to the path given by the `--bindir` + configure option (or the default). + +`$libdir` +: As above but for `--libdir` + +`$libsubdir` +: As above but for `--libsubdir` + +`$datadir` +: As above but for `--datadir` + +`$datasubdir` +: As above but for `--datasubdir` + +`$docdir` +: As above but for `--docdir` + +`$pkgid` +: The name and version of the package, eg `mypkg-0.2` + +`$pkg` +: The name of the package, eg `mypkg` + +`$version` +: The version of the package, eg `0.2` + +`$compiler` +: The compiler being used to build the package, eg `ghc-6.6.1` + +`$os` +: The operating system of the computer being used to build the + package, eg `linux`, `windows`, `osx`, `freebsd` or `solaris` + +`$arch` +: The architecture of the computer being used to build the package, eg + `i386`, `x86_64`, `ppc` or `sparc` + +#### Paths in the simple build system #### + +For the simple build system, the following defaults apply: + +Option Windows Default Unix Default +------- ---------------- ------------- +`--prefix` (global) `C:\Program Files\Haskell` `/usr/local` +`--prefix` (per-user) `C:\Documents And Settings\user\Application Data\cabal` `$HOME/.cabal` +`--bindir` `$prefix\bin` `$prefix/bin` +`--libdir` `$prefix` `$prefix/lib` +`--libsubdir` (Hugs) `hugs\packages\$pkg` `hugs/packages/$pkg` +`--libsubdir` (others) `$pkgid\$compiler` `$pkgid/$compiler` +`--libexecdir` `$prefix\$pkgid` `$prefix/libexec` +`--datadir` (executable) `$prefix` `$prefix/share` +`--datadir` (library) `C:\Program Files\Haskell` `$prefix/share` +`--datasubdir` `$pkgid` `$pkgid` +`--docdir` `$prefix\doc\$pkgid` `$datadir/doc/$pkgid` +`--htmldir` `$docdir\html` `$docdir/html` +`--program-prefix` (empty) (empty) +`--program-suffix` (empty) (empty) + + +#### Prefix-independence #### + +On Windows, and when using Hugs on any system, it is possible to obtain +the pathname of the running program. This means that we can construct an +installable executable package that is independent of its absolute +install location. The executable can find its auxiliary files by finding +its own path and knowing the location of the other files relative to +`$bindir`. Prefix-independence is particularly +useful: it means the user can choose the install location (i.e. the +value of `$prefix`) at install-time, rather than +having to bake the path into the binary when it is built. + +In order to achieve this, we require that for an executable on Windows, +all of `$bindir`, `$libdir`, `$datadir` and `$libexecdir` begin with +`$prefix`. If this is not the case then the compiled executable will +have baked-in all absolute paths. + +The application need do nothing special to achieve prefix-independence. +If it finds any files using `getDataFileName` and the [other functions +provided for the purpose](#accessing-data-files-from-package-code), the +files will be accessed relative to the location of the current +executable. + +A library cannot (currently) be prefix-independent, because it will be +linked into an executable whose file system location bears no relation +to the library package. + +### Controlling Flag Assignments ### + +Flag assignments (see the [resolution of conditions and +flags](#resolution-of-conditions-and-flags)) can be controlled with the +followingcommand line options. + +`-f` _flagname_ or `-f` `-`_flagname_ +: Force the specified flag to `true` or `false` (if preceded with a `-`). Later + specifications for the same flags will override earlier, i.e., + specifying `-fdebug -f-debug` is equivalent to `-f-debug` + +`--flags=`_flagspecs_ +: Same as `-f`, but allows specifying multiple flag assignments at + once. The parameter is a space-separated list of flag names (to + force a flag to `true`), optionally preceded by a `-` (to force a + flag to `false`). For example, `--flags="debug -feature1 feature2"` is + equivalent to `-fdebug -f-feature1 -ffeature2`. + +### Miscellaneous options ## + +`--user` +: Does a per-user installation. This changes the [default installation + prefix](#paths-in-the-simple-build-system). It also allow + dependencies to be satisfied by the user's package database, in + addition to the global database. This also implies a default of + `--user` for any subsequent `install` command, as packages + registered in the global database should not depend on packages + registered in a user's database. + +`--global` +: (default) Does a global installation. In this case package + dependencies must be satisfied by the global package database. All + packages in the user's package database will be ignored. Typically + the final instllation step will require administrative privileges. + +`--package-db=`_db_ +: Allows package dependencies to be satisfied from this additional + package database _db_ in addition to the global package database. + All packages in the user's package database will be ignored. The + interpretation of _db_ is implementation-specific. Typically it will + be a file or directory. Not all implementations support arbitrary + package databases. + +`--enable-optimization`[=_n_] or `-O`[_n_] +: (default) Build with optimization flags (if available). This is + appropriate for production use, taking more time to build faster + libraries and programs. + + The optional _n_ value is the optimisation level. Some compilers + support multiple optimisation levels. The range is 0 to 2. Level 0 + is equivalent to `--disable-optimization`, level 1 is the default if + no _n_ parameter is given. Level 2 is higher optimisation if the + compiler supports it. Level 2 is likely to lead to longer compile + times and bigger generated code. + +`--disable-optimization` +: Build without optimization. This is suited for development: building + will be quicker, but the resulting library or programs will be slower. + +`--enable-library-profiling` or `-p` +: Request that an additional version of the library with profiling + features enabled be built and installed (only for implementations + that support profiling). + +`--disable-library-profiling` +: (default) Do not generate an additional profiling version of the + library. + +`--enable-executable-profiling` +: Any executables generated should have profiling enabled (only for + implementations that support profiling). For this to work, all + libraries used by these executables must also have been built with + profiling support. + +`--disable-executable-profiling` +: (default) Do not enable profiling in generated executables. + +`--enable-library-vanilla` +: (default) Build ordinary libraries (as opposed to profiling + libraries). This is independent of the `--enable-library-profiling` + option. If you enable both, you get both. + +`--disable-library-vanilla` +: Do not build ordinary libraries. This is useful in conjunction with + `--enable-library-profiling` to build only profiling libraries, + rather than profiling and ordinary libraries. + +`--enable-library-for-ghci` +: (default) Build libraries suitable for use with GHCi. + +`--disable-library-for-ghci` +: Not all platforms support GHCi and indeed on some platforms, trying + to build GHCi libs fails. In such cases this flag can be used as a + workaround. + +`--enable-split-objs` +: Use the GHC `-split-objs` feature when building the library. This + reduces the final size of the executables that use the library by + allowing them to link with only the bits that they use rather than + the entire library. The downside is that building the library takes + longer and uses considerably more memory. + +`--disable-split-objs` +: (default) Do not use the GHC `-split-objs` feature. This makes + building the library quicker but the final executables that use the + library will be larger. + +`--enable-executable-stripping` +: (default) When installing binary executable programs, run the + `strip` program on the binary. This can considerably reduce the size + of the executable binary file. It does this by removing debugging + information and symbols. While such extra information is useful for + debugging C programs with traditional debuggers it is rarely helpful + for debugging binaries produced by Haskell compilers. + + Not all Haskell implementations generate native binaries. For such + implementations this option has no effect. + +`--disable-executable-stripping` +: Do not strip binary executables during installation. You might want + to use this option if you need to debug a program using gdb, for + example if you want to debug the C parts of a program containing + both Haskell and C code. Another reason is if your are building a + package for a system which has a policy of managing the stripping + itself (such as some linux distributions). + +`--enable-shared` +: Build shared library. This implies a seperate compiler run to + generate position independent code as required on most platforms. + +`--disable-shared` +: (default) Do not build shared library. + +`--configure-option=`_str_ +: An extra option to an external `configure` script, if one is used + (see the section on [system-dependent + parameters](#system-dependent-parameters)). There can be several of + these options. + +`--extra-include-dirs`[=_dir_] +: An extra directory to search for C header files. You can use this + flag multiple times to get a list of directories. + + You might need to use this flag if you have standard system header + files in a non-standard location that is not mentioned in the + package's `.cabal` file. Using this option has the same affect as + appending the directory _dir_ to the `include-dirs` field in each + library and executable in the package's `.cabal` file. The advantage + of course is that you do not have to modify the package at all. + These extra directories will be used while building the package and + for libraries it is also saved in the package registration + information and used when compiling modules that use the library. + +`--extra-lib-dirs`[=_dir_] +: An extra directory to search for system libraries files. You can use + this flag multiple times to get a list of directories. + + You might need to use this flag if you have standard system + libraries in a non-standard location that is not mentioned in the + package's `.cabal` file. Using this option has the same affect as + appending the directory _dir_ to the `extra-lib-dirs` field in each + library and executable in the package's `.cabal` file. The advantage + of course is that you do not have to modify the package at all. + These extra directories will be used while building the package and + for libraries it is also saved in the package registration + information and used when compiling modules that use the library. + +In the simple build infrastructure, an additional option is recognized: + +`--scratchdir=`_dir_ +: Specify the directory into which the Hugs output will be placed + (default: `dist/scratch`). + +## setup build ## + +Perform any preprocessing or compilation needed to make this package ready for installation. + +This command takes the following options: + +--_prog_-options=_options_, --_prog_-option=_option_ +: These are mostly the same as the [options configure + step](#setup-configure). Unlike the options specified at the + configure step, any program options specified at the build step are + not persistent but are used for that invocation only. They options + specified at the build step are in addition not in replacement of + any options specified at the configure step. + +## setup haddock ## + +Build the documentation for the package using [haddock][]. By default, +only the documentation for the exposed modules is generated (but see the +`--executables` and `--internal` flags below). + +This command takes the following options: + +`--hoogle` +: Generate a file `dist/doc/html/`_pkgid_`.txt`, which can be + converted by [Hoogle](http://www.haskell.org/hoogle/) into a + database for searching. This is equivalent to running [haddock][] + with the `--hoogle` flag. + +`--html-location=`_url_ +: Specify a template for the location of HTML documentation for + prerequisite packages. The substitutions ([see + listing](#paths-in-the-simple-build-system)) are applied to the + template to obtain a location for each package, which will be used + by hyperlinks in the generated documentation. For example, the + following command generates links pointing at [HackageDB][] pages: + + > setup haddock --html-location='http://hackage.haskell.org/packages/archive/$pkg/latest/doc/html' + + Here the argument is quoted to prevent substitution by the shell. If + this option is omitted, the location for each package is obtained + using the package tool (e.g. `ghc-pkg`). + +`--executables` +: Also run [haddock][] for the modules of all the executable programs. + By default [haddock][] is run only on the exported modules. + +`--internal` +: Run [haddock][] for the all modules, including unexposed ones, and + make [haddock][] generate documentation for unexported symbols as + well. + +`--css=`_path_ +: The argument _path_ denotes a CSS file, which is passed to + [haddock][] and used to set the style of the generated + documentation. This is only needed to override the default style + that [haddock][] uses. + +`--hyperlink-source` +: Generate [haddock][] documentation integrated with [HsColour][]. + First, [HsColour][] is run to generate colourised code. Then + [haddock][] is run to generate HTML documentation. Each entity + shown in the documentation is linked to its definition in the + colourised code. + +`--hscolour-css=`_path_ +: The argument _path_ denotes a CSS file, which is passed to [HsColour][] as in + + > runhaskell Setup.hs hscolour --css=_path_ + +## setup hscolour ## + +Produce colourised code in HTML format using [HsColour][]. Colourised +code for exported modules is put in `dist/doc/html/`_pkgid_`/src`. + +This command takes the following options: + +`--executables` +: Also run [HsColour][] on the sources of all executable programs. + Colourised code is put in `dist/doc/html/`_pkgid_/_executable_`/src`. + +`--css=`_path_ +: Use the given CSS file for the generated HTML files. The CSS file + defines the colours used to colourise code. Note that this copies + the given CSS file to the directory with the generated HTML files + (renamed to `hscolour.css`) rather than linking to it. + +## setup install ## + +Copy the files into the install locations and (for library packages) +register the package with the compiler, i.e. make the modules it +contains available to programs. + +The [install locations](#installation-paths) are determined by options +to `setup configure`. + +This command takes the following options: + +`--global` +: Register this package in the system-wide database. (This is the + default, unless the `--user` option was supplied to the `configure` + command.) + +`--user` +: Register this package in the user's local package database. (This is + the default if the `--user` option was supplied to the `configure` + command.) + +## setup copy ## + +Copy the files without registering them. This command is mainly of use +to those creating binary packages. + +This command takes the following option: + +`--destdir=`_path_ + +Specify the directory under which to place installed files. If this is +not given, then the root directory is assumed. + +## setup register ## + +Register this package with the compiler, i.e. make the modules it +contains available to programs. This only makes sense for library +packages. Note that the `install` command incorporates this action. The +main use of this separate command is in the post-installation step for a +binary package. + +This command takes the following options: + +`--global` +: Register this package in the system-wide database. (This is the default.) + + +`--user` +: Register this package in the user's local package database. + + +`--gen-script` +: Instead of registering the package, generate a script containing + commands to perform the registration. On Unix, this file is called + `register.sh`, on Windows, `register.bat`. This script might be + included in a binary bundle, to be run after the bundle is unpacked + on the target system. + +`--gen-pkg-config`[=_path_] +: Instead of registering the package, generate a package registration + file. This only applies to compilers that support package + registration files which at the moment is only GHC. The file should + be used with the compiler's mechanism for registering packages. This + option is mainly intended for packaging systems. If possible use the + `--gen-script` option instead since it is more portable across + Haskell implementations. The _path_ is + optional and can be used to specify a particular output file to + generate. Otherwise, by default the file is the package name and + version with a `.conf` extension. + +`--inplace` +: Registers the package for use directly from the build tree, without + needing to install it. This can be useful for testing: there's no + need to install the package after modifying it, just recompile and + test. + + This flag does not create a build-tree-local package database. It + still registers the package in one of the user or global databases. + + However, there are some caveats. It only works with GHC + (currently). It only works if your package doesn't depend on having + any supplemental files installed --- plain Haskell libraries should + be fine. + +## setup unregister ## + +Deregister this package with the compiler. + +This command takes the following options: + +`--global` +: Deregister this package in the system-wide database. (This is the default.) + +`--user` +: Deregister this package in the user's local package database. + +`--gen-script` +: Instead of deregistering the package, generate a script containing + commands to perform the deregistration. On Unix, this file is + called `unregister.sh`, on Windows, `unregister.bat`. This script + might be included in a binary bundle, to be run on the target + system. + +## setup clean ## + +Remove any local files created during the `configure`, `build`, +`haddock`, `register` or `unregister` steps, and also any files and +directories listed in the `extra-tmp-files` field. + +This command takes the following options: + +`--save-configure` or `-s` +: Keeps the configuration information so it is not necessary to run + the configure step again before building. + +## setup test ## + +Run the test suite specified by the `runTests` field of +`Distribution.Simple.UserHooks`. See [Distribution.Simple][dist-simple] +for information about creating hooks and using `defaultMainWithHooks`. + +## setup sdist ## + +Create a system- and compiler-independent source distribution in a file +_package_-_version_`.tar.gz` in the `dist` subdirectory, for +distribution to package builders. When unpacked, the commands listed in +this section will be available. + +The files placed in this distribution are the package description file, +the setup script, the sources of the modules named in the package +description file, and files named in the `license-file`, `main-is`, +`c-sources`, `data-files` and `extra-source-files` fields. + +This command takes the following option: + +`--snapshot` +: Append today's date (in "YYYYMMDD" format) to the version number for + the generated source package. The original package is unaffected. + +# Reporting bugs and deficiencies # + +Please report any flaws or feature requests in the [bug tracker][]. + +For general discussion or queries email the libraries mailing list +. There is also a development mailing list +. + +[bug tracker]: http://hackage.haskell.org/trac/hackage/ + +# Stability of Cabal interfaces # + +The Cabal library and related infrastructure is still under active +development. New features are being added and limitations and bugs are +being fixed. This requires internal changes and often user visible +changes as well. We therefor cannot promise complete future-proof +stability, at least not without halting all development work. + +This section documents the aspects of the Cabal interface that we can +promise to keep stable and which bits are subject to change. + +## Cabal file format ## + +This is backwards compatible and mostly forwards compatible. New fields +can be added without breaking older versions of Cabal. Fields can be +deprecated without breaking older packages. + +## Command-line interface ## + +### Very Stable Command-line interfaces ### + +* `./setup configure` + * `--prefix` + * `--user` + * `--ghc`, `--hugs` + * `--verbose` + * `--prefix` + +* `./setup build` +* `./setup install` +* `./setup register` +* `./setup copy` + +### Stable Command-line interfaces ### + +### Unstable command-line ### + +## Functions and Types ## + +The Cabal library follows the [Package Versioning Policy][PVP]. This +means that within a stable major release, for example 1.2.x, there will +be no incompatible API changes. But minor versions increments, for +example 1.2.3, indicate compatible API additions. + +The Package Versioning Policy does not require any API guarantees +between major releases, for example between 1.2.x and 1.4.x. In practise +of course not everything changes between major releases. Some parts of +the API are more prone to change than others. The rest of this section +gives some informal advice on what level of API stability you can expect +between major releases. + +[PVP]: http://haskell.org/haskellwiki/Package_versioning_policy + +### Very Stable API ### + +* `defaultMain` + +* `defaultMainWithHooks defaultUserHooks` + + But regular `defaultMainWithHooks` isn't stable since `UserHooks` + changes. + +### Semi-stable API ### + +* `UserHooks` The hooks API will change in the future + +* `Distribution.*` is mostly declarative information about packages and + is somewhat stable. + +### Unstable API ### + +Everything under `Distribution.Simple.*` has no stability guarantee. + +## Hackage ## + +The index format is a partly stable interface. It consists of a tar.gz +file that contains directories with `.cabal` files in. In future it may +contain more kinds of files so do not assume every file is a `.cabal` +file. Incompatible revisions to the format would involve bumping the +name of the index file, i.e., `00-index.tar.gz`, `01-index.tar.gz` etc. + + +[dist-simple]: ../libraries/Cabal/Distribution-Simple.html +[dist-make]: ../libraries/Cabal/Distribution-Make.html +[dist-license]: ../libraries/Cabal/Distribution-License.html#t:License +[extension]: ../libraries/Cabal/Language-Haskell-Extension.html#t:Extension +[BuildType]: ../libraries/Cabal/Distribution-PackageDescription.html#t:BuildType +[alex]: http://www.haskell.org/alex/ +[autoconf]: http://www.gnu.org/software/autoconf/ +[c2hs]: http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ +[cpphs]: http://www.haskell.org/cpphs/ +[greencard]: http://www.haskell.org/greencard/ +[haddock]: http://www.haskell.org/haddock/ +[HsColour]: http://www.cs.york.ac.uk/fp/darcs/hscolour/ +[happy]: http://www.haskell.org/happy/ +[HackageDB]: http://hackage.haskell.org/ +[pkg-config]: http://pkg-config.freedesktop.org/ hunk ./tests/systemTests/twoMains/MainA.hs 2 -import System -import Control.Monad(when) + +import System.Environment (getArgs) +import Control.Monad (when) + hunk ./tests/systemTests/twoMains/MainB.hs 2 -import System + +import System.Environment (getArgs) hunk ./tests/systemTests/twoMains/MainB.hs 5 + hunk ./tests/systemTests/twoMains/test.cabal 5 -build-depends: base, haskell98 +build-depends: base hunk ./tests/systemTests/wash2hs/hs/WASHClean.hs 3 -import Char +import Data.Char hunk ./tests/systemTests/wash2hs/hs/WASHExpression.hs 3 -import Monad +import Control.Monad hunk ./tests/systemTests/wash2hs/hs/WASHGenerator.hs 3 -import List; -import IO; +import Data.List; +import System.IO; hunk ./tests/systemTests/wash2hs/hs/WASHMain.hs 5 -import IO -import List +import System.IO +import Data.List hunk ./tests/systemTests/wash2hs/hs/WASHParser.hs 3 -import Char ; +import Data.Char ; hunk ./tests/systemTests/wash2hs/hs/WASHUtil.hs 8 -import IOExts ; +import System.IOExts ; hunk ./tests/systemTests/wash2hs/wash2hs.cabal 4 -Build-Depends: base, text, lang, haskell98 +Build-Depends: base, text, lang hunk ./Distribution/Simple/PreProcess.hs 297 - where cppArgs = sysDefines ++ cppOptions bi ++ getCppOptions bi lbi - sysDefines = - ["-D" ++ os ++ "_" ++ loc ++ "_OS" | loc <- locations] ++ - ["-D" ++ arch ++ "_" ++ loc ++ "_ARCH" | loc <- locations] - locations = ["BUILD", "HOST"] + where cppArgs = getCppOptions bi lbi hunk ./Distribution/Simple/PreProcess.hs 372 - -- Options from the current package: hunk ./Distribution/Simple/PreProcess.hs 373 + ++ [ "--cflag=" ++ opt | opt <- sysDefines ] + + -- Options from the current package: hunk ./Distribution/Simple/PreProcess.hs 430 +--TODO: perhaps use this with hsc2hs too +--TODO: remove cc-options from cpphs for cabal-version: >= 1.10 hunk ./Distribution/Simple/PreProcess.hs 435 + ++ sysDefines + ++ cppOptions bi hunk ./Distribution/Simple/PreProcess.hs 440 +sysDefines :: [String] +sysDefines = ["-D" ++ os ++ "_" ++ loc ++ "_OS" | loc <- locations] + ++ ["-D" ++ arch ++ "_" ++ loc ++ "_ARCH" | loc <- locations] + where + locations = ["BUILD", "HOST"] + hunk ./Distribution/Simple/Haddock.hs 305 - ++ [ "-odir", tmp, "-hidir", tmp ], + ++ [ "-odir", tmp, "-hidir", tmp + , "-stubdir", tmp ], hunk ./Distribution/Simple/Haddock.hs 323 - ++ [ "-odir", tmp, "-hidir", tmp ], + ++ [ "-odir", tmp, "-hidir", tmp + , "-stubdir", tmp ], hunk ./Distribution/Simple/PreProcess.hs 256 - runPreProcessor pp + runPreProcessorWithHsBootHack pp hunk ./Distribution/Simple/PreProcess.hs 258 - (buildLoc, srcStem <.> "hs") verbosity + (buildLoc, srcStem <.> "hs") hunk ./Distribution/Simple/PreProcess.hs 260 - where dirName = takeDirectory - tailNotNull [] = [] - tailNotNull x = tail x + where + dirName = takeDirectory + tailNotNull [] = [] + tailNotNull x = tail x + + -- FIXME: This is a somewhat nasty hack. GHC requires that hs-boot files + -- be in the same place as the hs files, so if we put the hs file in dist/ + -- then we need to copy the hs-boot file there too. This should probably be + -- done another way. Possibly we should also be looking for .lhs-boot + -- files, but I think that preprocessors only produce .hs files. + runPreProcessorWithHsBootHack pp + (inBaseDir, inRelativeFile) + (outBaseDir, outRelativeFile) = do + runPreProcessor pp + (inBaseDir, inRelativeFile) + (outBaseDir, outRelativeFile) verbosity + + exists <- doesFileExist inBoot + when exists $ copyFileVerbose verbosity inBoot outBoot + + where + inBoot = replaceExtension inFile "hs-boot" + outBoot = replaceExtension outFile "hs-boot" + + inFile = normalise (inBaseDir inRelativeFile) + outFile = normalise (outBaseDir outRelativeFile) hunk ./Distribution/Simple/PreProcess.hs 514 - do rawSystemProgramConf verbosity prog (withPrograms lbi) - (args ++ ["-o", outFile, inFile]) - -- Note: This is a nasty hack. GHC requires that hs-boot files - -- be in the same place as the hs files, so if we put the hs - -- file in dist/... then we need to copy the hs-boot file - -- there too. This should probably be done another way, e.g. - -- by preprocessing all files, with and "id" preprocessor if - -- nothing else, so the hs-boot files automatically get copied - -- into the right place. - -- Possibly we should also be looking for .lhs-boot files, but - -- I think that preprocessors only produce .hs files. - let inBoot = replaceExtension inFile "hs-boot" - outBoot = replaceExtension outFile "hs-boot" - exists <- doesFileExist inBoot - when exists $ copyFileVerbose verbosity inBoot outBoot + rawSystemProgramConf verbosity prog (withPrograms lbi) + (args ++ ["-o", outFile, inFile]) hunk ./Distribution/Simple/PreProcess.hs 78 - ( Program(..), ConfiguredProgram(..), lookupProgram, programPath + ( Program(..), ConfiguredProgram(..), programPath + , lookupProgram, requireProgram, requireProgramVersion hunk ./Distribution/Simple/PreProcess.hs 85 -import Distribution.Version (Version(..)) +import Distribution.Version + ( Version(..), anyVersion, orLaterVersion ) hunk ./Distribution/Simple/PreProcess.hs 328 - runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> + runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> do + (ghcProg, ghcVersion, _) <- requireProgramVersion verbosity + ghcProgram anyVersion (withPrograms lbi) hunk ./Distribution/Simple/PreProcess.hs 344 - where Just ghcProg = lookupProgram ghcProgram (withPrograms lbi) - Just ghcVersion = programVersion ghcProg hunk ./Distribution/Simple/PreProcess.hs 349 - runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> + runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> do + (cpphsProg, cpphsVersion, _) <- requireProgramVersion verbosity + cpphsProgram anyVersion (withPrograms lbi) hunk ./Distribution/Simple/PreProcess.hs 360 - where Just cpphsProg = lookupProgram cpphsProgram (withPrograms lbi) - Just cpphsVersion = programVersion cpphsProg hunk ./Distribution/Simple/PreProcess.hs 372 -ppHsc2hs bi lbi = standardPP lbi hsc2hsProgram $ - [ "--cc=" ++ programPath gccProg - , "--ld=" ++ programPath gccProg ] +ppHsc2hs bi lbi = + PreProcessor { + platformIndependent = False, + runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> do + (gccProg, _) <- requireProgram verbosity gccProgram (withPrograms lbi) + rawSystemProgramConf verbosity hsc2hsProgram (withPrograms lbi) $ + [ "--cc=" ++ programPath gccProg + , "--ld=" ++ programPath gccProg ] hunk ./Distribution/Simple/PreProcess.hs 381 - -- Additional gcc options - ++ [ "--cflag=" ++ opt | opt <- programDefaultArgs gccProg - ++ programOverrideArgs gccProg ] - ++ [ "--lflag=" ++ opt | opt <- programDefaultArgs gccProg - ++ programOverrideArgs gccProg ] + -- Additional gcc options + ++ [ "--cflag=" ++ opt | opt <- programDefaultArgs gccProg + ++ programOverrideArgs gccProg ] + ++ [ "--lflag=" ++ opt | opt <- programDefaultArgs gccProg + ++ programOverrideArgs gccProg ] hunk ./Distribution/Simple/PreProcess.hs 387 - -- OSX frameworks: - ++ [ what ++ "=-F" ++ opt - | isOSX - , opt <- nub (concatMap Installed.frameworkDirs pkgs) - , what <- ["--cflag", "--lflag"] ] - ++ [ "--lflag=" ++ arg - | isOSX - , opt <- PD.frameworks bi ++ concatMap Installed.frameworks pkgs - , arg <- ["-framework", opt] ] + -- OSX frameworks: + ++ [ what ++ "=-F" ++ opt + | isOSX + , opt <- nub (concatMap Installed.frameworkDirs pkgs) + , what <- ["--cflag", "--lflag"] ] + ++ [ "--lflag=" ++ arg + | isOSX + , opt <- PD.frameworks bi ++ concatMap Installed.frameworks pkgs + , arg <- ["-framework", opt] ] hunk ./Distribution/Simple/PreProcess.hs 397 - -- Note that on ELF systems, wherever we use -L, we must also use -R - -- because presumably that -L dir is not on the normal path for the - -- system's dynamic linker. This is needed because hsc2hs works by - -- compiling a C program and then running it. + -- Note that on ELF systems, wherever we use -L, we must also use -R + -- because presumably that -L dir is not on the normal path for the + -- system's dynamic linker. This is needed because hsc2hs works by + -- compiling a C program and then running it. hunk ./Distribution/Simple/PreProcess.hs 402 - ++ [ "--cflag=" ++ opt | opt <- hcDefines (compiler lbi) ] - ++ [ "--cflag=" ++ opt | opt <- sysDefines ] + ++ [ "--cflag=" ++ opt | opt <- hcDefines (compiler lbi) ] + ++ [ "--cflag=" ++ opt | opt <- sysDefines ] hunk ./Distribution/Simple/PreProcess.hs 405 - -- Options from the current package: - ++ [ "--cflag=-I" ++ dir | dir <- PD.includeDirs bi ] - ++ [ "--cflag=" ++ opt | opt <- PD.ccOptions bi - ++ PD.cppOptions bi ] - ++ [ "--lflag=-L" ++ opt | opt <- PD.extraLibDirs bi ] - ++ [ "--lflag=-Wl,-R," ++ opt | isELF - , opt <- PD.extraLibDirs bi ] - ++ [ "--lflag=-l" ++ opt | opt <- PD.extraLibs bi ] - ++ [ "--lflag=" ++ opt | opt <- PD.ldOptions bi ] + -- Options from the current package: + ++ [ "--cflag=-I" ++ dir | dir <- PD.includeDirs bi ] + ++ [ "--cflag=" ++ opt | opt <- PD.ccOptions bi + ++ PD.cppOptions bi ] + ++ [ "--lflag=-L" ++ opt | opt <- PD.extraLibDirs bi ] + ++ [ "--lflag=-Wl,-R," ++ opt | isELF + , opt <- PD.extraLibDirs bi ] + ++ [ "--lflag=-l" ++ opt | opt <- PD.extraLibs bi ] + ++ [ "--lflag=" ++ opt | opt <- PD.ldOptions bi ] hunk ./Distribution/Simple/PreProcess.hs 415 - -- Options from dependent packages - ++ [ "--cflag=" ++ opt - | pkg <- pkgs - , opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] - ++ [ opt | opt <- Installed.ccOptions pkg ] ] - ++ [ "--lflag=" ++ opt - | pkg <- pkgs - , opt <- [ "-L" ++ opt | opt <- Installed.libraryDirs pkg ] - ++ [ "-Wl,-R," ++ opt | isELF - , opt <- Installed.libraryDirs pkg ] - ++ [ "-l" ++ opt | opt <- Installed.extraLibraries pkg ] - ++ [ opt | opt <- Installed.ldOptions pkg ] ] + -- Options from dependent packages + ++ [ "--cflag=" ++ opt + | pkg <- pkgs + , opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] + ++ [ opt | opt <- Installed.ccOptions pkg ] ] + ++ [ "--lflag=" ++ opt + | pkg <- pkgs + , opt <- [ "-L" ++ opt | opt <- Installed.libraryDirs pkg ] + ++ [ "-Wl,-R," ++ opt | isELF + , opt <- Installed.libraryDirs pkg ] + ++ [ "-l" ++ opt | opt <- Installed.extraLibraries pkg ] + ++ [ opt | opt <- Installed.ldOptions pkg ] ] + ++ ["-o", outFile, inFile] + } hunk ./Distribution/Simple/PreProcess.hs 431 - Just gccProg = lookupProgram gccProgram (withPrograms lbi) hunk ./Distribution/Simple/PreProcess.hs 448 -ppC2hs bi lbi - = PreProcessor { - platformIndependent = False, - runPreProcessor = \(inBaseDir, inRelativeFile) - (outBaseDir, outRelativeFile) verbosity -> - rawSystemProgramConf verbosity c2hsProgram (withPrograms lbi) $ - ["--include=" ++ outBaseDir] - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ outBaseDir, - "--output=" ++ outRelativeFile, - inBaseDir inRelativeFile] - } +ppC2hs bi lbi = + PreProcessor { + platformIndependent = False, + runPreProcessor = \(inBaseDir, inRelativeFile) + (outBaseDir, outRelativeFile) verbosity -> do + (c2hsProg, _, _) <- requireProgramVersion verbosity + c2hsProgram (orLaterVersion (Version [0,15] [])) + (withPrograms lbi) + (gccProg, _) <- requireProgram verbosity gccProgram (withPrograms lbi) + rawSystemProgram verbosity c2hsProg $ + + -- Options from the current package: + [ "--cpp=" ++ programPath gccProg, "--cppopts=-E" ] + ++ [ "--cppopts=" ++ opt | opt <- getCppOptions bi lbi ] + ++ [ "--include=" ++ outBaseDir ] + + -- Options from dependent packages + ++ [ "--cppopts=" ++ opt + | pkg <- pkgs + , opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] + ++ [ opt | opt@('-':c:_) <- Installed.ccOptions pkg + , c `elem` "DIU" ] ] + --TODO: install .chi files for packages, so we can --include + -- those dirs here, for the dependencies + + -- input and output files + ++ [ "--output-dir=" ++ outBaseDir + , "--output=" ++ outRelativeFile + , inBaseDir inRelativeFile ] + } + where + pkgs = PackageIndex.topologicalOrder (installedPkgs lbi) hunk ./Language/Haskell/Extension.hs 66 +-- +-- Where applicable, references are given to an implementation's +-- official documentation, e.g. \"GHC § 7.2.1\" for an extension +-- documented in section 7.2.1 of the GHC User's Guide. hunk ./Language/Haskell/Extension.hs 71 -data Extension - = OverlappingInstances +data Extension = + + -- | [GHC § 7.6.3.4] Allow overlapping class instances, + -- provided there is a unique most specific instance for each use. + OverlappingInstances + + -- | [GHC § 7.6.3.3] Ignore structural rules guaranteeing the + -- termination of class instance resolution. Termination is + -- guaranteed by a fixed-depth recursion stack, and compilation + -- may fail if this depth is exceeded. hunk ./Language/Haskell/Extension.hs 82 + + -- | [GHC § 7.6.3.4] Implies 'OverlappingInstances'. Allow the + -- implementation to choose an instance even when it is possible + -- that further instantiation of types will lead to a more specific + -- instance being applicable. hunk ./Language/Haskell/Extension.hs 88 + + -- | [GHC § 7.3.8.2] Deprecated in GHC. Allows recursive bindings + -- using @mdo@, a variant of @do@. @DoRec@ provides a different, + -- preferred syntax. hunk ./Language/Haskell/Extension.hs 93 + + -- | [GHC § 7.3.9] Provide syntax for writing list + -- comprehensions which iterate over several lists together, like + -- the 'zipWith' family of functions. hunk ./Language/Haskell/Extension.hs 98 + + -- | [GHC § 7.6.1.1] Allow multiple parameters in a type class. hunk ./Language/Haskell/Extension.hs 101 + + -- | [GHC § 7.17] Disable the dreaded monomorphism restriction. hunk ./Language/Haskell/Extension.hs 104 + + -- | [GHC § 7.6.2] Allow a specification attached to a + -- multi-parameter type class which indicates that some parameters + -- are entirely determined by others. The implementation will check + -- that this property holds for the declared instances, and will use + -- this property to reduce ambiguity in instance resolution. hunk ./Language/Haskell/Extension.hs 111 + + -- | [GHC § 7.8.5] Like 'RankNTypes' but does not allow a + -- higher-rank type to itself appear on the left of a function + -- arrow. hunk ./Language/Haskell/Extension.hs 116 + + -- | [GHC § 7.8.5] Allow a universally-quantified type to occur on + -- the left of a function arrow. hunk ./Language/Haskell/Extension.hs 120 + + -- | [GHC § 7.8.5] Allow data constructors to have polymorphic + -- arguments. Unlike 'RankNTypes', does not allow this for ordinary + -- functions. hunk ./Language/Haskell/Extension.hs 125 + + -- | [GHC § 7.4.4] Allow existentially-quantified data constructors. hunk ./Language/Haskell/Extension.hs 128 + + -- | [GHC § 7.8.7] Cause a type variable in a signature, which has an + -- explicit @forall@ quantifier, to scope over the definition of the + -- accompanying value declaration. hunk ./Language/Haskell/Extension.hs 133 - -- | Deprecated, use ScopedTypeVariables instead. + + -- | Deprecated, use 'ScopedTypeVariables' instead. hunk ./Language/Haskell/Extension.hs 136 + + -- | [GHC § 7.8.3] Enable implicit function parameters with dynamic + -- scope. hunk ./Language/Haskell/Extension.hs 140 + + -- | [GHC § 7.8.2] Relax some restrictions on the form of the context + -- of a type signature. hunk ./Language/Haskell/Extension.hs 144 + + -- | [GHC § 7.6.3.2] Relax some restrictions on the form of the + -- context of an instance declaration. hunk ./Language/Haskell/Extension.hs 148 + + -- | [GHC § 7.4.1] Allow data type declarations with no constructors. hunk ./Language/Haskell/Extension.hs 151 + + -- | [GHC § 4.10.3] Run the C preprocessor on Haskell source code. hunk ./Language/Haskell/Extension.hs 155 + -- | [GHC § 7.8.4] Allow an explicit kind signature giving the kind of + -- types over which a type variable ranges. hunk ./Language/Haskell/Extension.hs 158 + + -- | [GHC § 7.11] Enable a form of pattern which forces evaluation + -- before an attempted match, and a form of strict @let@/@where@ + -- binding. hunk ./Language/Haskell/Extension.hs 163 + + -- | [GHC § 7.6.3.1] Allow type synonyms in instance heads. hunk ./Language/Haskell/Extension.hs 166 + + -- | [GHC § 7.9] Enable Template Haskell, a system for compile-time + -- metaprogramming. hunk ./Language/Haskell/Extension.hs 170 + + -- | [GHC § 8] Enable the Foreign Function Interface. In GHC, + -- implements the standard Haskell 98 Foreign Function Interface + -- Addendum, plus some GHC-specific extensions. hunk ./Language/Haskell/Extension.hs 175 + + -- | [GHC § 7.10] Enable arrow notation. hunk ./Language/Haskell/Extension.hs 178 + + -- | [GHC § 7.16] Enable generic type classes, with default instances + -- defined in terms of the algebraic structure of a type. hunk ./Language/Haskell/Extension.hs 182 + + -- | [GHC § 7.3.11] Disable the implicit importing of the module + -- @Prelude@. When desugaring certain built-in syntax into ordinary + -- identifiers, use whatever is in scope rather than the @Prelude@ + -- version. hunk ./Language/Haskell/Extension.hs 188 + + -- | [GHC § 7.3.15] Enable syntax for implicitly binding local names + -- corresponding to the field names of a record. Puns bind specific + -- names, unlike 'RecordWildCards'. hunk ./Language/Haskell/Extension.hs 193 + + -- | [GHC § 7.3.5] Enable a form of guard which matches a pattern and + -- binds variables. hunk ./Language/Haskell/Extension.hs 197 + + -- | [GHC § 7.5.4] Allow a type declared with @newtype@ to use + -- @deriving@ for any class with an instance for the underlying type. hunk ./Language/Haskell/Extension.hs 202 + -- | [Hugs § 7.1] Enable the \"Trex\" extensible records system. hunk ./Language/Haskell/Extension.hs 204 + + -- | [Hugs § 7.2] Enable type synonyms which are transparent in + -- some definitions and opaque elsewhere, as a way of implementing + -- abstract datatypes. hunk ./Language/Haskell/Extension.hs 209 + + -- | [Hugs § 7.3] Enable an alternate syntax for string literals, + -- with string templating. hunk ./Language/Haskell/Extension.hs 213 + + -- | [GHC § 7.3.2] Allow the character @#@ as a postfix modifier on + -- identifiers. Also enables literal syntax for unboxed values. hunk ./Language/Haskell/Extension.hs 217 + + -- | [GHC § 7.7] Allow data types and type synonyms which are + -- indexed by types, i.e. ad-hoc polymorphism for types. hunk ./Language/Haskell/Extension.hs 221 + + -- | [GHC § 7.5.2] Allow a standalone declaration which invokes the + -- type class @deriving@ mechanism. hunk ./Language/Haskell/Extension.hs 226 + -- | [GHC § 7.3.1] Allow certain Unicode characters to stand for + -- certain ASCII character sequences, e.g. keywords and punctuation. hunk ./Language/Haskell/Extension.hs 229 + + -- | [GHC § 8.1.1] Allow the use of unboxed types as foreign types, + -- e.g. in @foreign import@ and @foreign export@. hunk ./Language/Haskell/Extension.hs 233 + + -- | [GHC § 7.4.3] Defer validity checking of types until after + -- expanding type synonyms, relaxing the constraints on how synonyms + -- may be used. hunk ./Language/Haskell/Extension.hs 238 + + -- | [GHC § 7.4.2] Allow the name of a type constructor, type class, + -- or type variable to be an infix operator. hunk ./Language/Haskell/Extension.hs 242 + hunk ./Language/Haskell/Extension.hs 244 + + -- | [GHC § 7.3.16] Enable syntax for implicitly binding local names + -- corresponding to the field names of a record. A wildcard binds + -- all unmentioned names, unlike 'NamedFieldPuns'. hunk ./Language/Haskell/Extension.hs 249 + + -- | Deprecated, use 'NamedFieldPuns' instead. hunk ./Language/Haskell/Extension.hs 252 + + -- | [GHC § 7.3.14] Allow a record field name to be disambiguated + -- by the type of the record it's in. hunk ./Language/Haskell/Extension.hs 256 + + -- | [GHC § 7.6.4] Enable overloading of string literals using a + -- type class, much like integer literals. hunk ./Language/Haskell/Extension.hs 260 + + -- | [GHC § 7.4.6] Enable generalized algebraic data types, in + -- which type variables may be instantiated on a per-constructor + -- basis. Enables \"GADT syntax\" which can be used to declare + -- GADTs as well as ordinary algebraic types. hunk ./Language/Haskell/Extension.hs 266 + + -- | [GHC § 7.17.2] Allow pattern bindings to be polymorphic. hunk ./Language/Haskell/Extension.hs 269 + + -- | [GHC § 7.8.8] Relax the requirements on mutually-recursive + -- polymorphic functions. hunk ./Language/Haskell/Extension.hs 273 + + -- | [GHC § 2.4.5] Allow default instantiation of polymorphic + -- types in more situations. hunk ./Language/Haskell/Extension.hs 277 + + -- | [GHC § 7.2.2] Enable unboxed tuples. hunk ./Language/Haskell/Extension.hs 280 + + -- | [GHC § 7.5.3] Enable @deriving@ for classes + -- @Data.Typeable.Typeable@ and @Data.Generics.Data@. hunk ./Language/Haskell/Extension.hs 284 + + -- | [GHC § 7.6.1.3] Allow a class method's type to place + -- additional constraints on a class type variable. hunk ./Language/Haskell/Extension.hs 289 - -- | Allow imports to be qualified by the package name that the module - -- is intended to be imported from, e.g. + -- | [GHC § 7.3.18] Allow imports to be qualified by the package + -- name the module is intended to be imported from, e.g. hunk ./Language/Haskell/Extension.hs 295 + -- | [GHC § 7.8.6] Deprecated in GHC 6.12 and will be removed in + -- GHC 6.14. Allow a type variable to be instantiated at a + -- polymorphic type. hunk ./Language/Haskell/Extension.hs 299 + + -- | [GHC § 7.3.3] Change the syntax for qualified infix + -- operators. hunk ./Language/Haskell/Extension.hs 303 + + -- | [GHC § 7.3.12] Relax the interpretation of left operator + -- sections to allow unary postfix operators. hunk ./Language/Haskell/Extension.hs 307 + + -- | [GHC § 7.9.5] Enable quasi-quotation, a mechanism for defining + -- new concrete syntax for expressions and patterns. hunk ./Language/Haskell/Extension.hs 311 + + -- | [GHC § 7.3.10] Enable generalized list comprehensions, + -- supporting operations such as sorting and grouping. hunk ./Language/Haskell/Extension.hs 315 + + -- | [GHC § 7.3.6] Enable view patterns, which match a value by + -- applying a function and matching on the result. hunk ./Language/Haskell/Extension.hs 323 - -- discussed in the paper "Haskell Server Pages through Dynamic Loading" + -- discussed in the paper \"Haskell Server Pages through Dynamic Loading\" hunk ./Language/Haskell/Extension.hs 328 - -- paper "Regular Expression Patterns" by Niklas Broberg, Andreas Farre + -- paper \"Regular Expression Patterns\" by Niklas Broberg, Andreas Farre hunk ./Language/Haskell/Extension.hs 332 + -- | An unknown extension, identified by the name of its @LANGUAGE@ + -- pragma. hunk ./Distribution/Simple/Configure.hs 781 +-- Try to build a test C program which includes every header and links every +-- lib. If that fails, try to narrow it down by preprocessing (only) and linking +-- with individual headers and libs. If none is the obvious culprit then give a +-- generic error message. +-- TODO: produce a log file from the compiler errors, if any. hunk ./Distribution/Simple/Configure.hs 801 - -- NOTE: if some package-local header has errors, - -- we will report that this header is missing. - -- Maybe additional tests for local headers are needed - -- for better diagnostics hunk ./Distribution/Simple/Configure.hs 812 - cppArgs = "-c":commonCcArgs -- don't try to link + cppArgs = "-E":commonCcArgs -- preprocess only hunk ./Distribution/Simple/Configure.hs 861 - explainErrors Nothing [] = return () + explainErrors Nothing [] = die messageUnknownError + where + messageUnknownError = + "All foreign libraries and headers were found, but the C " + ++ "compiler encountered an error when including and linking " + ++ "them all together. You can re-run configure with the " + ++ "verbosity flag -v3 to see the error messages." + hunk ./Distribution/Simple/Configure.hs 874 - Just h -> ["* Missing header file: " ++ h ] + Just h -> ["* Missing or erroneous header file: " ++ h ] hunk ./Distribution/Simple/Configure.hs 880 + ++ case hdr of + Nothing -> [] + Just _ -> [hdrMessage] hunk ./Distribution/Simple/Configure.hs 899 + hdrMessage = + "If the header file does exist, it may contain errors that " + ++ "are caught at the preprocessing stage." hunk ./Distribution/Simple/Configure.hs 802 - ifBuildsWith allHeaders cppArgs + ifBuildsWith allHeaders ccArgs hunk ./Distribution/Simple/Configure.hs 807 - go (hdrs:hdrsInits) = do + go (hdrs:hdrsInits) = + -- Try just preprocessing first hunk ./Distribution/Simple/Configure.hs 810 - (go hdrsInits) - (return . Just . last $ hdrs) + -- If that works, try compiling too + (ifBuildsWith hdrs ccArgs + (go hdrsInits) + (return . Just . Right . last $ hdrs)) + (return . Just . Left . last $ hdrs) hunk ./Distribution/Simple/Configure.hs 816 - cppArgs = "-E":commonCcArgs -- preprocess only + cppArgs = "-E":commonCppArgs -- preprocess only + ccArgs = "-c":commonCcArgs -- don't try to link hunk ./Distribution/Simple/Configure.hs 825 - commonCcArgs = hcDefines (compiler lbi) + commonCppArgs = hcDefines (compiler lbi) hunk ./Distribution/Simple/Configure.hs 837 + commonCcArgs = commonCppArgs + ++ collectField PD.ccOptions + ++ [ opt + | dep <- deps + , opt <- Installed.ccOptions dep ] + hunk ./Distribution/Simple/Configure.hs 872 - explainErrors Nothing [] = die messageUnknownError - where - messageUnknownError = - "All foreign libraries and headers were found, but the C " - ++ "compiler encountered an error when including and linking " - ++ "them all together. You can re-run configure with the " - ++ "verbosity flag -v3 to see the error messages." - - explainErrors hdr libs = die $ unlines $ - (if plural then "Missing dependencies on foreign libraries:" - else "Missing dependency on a foreign library:") - : case hdr of - Nothing -> [] - Just h -> ["* Missing or erroneous header file: " ++ h ] + explainErrors Nothing [] = return () -- should be impossible! + explainErrors hdr libs = die $ unlines $ + [ if plural + then "Missing dependencies on foreign libraries:" + else "Missing dependency on a foreign library:" + | missing ] + ++ case hdr of + Just (Left h) -> ["* Missing (or bad) header file: " ++ h ] + _ -> [] hunk ./Distribution/Simple/Configure.hs 885 - ++ [if plural then messagePlural else messageSingular] + ++ [if plural then messagePlural else messageSingular | missing] hunk ./Distribution/Simple/Configure.hs 887 - Nothing -> [] - Just _ -> [hdrMessage] + Just (Left _) -> [ headerCppMessage ] + Just (Right h) -> [ (if missing then "* " else "") + ++ "Bad header file: " ++ h + , headerCcMessage ] + _ -> [] + hunk ./Distribution/Simple/Configure.hs 894 - plural = length libs >= 2 - messageSingular = - "This problem can usually be solved by installing the system " - ++ "package that provides this library (you may need the " - ++ "\"-dev\" version). If the library is already installed " - ++ "but in a non-standard location then you can use the flags " - ++ "--extra-include-dirs= and --extra-lib-dirs= to specify " - ++ "where it is." - messagePlural = - "This problem can usually be solved by installing the system " - ++ "packages that provide these libraries (you may need the " - ++ "\"-dev\" versions). If the libraries are already installed " - ++ "but in a non-standard location then you can use the flags " - ++ "--extra-include-dirs= and --extra-lib-dirs= to specify " - ++ "where they are." - hdrMessage = - "If the header file does exist, it may contain errors that " - ++ "are caught at the preprocessing stage." + plural = length libs >= 2 + -- Is there something missing? (as opposed to broken) + missing = not (null libs) + || case hdr of Just (Left _) -> True; _ -> False + + messageSingular = + "This problem can usually be solved by installing the system " + ++ "package that provides this library (you may need the " + ++ "\"-dev\" version). If the library is already installed " + ++ "but in a non-standard location then you can use the flags " + ++ "--extra-include-dirs= and --extra-lib-dirs= to specify " + ++ "where it is." + messagePlural = + "This problem can usually be solved by installing the system " + ++ "packages that provide these libraries (you may need the " + ++ "\"-dev\" versions). If the libraries are already installed " + ++ "but in a non-standard location then you can use the flags " + ++ "--extra-include-dirs= and --extra-lib-dirs= to specify " + ++ "where they are." + headerCppMessage = + "If the header file does exist, it may contain errors that " + ++ "are caught by the C compiler at the preprocessing stage. " + ++ "In this case you can re-run configure with the verbosity " + ++ "flag -v3 to see the error messages." + headerCcMessage = + "The header file contains a compile error. " + ++ "You can re-run configure with the verbosity flag " + ++ "-v3 to see the error messages from the C compiler." hunk ./Distribution/Simple/Build/Macros.hs 13 +-- > VERSION_ hunk ./Distribution/Simple/Build/Macros.hs 44 + , "#define VERSION_",pkgname,show (display version),"\n" hunk ./Distribution/License.hs 109 - , BSD3, BSD4, MIT + , BSD3, MIT hunk ./Language/Haskell/Extension.hs 88 + + -- | [GHC § 7.3.8] Allows recursive bindings in @do@ blocks, + -- using the @rec@ keyword. + | DoRec hunk ./Cabal.cabal 40 - filepath >= 1 && < 1.2 + filepath >= 1 && < 1.3 hunk ./tests/PackageTests/PackageTester.hs 109 - run (Just $ directory spec) "runhaskell" (["Setup"] ++ cabalArgs) + run (Just $ directory spec) "runghc" (["Setup.hs"] ++ cabalArgs) hunk ./Cabal.cabal 105 + Distribution.Simple.UHC, hunk ./Distribution/Compiler.hs 76 -data CompilerFlavor = GHC | NHC | YHC | Hugs | HBC | Helium | JHC | LHC +data CompilerFlavor = GHC | NHC | YHC | Hugs | HBC | Helium | JHC | LHC | UHC hunk ./Distribution/Compiler.hs 81 -knownCompilerFlavors = [GHC, NHC, YHC, Hugs, HBC, Helium, JHC, LHC] +knownCompilerFlavors = [GHC, NHC, YHC, Hugs, HBC, Helium, JHC, LHC, UHC] hunk ./Distribution/Simple/Build.hs 60 +import qualified Distribution.Simple.UHC as UHC hunk ./Distribution/Simple/Build.hs 163 + UHC -> UHC.buildLib verbosity pkg_descr lbi lib clbi hunk ./Distribution/Simple/Configure.hs 121 +import qualified Distribution.Simple.UHC as UHC hunk ./Distribution/Simple/Configure.hs 779 + UHC -> UHC.configure verbosity hcPath hcPkg conf hunk ./Distribution/Simple/Program.hs 96 + , uhcProgram hunk ./Distribution/Simple/Program/Builtin.hs 28 + uhcProgram, hunk ./Distribution/Simple/Program/Builtin.hs 71 + , uhcProgram hunk ./Distribution/Simple/Program/Builtin.hs 153 +uhcProgram = (simpleProgram "uhc") { + programFindVersion = findProgramVersion "--numeric-version" id + } + hunk ./Distribution/Simple/Setup.hs 336 - , (Flag Hugs,([] , ["hugs"]), "compile with Hugs")]) + , (Flag Hugs,([] , ["hugs"]), "compile with Hugs") + , (Flag UHC, ([] , ["uhc"]), "compile with UHC")]) addfile ./Distribution/Simple/UHC.hs hunk ./Distribution/Simple/UHC.hs 1 +----------------------------------------------------------------------------- +-- | +-- Module : Distribution.Simple.UHC +-- Copyright : Andres Loeh 2009 +-- +-- Maintainer : cabal-devel@haskell.org +-- Portability : portable +-- +-- This module contains most of the UHC-specific code for configuring, building +-- and installing packages. + +{- +Copyright (c) 2009, Andres Loeh +Copyright (c) 2003-2005, Isaac Jones +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Isaac Jones nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -} + +module Distribution.Simple.UHC ( + configure, buildLib + ) where + +import Data.List +import Distribution.Package +import Distribution.PackageDescription +import Distribution.Simple.BuildPaths +import Distribution.Simple.Compiler as C +import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Program +import Distribution.Text +import Distribution.Verbosity +import Distribution.Version +import Language.Haskell.Extension +import System.FilePath + +-- ----------------------------------------------------------------------------- +-- Configuring + +configure :: Verbosity -> Maybe FilePath -> Maybe FilePath + -> ProgramConfiguration -> IO (Compiler, ProgramConfiguration) +configure verbosity hcPath _hcPkgPath conf = do + + (_uhcProg, uhcVersion, conf') <- + requireProgramVersion verbosity uhcProgram + (orLaterVersion (Version [1,0,2] [])) + (userMaybeSpecifyPath "uhc" hcPath conf) + + let comp = Compiler { + compilerId = CompilerId UHC uhcVersion, + compilerExtensions = uhcLanguageExtensions + } + return (comp, conf') + +-- | The flags for the supported extensions. +uhcLanguageExtensions :: [(Extension, C.Flag)] +uhcLanguageExtensions = [] + + +-- ----------------------------------------------------------------------------- +-- Building + +buildLib :: Verbosity -> PackageDescription -> LocalBuildInfo + -> Library -> ComponentLocalBuildInfo -> IO () +buildLib verbosity pkg_descr lbi lib clbi = do + + let runUhcProg = rawSystemProgramConf verbosity uhcProgram (withPrograms lbi) + let uhcArgs = -- set package name + ["--pkg-build=" ++ display (packageId pkg_descr)] + -- common flags lib/exe + ++ constructUHCCmdLine lbi (libBuildInfo lib) clbi + (buildDir lbi) verbosity + -- source files + -- suboptimal: UHC does not understand module names, so + -- we replace periods by path separators + ++ map (map (\ c -> if c == '.' then pathSeparator else c)) + (map display (libModules lib)) + + runUhcProg uhcArgs + + return () + +constructUHCCmdLine :: LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo + -> FilePath -> Verbosity -> [String] +constructUHCCmdLine lbi bi clbi odir verbosity = + -- verbosity + (if verbosity >= deafening then ["-v4"] + else if verbosity >= normal then [] + else ["-v0"]) + -- packages + ++ ["--hide-all-packages"] + ++ ["--package=" ++ display (pkgName pkgid) | (_, pkgid) <- componentPackageDeps clbi ] + -- search paths + ++ ["-i" ++ odir] + ++ ["-i" ++ l | l <- nub (hsSourceDirs bi)] + ++ ["-i" ++ autogenModulesDir lbi] + -- output path + ++ ["--odir=" ++ odir] + -- optimization + ++ (case withOptimization lbi of + NoOptimisation -> ["-O0"] + NormalOptimisation -> ["-O1"] + MaximumOptimisation -> ["-O2"]) hunk ./Distribution/Simple/Configure.hs 613 + UHC -> UHC.getInstalledPackages verbosity comp packageDBs progconf hunk ./Distribution/Simple/Install.hs 68 +import qualified Distribution.Simple.UHC as UHC hunk ./Distribution/Simple/Install.hs 168 + UHC -> do withLib pkg_descr $ \ _ -> UHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr hunk ./Distribution/Simple/InstallDirs.hs 239 + UHC -> "$pkgid" hunk ./Distribution/Simple/Register.hs 74 +import qualified Distribution.Simple.UHC as UHC hunk ./Distribution/Simple/Register.hs 164 + UHC -> notice verbosity "Registration scripts not needed for uhc" hunk ./Distribution/Simple/Register.hs 217 + UHC -> UHC.registerPackage verbosity installedPkgInfo pkg lbi inplace packageDbs hunk ./Distribution/Simple/UHC.hs 11 +-- +-- Thanks to the authors of the other implementation-specific files, in +-- particular to Isaac Jones, Duncan Coutts and Henning Thielemann, for +-- inspiration on how to design this module. hunk ./Distribution/Simple/UHC.hs 50 - configure, buildLib + configure, getInstalledPackages, + buildLib, installLib, registerPackage hunk ./Distribution/Simple/UHC.hs 54 +import Control.Monad hunk ./Distribution/Simple/UHC.hs 56 +import Distribution.Compat.ReadP +import Distribution.InstalledPackageInfo hunk ./Distribution/Simple/UHC.hs 63 +import Distribution.Simple.PackageIndex hunk ./Distribution/Simple/UHC.hs 65 +import Distribution.Simple.Setup +import Distribution.Simple.Utils hunk ./Distribution/Simple/UHC.hs 71 +import System.Directory hunk ./Distribution/Simple/UHC.hs 94 -uhcLanguageExtensions = [] +uhcLanguageExtensions = + [(CPP, "--cpp"), + (PolymorphicComponents, ""), + (ExistentialQuantification, ""), + (FlexibleInstances, "")] + +getInstalledPackages :: Verbosity -> Compiler -> PackageDBStack -> ProgramConfiguration + -> IO PackageIndex +getInstalledPackages verbosity comp packagedbs conf = do + let compilerid = compilerId comp + systemPkgDir <- rawSystemProgramStdoutConf verbosity uhcProgram conf ["--meta-pkgdir-system"] + userPkgDir <- getUserPackageDir + let pkgDirs = nub (concatMap (packageDbPaths userPkgDir systemPkgDir) packagedbs) + -- putStrLn $ "pkgdirs: " ++ show pkgDirs + -- call to "lines" necessary, because pkgdir contains an extra newline at the end + pkgs <- liftM (map addBuiltinVersions . concat) . + mapM (\ d -> getDirectoryContents d >>= filterM (isPkgDir (display compilerid) d)) . + concatMap lines $ pkgDirs + -- putStrLn $ "pkgs: " ++ show pkgs + let iPkgs = + map mkInstalledPackageInfo $ + concatMap parsePackage $ + pkgs + -- putStrLn $ "installed pkgs: " ++ show iPkgs + return (fromList iPkgs) + +getUserPackageDir :: IO FilePath +getUserPackageDir = + do + homeDir <- getHomeDirectory + return $ homeDir ".cabal" "lib" -- TODO: determine in some other way + +packageDbPaths :: FilePath -> FilePath -> PackageDB -> [FilePath] +packageDbPaths user system db = + case db of + GlobalPackageDB -> [ system ] + UserPackageDB -> [ user ] + SpecificPackageDB path -> [ path ] + +-- | Hack to add version numbers to UHC-builtin packages. This should sooner or +-- later be fixed on the UHC side. +addBuiltinVersions :: String -> String +addBuiltinVersions "base" = "base-3.0" +addBuiltinVersions "array" = "array-0.2" +addBuiltinVersions xs = xs + +-- | Name of the installed package config file. +installedPkgConfig :: String +installedPkgConfig = "installed-pkg-config" + +-- | Check if a certain dir contains a valid package. Currently, we are +-- looking only for the presence of an installed package configuration. +-- TODO: Actually make use of the information provided in the file. +isPkgDir :: String -> String -> String -> IO Bool +isPkgDir c dir ('.' : xs) = return False -- ignore files starting with a . +isPkgDir c dir xs = do + let candidate = dir uhcPackageDir xs c + -- putStrLn $ "trying: " ++ candidate + doesFileExist (candidate installedPkgConfig) + +parsePackage :: String -> [PackageId] +parsePackage x = map fst (filter (\ (_,x) -> null x) (readP_to_S parse x)) + +-- | Create a trivial package info from a directory name. +mkInstalledPackageInfo :: PackageId -> InstalledPackageInfo +mkInstalledPackageInfo p = emptyInstalledPackageInfo + { installedPackageId = InstalledPackageId (display p), + sourcePackageId = p } hunk ./Distribution/Simple/UHC.hs 171 + systemPkgDir <- rawSystemProgramStdoutConf verbosity uhcProgram (withPrograms lbi) ["--meta-pkgdir-system"] + userPkgDir <- getUserPackageDir hunk ./Distribution/Simple/UHC.hs 177 - ++ constructUHCCmdLine lbi (libBuildInfo lib) clbi + ++ constructUHCCmdLine userPkgDir systemPkgDir + lbi (libBuildInfo lib) clbi hunk ./Distribution/Simple/UHC.hs 190 -constructUHCCmdLine :: LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo +constructUHCCmdLine :: FilePath -> FilePath + -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo hunk ./Distribution/Simple/UHC.hs 193 -constructUHCCmdLine lbi bi clbi odir verbosity = +constructUHCCmdLine user system lbi bi clbi odir verbosity = hunk ./Distribution/Simple/UHC.hs 198 + -- flags for language extensions + ++ extensionsToFlags (compiler lbi) (extensions bi) hunk ./Distribution/Simple/UHC.hs 202 + ++ uhcPackageDbOptions user system (withPackageDB lbi) hunk ./Distribution/Simple/UHC.hs 215 + +uhcPackageDbOptions :: FilePath -> FilePath -> PackageDBStack -> [String] +uhcPackageDbOptions user system db = map (\ x -> "--pkg-searchpath=" ++ x) + (concatMap (packageDbPaths user system) db) + +-- ----------------------------------------------------------------------------- +-- Installation + +installLib :: CopyFlags -> LocalBuildInfo + -> FilePath -> FilePath -> FilePath + -> PackageDescription -> IO () +installLib flags lbi targetDir dynlibTargetDir builtDir + pkg@PackageDescription{ library = Nothing } = + return () -- TODO: is this ok? +installLib flags lbi targetDir dynlibTargetDir builtDir + pkg@PackageDescription{ library = Just lib } = do + + -- putStrLn $ "dest: " ++ targetDir + -- putStrLn $ "built: " ++ builtDir + + let verbosity = fromFlag (copyVerbosity flags) + copyHelper installFun src dst n = do + createDirectoryIfMissingVerbose verbosity True dst + installFun verbosity (src n) (dst n) + copy = copyHelper installOrdinaryFile + copyShared = copyHelper installExecutableFile + copyModuleFiles ext = + findModuleFiles [builtDir] [ext] (libModules lib) + >>= installOrdinaryFiles verbosity targetDir + + installDirectoryContents verbosity (builtDir display pkgid) targetDir + + where + + vanillaLibName = mkUHCLibName pkgid + pkgid = packageId pkg + +-- GHC library names have an extra HS +mkUHCLibName :: PackageIdentifier -> String +mkUHCLibName lib = "lib" ++ display lib <.> "a" + +-- currently hardcoded UHC code generator and variant to use +uhcTarget = "bc" +uhcTargetVariant = "plain" + +-- root directory for a package in UHC +uhcPackageDir pkgid compilerid = pkgid uhcPackageSubDir compilerid +uhcPackageSubDir compilerid = compilerid "bc" "plain" + +-- ----------------------------------------------------------------------------- +-- Registering + +registerPackage + :: Verbosity + -> InstalledPackageInfo + -> PackageDescription + -> LocalBuildInfo + -> Bool + -> PackageDBStack + -> IO () +registerPackage verbosity installedPkgInfo pkg lbi inplace _packageDbs = do + let installDirs = absoluteInstallDirs pkg lbi NoCopyDest + pkgdir | inplace = buildDir lbi uhcPackageDir (display pkgid) (display compilerid) + | otherwise = libdir installDirs uhcPackageSubDir (display compilerid) + createDirectoryIfMissingVerbose verbosity True pkgdir + writeUTF8File (pkgdir installedPkgConfig) + (showInstalledPackageInfo installedPkgInfo) + where + pkgid = packageId pkg + compilerid = compilerId (compiler lbi) hunk ./Distribution/Simple/UHC.hs 148 -isPkgDir c dir ('.' : xs) = return False -- ignore files starting with a . +isPkgDir _ _ ('.' : _) = return False -- ignore files starting with a . hunk ./Distribution/Simple/UHC.hs 155 -parsePackage x = map fst (filter (\ (_,x) -> null x) (readP_to_S parse x)) +parsePackage x = map fst (filter (\ (_,y) -> null y) (readP_to_S parse x)) hunk ./Distribution/Simple/UHC.hs 226 -installLib flags lbi targetDir dynlibTargetDir builtDir - pkg@PackageDescription{ library = Nothing } = +installLib _flags _lbi _targetDir _dynlibTargetDir _builtDir + PackageDescription{ library = Nothing } = hunk ./Distribution/Simple/UHC.hs 229 -installLib flags lbi targetDir dynlibTargetDir builtDir - pkg@PackageDescription{ library = Just lib } = do - +installLib flags _lbi targetDir _dynlibTargetDir builtDir + pkg@PackageDescription{ library = Just _ } = do hunk ./Distribution/Simple/UHC.hs 233 - hunk ./Distribution/Simple/UHC.hs 234 - copyHelper installFun src dst n = do - createDirectoryIfMissingVerbose verbosity True dst - installFun verbosity (src n) (dst n) - copy = copyHelper installOrdinaryFile - copyShared = copyHelper installExecutableFile - copyModuleFiles ext = - findModuleFiles [builtDir] [ext] (libModules lib) - >>= installOrdinaryFiles verbosity targetDir - - installDirectoryContents verbosity (builtDir display pkgid) targetDir - - where - - vanillaLibName = mkUHCLibName pkgid - pkgid = packageId pkg - --- GHC library names have an extra HS -mkUHCLibName :: PackageIdentifier -> String -mkUHCLibName lib = "lib" ++ display lib <.> "a" + installDirectoryContents verbosity (builtDir display (packageId pkg)) targetDir hunk ./Distribution/Simple/UHC.hs 237 +uhcTarget, uhcTargetVariant :: String hunk ./Distribution/Simple/UHC.hs 242 +uhcPackageDir :: String -> String -> FilePath +uhcPackageSubDir :: String -> FilePath hunk ./Distribution/Simple/UHC.hs 245 -uhcPackageSubDir compilerid = compilerid "bc" "plain" +uhcPackageSubDir compilerid = compilerid uhcTarget uhcTargetVariant hunk ./Distribution/Simple/GHC.hs 80 - ( PackageDescription(..), BuildInfo(..), Executable(..), withExe + ( PackageDescription(..), BuildInfo(..), Executable(..) hunk ./Distribution/Simple/GHC.hs 872 + -> Executable hunk ./Distribution/Simple/GHC.hs 874 -installExe flags lbi installDirs buildPref (progprefix, progsuffix) pkg_descr - = do let verbosity = fromFlag (copyVerbosity flags) - binDir = bindir installDirs - createDirectoryIfMissingVerbose verbosity True binDir - withExe pkg_descr $ \Executable { exeName = e } -> do - let exeFileName = e <.> exeExtension - fixedExeBaseName = progprefix ++ e ++ progsuffix - installBinary dest = do - installExecutableFile verbosity - (buildPref e exeFileName) - (dest <.> exeExtension) - stripExe verbosity lbi exeFileName (dest <.> exeExtension) - installBinary (binDir fixedExeBaseName) +installExe flags lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do + let verbosity = fromFlag (copyVerbosity flags) + binDir = bindir installDirs + createDirectoryIfMissingVerbose verbosity True binDir + let exeFileName = exeName exe <.> exeExtension + fixedExeBaseName = progprefix ++ exeName exe ++ progsuffix + installBinary dest = do + installExecutableFile verbosity + (buildPref exeName exe exeFileName) + (dest <.> exeExtension) + stripExe verbosity lbi exeFileName (dest <.> exeExtension) + installBinary (binDir fixedExeBaseName) hunk ./Distribution/Simple/GHC.hs 910 - -> PackageDescription -> IO () -installLib flags lbi targetDir dynlibTargetDir builtDir - pkg@PackageDescription{library=Just lib} = do - -- copy .hi files over: - let verbosity = fromFlag (copyVerbosity flags) - copyHelper installFun src dst n = do - createDirectoryIfMissingVerbose verbosity True dst - installFun verbosity (src n) (dst n) - copy = copyHelper installOrdinaryFile - copyShared = copyHelper installExecutableFile - copyModuleFiles ext = - findModuleFiles [builtDir] [ext] (libModules lib) - >>= installOrdinaryFiles verbosity targetDir - ifVanilla $ copyModuleFiles "hi" - ifProf $ copyModuleFiles "p_hi" - ifShared $ copyModuleFiles "dyn_hi" + -> PackageDescription + -> Library + -> IO () +installLib flags lbi targetDir dynlibTargetDir builtDir pkg lib = do + -- copy .hi files over: + let verbosity = fromFlag (copyVerbosity flags) + copyHelper installFun src dst n = do + createDirectoryIfMissingVerbose verbosity True dst + installFun verbosity (src n) (dst n) + copy = copyHelper installOrdinaryFile + copyShared = copyHelper installExecutableFile + copyModuleFiles ext = + findModuleFiles [builtDir] [ext] (libModules lib) + >>= installOrdinaryFiles verbosity targetDir + ifVanilla $ copyModuleFiles "hi" + ifProf $ copyModuleFiles "p_hi" + ifShared $ copyModuleFiles "dyn_hi" hunk ./Distribution/Simple/GHC.hs 928 - -- copy the built library files over: - ifVanilla $ copy builtDir targetDir vanillaLibName - ifProf $ copy builtDir targetDir profileLibName - ifGHCi $ copy builtDir targetDir ghciLibName - ifShared $ copyShared builtDir dynlibTargetDir sharedLibName + -- copy the built library files over: + ifVanilla $ copy builtDir targetDir vanillaLibName + ifProf $ copy builtDir targetDir profileLibName + ifGHCi $ copy builtDir targetDir ghciLibName + ifShared $ copyShared builtDir dynlibTargetDir sharedLibName hunk ./Distribution/Simple/GHC.hs 934 - -- run ranlib if necessary: - ifVanilla $ updateLibArchive verbosity lbi - (targetDir vanillaLibName) - ifProf $ updateLibArchive verbosity lbi - (targetDir profileLibName) + -- run ranlib if necessary: + ifVanilla $ updateLibArchive verbosity lbi + (targetDir vanillaLibName) + ifProf $ updateLibArchive verbosity lbi + (targetDir profileLibName) hunk ./Distribution/Simple/GHC.hs 955 -installLib _ _ _ _ _ PackageDescription{library=Nothing} - = die $ "Internal Error. installLibGHC called with no library." - hunk ./Distribution/Simple/Install.hs 152 - GHC -> do withLib pkg_descr $ \_ -> + GHC -> do withLib pkg_descr $ hunk ./Distribution/Simple/Install.hs 154 - withExe pkg_descr $ \_ -> + withExe pkg_descr $ hunk ./Distribution/Simple/Install.hs 156 - LHC -> do withLib pkg_descr $ \_ -> + LHC -> do withLib pkg_descr $ hunk ./Distribution/Simple/Install.hs 158 - withExe pkg_descr $ \_ -> + withExe pkg_descr $ hunk ./Distribution/Simple/Install.hs 160 - JHC -> do withLib pkg_descr $ JHC.installLib verbosity libPref buildPref pkg_descr - withExe pkg_descr $ JHC.installExe verbosity binPref buildPref (progPrefixPref, progSuffixPref) pkg_descr + JHC -> do withLib pkg_descr $ + JHC.installLib verbosity libPref buildPref pkg_descr + withExe pkg_descr $ + JHC.installExe verbosity binPref buildPref (progPrefixPref, progSuffixPref) pkg_descr hunk ./Distribution/Simple/Install.hs 170 - UHC -> do withLib pkg_descr $ \ _ -> UHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr + UHC -> do withLib pkg_descr $ UHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr hunk ./Distribution/Simple/LHC.hs 75 - ( PackageDescription(..), BuildInfo(..), Executable(..), withExe + ( PackageDescription(..), BuildInfo(..), Executable(..) hunk ./Distribution/Simple/LHC.hs 703 + -> Executable hunk ./Distribution/Simple/LHC.hs 705 -installExe flags lbi installDirs buildPref (progprefix, progsuffix) pkg_descr - = do let verbosity = fromFlag (copyVerbosity flags) - binDir = bindir installDirs - createDirectoryIfMissingVerbose verbosity True binDir - withExe pkg_descr $ \Executable { exeName = e } -> do - let exeFileName = e <.> exeExtension - fixedExeBaseName = progprefix ++ e ++ progsuffix - installBinary dest = do - installExecutableFile verbosity - (buildPref e exeFileName) - (dest <.> exeExtension) - stripExe verbosity lbi exeFileName (dest <.> exeExtension) - installBinary (binDir fixedExeBaseName) +installExe flags lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do + let verbosity = fromFlag (copyVerbosity flags) + binDir = bindir installDirs + createDirectoryIfMissingVerbose verbosity True binDir + let exeFileName = exeName exe <.> exeExtension + fixedExeBaseName = progprefix ++ exeName exe ++ progsuffix + installBinary dest = do + installExecutableFile verbosity + (buildPref exeName exe exeFileName) + (dest <.> exeExtension) + stripExe verbosity lbi exeFileName (dest <.> exeExtension) + installBinary (binDir fixedExeBaseName) hunk ./Distribution/Simple/LHC.hs 741 - -> PackageDescription -> IO () -installLib flags lbi targetDir dynlibTargetDir builtDir - pkg@PackageDescription{library=Just lib} = do - -- copy .hi files over: - let copy src dst n = do - createDirectoryIfMissingVerbose verbosity True dst - installOrdinaryFile verbosity (src n) (dst n) - copyModuleFiles ext = - findModuleFiles [builtDir] [ext] (libModules lib) - >>= installOrdinaryFiles verbosity targetDir - ifVanilla $ copyModuleFiles "hi" - ifProf $ copyModuleFiles "p_hi" - hcrFiles <- findModuleFiles (builtDir : hsSourceDirs (libBuildInfo lib)) ["hcr"] (libModules lib) - flip mapM_ hcrFiles $ \(srcBase, srcFile) -> runLhc ["install", srcBase srcFile] + -> PackageDescription + -> Library + -> IO () +installLib flags lbi targetDir dynlibTargetDir builtDir pkg lib = do + -- copy .hi files over: + let copy src dst n = do + createDirectoryIfMissingVerbose verbosity True dst + installOrdinaryFile verbosity (src n) (dst n) + copyModuleFiles ext = + findModuleFiles [builtDir] [ext] (libModules lib) + >>= installOrdinaryFiles verbosity targetDir + ifVanilla $ copyModuleFiles "hi" + ifProf $ copyModuleFiles "p_hi" + hcrFiles <- findModuleFiles (builtDir : hsSourceDirs (libBuildInfo lib)) ["hcr"] (libModules lib) + flip mapM_ hcrFiles $ \(srcBase, srcFile) -> runLhc ["install", srcBase srcFile] hunk ./Distribution/Simple/LHC.hs 757 - -- copy the built library files over: - ifVanilla $ copy builtDir targetDir vanillaLibName - ifProf $ copy builtDir targetDir profileLibName - ifGHCi $ copy builtDir targetDir ghciLibName - ifShared $ copy builtDir dynlibTargetDir sharedLibName + -- copy the built library files over: + ifVanilla $ copy builtDir targetDir vanillaLibName + ifProf $ copy builtDir targetDir profileLibName + ifGHCi $ copy builtDir targetDir ghciLibName + ifShared $ copy builtDir dynlibTargetDir sharedLibName hunk ./Distribution/Simple/LHC.hs 763 - -- run ranlib if necessary: - ifVanilla $ updateLibArchive verbosity lbi - (targetDir vanillaLibName) - ifProf $ updateLibArchive verbosity lbi - (targetDir profileLibName) + -- run ranlib if necessary: + ifVanilla $ updateLibArchive verbosity lbi + (targetDir vanillaLibName) + ifProf $ updateLibArchive verbosity lbi + (targetDir profileLibName) hunk ./Distribution/Simple/LHC.hs 787 -installLib _ _ _ _ _ PackageDescription{library=Nothing} - = die $ "Internal Error. installLibGHC called with no library." - hunk ./Distribution/Simple/UHC.hs 225 - -> PackageDescription -> IO () -installLib _flags _lbi _targetDir _dynlibTargetDir _builtDir - PackageDescription{ library = Nothing } = - return () -- TODO: is this ok? -installLib flags _lbi targetDir _dynlibTargetDir builtDir - pkg@PackageDescription{ library = Just _ } = do + -> PackageDescription -> Library -> IO () +installLib flags _lbi targetDir _dynlibTargetDir builtDir pkg _library = do hunk ./Distribution/Simple/Install.hs 77 +import Distribution.Text + ( display ) hunk ./Distribution/Simple/Install.hs 173 - _ -> die ("only installing with GHC, JHC, Hugs or nhc98 is implemented") + _ -> die $ "installing with " + ++ display (compilerFlavor (compiler lbi)) + ++ " is not implemented" hunk ./Cabal.cabal 2 -Version: 1.9.0 +Version: 1.9.1 hunk ./Distribution/Simple/GHC.hs 77 -import Distribution.Simple.Setup - ( CopyFlags(..), fromFlag ) hunk ./Distribution/Simple/GHC.hs 864 -installExe :: CopyFlags -- ^verbosity +installExe :: Verbosity hunk ./Distribution/Simple/GHC.hs 872 -installExe flags lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do - let verbosity = fromFlag (copyVerbosity flags) - binDir = bindir installDirs +installExe verbosity lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do + let binDir = bindir installDirs hunk ./Distribution/Simple/GHC.hs 902 -installLib :: CopyFlags -- ^verbosity +installLib :: Verbosity hunk ./Distribution/Simple/GHC.hs 910 -installLib flags lbi targetDir dynlibTargetDir builtDir pkg lib = do +installLib verbosity lbi targetDir dynlibTargetDir builtDir pkg lib = do hunk ./Distribution/Simple/GHC.hs 912 - let verbosity = fromFlag (copyVerbosity flags) - copyHelper installFun src dst n = do + let copyHelper installFun src dst n = do hunk ./Distribution/Simple/Install.hs 155 - GHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr + GHC.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr hunk ./Distribution/Simple/Install.hs 157 - GHC.installExe flags lbi installDirs buildPref (progPrefixPref, progSuffixPref) pkg_descr + GHC.installExe verbosity lbi installDirs buildPref (progPrefixPref, progSuffixPref) pkg_descr hunk ./Distribution/Simple/Install.hs 159 - LHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr + LHC.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr hunk ./Distribution/Simple/Install.hs 161 - LHC.installExe flags lbi installDirs buildPref (progPrefixPref, progSuffixPref) pkg_descr + LHC.installExe verbosity lbi installDirs buildPref (progPrefixPref, progSuffixPref) pkg_descr hunk ./Distribution/Simple/Install.hs 172 - UHC -> do withLib pkg_descr $ UHC.installLib flags lbi libPref dynlibPref buildPref pkg_descr + UHC -> do withLib pkg_descr $ UHC.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr hunk ./Distribution/Simple/LHC.hs 72 -import Distribution.Simple.Setup - ( CopyFlags(..), fromFlag ) hunk ./Distribution/Simple/LHC.hs 695 -installExe :: CopyFlags -- ^verbosity +installExe :: Verbosity hunk ./Distribution/Simple/LHC.hs 703 -installExe flags lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do - let verbosity = fromFlag (copyVerbosity flags) - binDir = bindir installDirs +installExe verbosity lbi installDirs buildPref (progprefix, progsuffix) _pkg exe = do + let binDir = bindir installDirs hunk ./Distribution/Simple/LHC.hs 733 -installLib :: CopyFlags -- ^verbosity +installLib :: Verbosity hunk ./Distribution/Simple/LHC.hs 741 -installLib flags lbi targetDir dynlibTargetDir builtDir pkg lib = do +installLib verbosity lbi targetDir dynlibTargetDir builtDir pkg lib = do hunk ./Distribution/Simple/LHC.hs 781 - verbosity = fromFlag (copyVerbosity flags) hunk ./Distribution/Simple/UHC.hs 65 -import Distribution.Simple.Setup hunk ./Distribution/Simple/UHC.hs 222 -installLib :: CopyFlags -> LocalBuildInfo +installLib :: Verbosity -> LocalBuildInfo hunk ./Distribution/Simple/UHC.hs 225 -installLib flags _lbi targetDir _dynlibTargetDir builtDir pkg _library = do +installLib verbosity _lbi targetDir _dynlibTargetDir builtDir pkg _library = do hunk ./Distribution/Simple/UHC.hs 228 - let verbosity = fromFlag (copyVerbosity flags) hunk ./Distribution/Simple/Configure.hs 103 +import Distribution.Simple.BuildPaths + ( autogenModulesDir ) hunk ./Distribution/Simple/Configure.hs 831 + ++ [ "-I" ++ autogenModulesDir lbi ] hunk ./Distribution/Simple/GHC.hs 848 - = ["-I" ++ dir | dir <- PD.includeDirs bi] + = ["-I" ++ dir | dir <- odir : PD.includeDirs bi] hunk ./Distribution/Simple/Program/Builtin.hs 153 +uhcProgram :: Program hunk ./Distribution/Simple/GHC.hs 824 - ierror = error "internal error: unexpected package db stack" + ierror = error ("internal error: unexpected package db stack: " ++ show dbstack) hunk ./Distribution/Simple/LHC.hs 660 - ierror = error "internal error: unexpected package db stack" + ierror = error ("internal error: unexpected package db stack: " ++ show dbstack) hunk ./Distribution/Simple/Program/HcPkg.hs 242 - ierror = error "internal error: unexpected package db stack" + ierror = error ("internal error: unexpected package db stack: " ++ show dbstack) hunk ./Distribution/Simple/Register.hs 115 -import Data.List (partition) +import Data.List + ( partition, nub ) hunk ./Distribution/Simple/Register.hs 147 - packageDbs = withPackageDB lbi - ++ maybeToList (flagToMaybe (regPackageDB regFlags)) + -- FIXME: there's really no guarantee this will work. + -- registering into a totally different db stack can + -- fail if dependencies cannot be satisfied. + packageDbs = nub $ withPackageDB lbi + ++ maybeToList (flagToMaybe (regPackageDB regFlags)) hunk ./Distribution/Simple/LHC.hs 240 - return $! hackRtsPackage (mconcat indexes) + return $! (mconcat indexes) hunk ./Distribution/Simple/LHC.hs 250 - hackRtsPackage index = - case PackageIndex.lookupPackageName index (PackageName "rts") of - [(_,[rts])] - -> PackageIndex.insert (removeMingwIncludeDir rts) index - _ -> error "No (or multiple) rts package is registered!!" - hunk ./Distribution/Simple/Program/HcPkg.hs 181 - args = [cmdname, pkgFile] ++ packageDbStackOpts packagedbs + args = [cmdname, pkgFile] + ++ (if legacyVersion hcPkg + then [packageDbOpts (last packagedbs)] + else packageDbStackOpts packagedbs) hunk ./Distribution/Simple/Program/HcPkg.hs 193 - args = [cmdname, "-"] ++ packageDbStackOpts packagedbs + args = [cmdname, "-"] + ++ (if legacyVersion hcPkg + then [packageDbOpts (last packagedbs)] + else packageDbStackOpts packagedbs) hunk ./Distribution/Simple/Program/HcPkg.hs 266 + +-- Handle quirks in ghc-pkg 6.8 and older +legacyVersion :: ConfiguredProgram -> Bool +legacyVersion hcPkg = programId hcPkg == "ghc-pkg" + && programVersion hcPkg < Just (Version [6,9] []) hunk ./Distribution/Simple/Program/Ar.hs 46 - let simpleArgs = ["-r"] + let simpleArgs = case buildOS of + OSX -> ["-r", "-s"] + _ -> ["-r"] addfile ./tests/README hunk ./tests/README 1 +Building and running the test suite +=================================== + +You can build and run the test suite by running: + + cabal configure && cabal build + cd tests + cabal configure --package-db=../dist/package.conf.inplace \ + --constraint='Cabal == 1.9.1' + cabal build + ./dist/build/suite/suite + +Replace the Cabal constraint with whatever the current development +version of Cabal. hunk ./Distribution/Simple/LHC.hs 89 - ( PackageIdentifier, Package(..), PackageName(..) ) + ( PackageIdentifier, Package(..) ) hunk ./Distribution/Simple/LHC.hs 257 --- GHC < 6.10 put "$topdir/include/mingw" in rts's installDirs. This --- breaks when you want to use a different gcc, so we need to filter --- it out. -removeMingwIncludeDir :: InstalledPackageInfo -> InstalledPackageInfo -removeMingwIncludeDir pkg = - let ids = InstalledPackageInfo.includeDirs pkg - ids' = filter (not . ("mingw" `isSuffixOf`)) ids - in pkg { InstalledPackageInfo.includeDirs = ids' } - hunk ./tests/suite.cabal 19 - test-framework-quickcheck2 == 0.2.2, + test-framework-quickcheck2, hunk ./Cabal.cabal 2 -Version: 1.9.1 +Version: 1.9.2 hunk ./Cabal.cabal 57 - cpp-options: "-DCABAL_VERSION=1,9,0" + cpp-options: "-DCABAL_VERSION=1,9,2" hunk ./Makefile 2 -VERSION=1.9.0 +VERSION=1.9.2 hunk ./Distribution/PackageDescription/Check.hs 90 - , asVersionIntervals, LowerBound(..), UpperBound(..) ) + , asVersionIntervals, LowerBound(..), UpperBound(..), isNoVersion ) hunk ./Distribution/PackageDescription/Check.hs 318 + + -- check use of impossible constraints "tested-with: GHC== 6.10 && ==6.12" + , check (not (null testedWithImpossibleRanges)) $ + PackageDistInexcusable $ + "Invalid 'tested-with' version range: " + ++ commaSep (map display testedWithImpossibleRanges) + ++ ". To indicate that you have tested a package with multiple " + ++ "different versions of the same compiler use multiple entries, " + ++ "for example 'tested-with: GHC==6.10.4, GHC==6.12.3' and not " + ++ "'tested-with: GHC==6.10.4 && ==6.12.3'." hunk ./Distribution/PackageDescription/Check.hs 338 + testedWithImpossibleRanges = + [ Dependency (PackageName (display compiler)) vr + | (compiler, vr) <- testedWith pkg + , isNoVersion vr ] + + hunk ./Distribution/PackageDescription/Check.hs 714 + -- check use of "tested-with: GHC (>= 1.0 && < 1.4) || >=1.8 " syntax + , checkVersion [1,8] (not (null testedWithVersionRangeExpressions)) $ + PackageDistInexcusable $ + "The package uses full version-range expressions " + ++ "in a 'tested-with' field: " + ++ commaSep (map display testedWithVersionRangeExpressions) + ++ ". To use this new syntax the package needs to specify at least " + ++ "'cabal-version: >= 1.8'." + + -- check use of "tested-with: GHC == 6.12.*" syntax + , checkVersion [1,6] (not (null testedWithUsingWildcardSyntax)) $ + PackageDistInexcusable $ + "The package uses wildcard syntax in the 'tested-with' field: " + ++ commaSep (map display testedWithUsingWildcardSyntax) + ++ ". To use this new syntax the package need to specify at least " + ++ "'cabal-version: >= 1.6'. Alternatively, if broader compatability " + ++ "is important then use: " ++ commaSep + [ display (Dependency name (eliminateWildcardSyntax versionRange)) + | Dependency name versionRange <- testedWithUsingWildcardSyntax ] + hunk ./Distribution/PackageDescription/Check.hs 809 - , depth vr > (2::Int) ] - where depth = foldVersionRange' + , versionExpDepth vr > 2 ] + + testedWithVersionRangeExpressions = + [ Dependency (PackageName (display compiler)) vr + | (compiler, vr) <- testedWith pkg + , versionExpDepth vr > 2 ] + + versionExpDepth :: VersionRange -> Int + versionExpDepth = foldVersionRange' hunk ./Distribution/PackageDescription/Check.hs 827 + testedWithUsingWildcardSyntax = [ Dependency (PackageName (display compiler)) vr + | (compiler, vr) <- testedWith pkg + , usesWildcardSyntax vr ] + hunk ./Distribution/Simple/LHC.hs 341 + lhcWrap x = ("--build-library --ghc-opts=\"":x) ++ ["\""] hunk ./Distribution/Simple/LHC.hs 355 - do ifVanillaLib forceVanillaLib (runGhcProg ghcArgs) - ifProfLib (runGhcProg ghcArgsProf) - ifSharedLib (runGhcProg ghcArgsShared) + do ifVanillaLib forceVanillaLib (runGhcProg $ lhcWrap ghcArgs) + ifProfLib (runGhcProg $ lhcWrap ghcArgsProf) + ifSharedLib (runGhcProg $ lhcWrap ghcArgsShared) hunk ./Distribution/Simple/LHC.hs 516 + let lhcWrap x = ("--ghc-opts\"":x) ++ ["\""] hunk ./Distribution/Simple/LHC.hs 541 - (runGhcProg (binArgs False False)) + (runGhcProg $ lhcWrap (binArgs False False)) hunk ./Distribution/Simple/LHC.hs 739 - flip mapM_ hcrFiles $ \(srcBase, srcFile) -> runLhc ["install", srcBase srcFile] + flip mapM_ hcrFiles $ \(srcBase, srcFile) -> runLhc ["--install-library", srcBase srcFile] hunk ./Distribution/Simple/LHC.hs 341 - lhcWrap x = ("--build-library --ghc-opts=\"":x) ++ ["\""] + lhcWrap x = ["--build-library", "--ghc-opts=" ++ unwords x] hunk ./Distribution/PackageDescription/Check.hs 94 + hunk ./Distribution/PackageDescription/Check.hs 96 - ( display ) + ( display, disp ) +import qualified Text.PrettyPrint as Disp +import Text.PrettyPrint ((<>), (<+>)) + hunk ./Distribution/PackageDescription/Check.hs 701 - ++ commaSep (map display versionRangeExpressions) + ++ commaSep (map displayRawDependency versionRangeExpressions) hunk ./Distribution/PackageDescription/Check.hs 723 - ++ commaSep (map display testedWithVersionRangeExpressions) + ++ commaSep (map displayRawDependency testedWithVersionRangeExpressions) hunk ./Distribution/PackageDescription/Check.hs 813 - , versionExpDepth vr > 2 ] + , usesNewVersionRangeSyntax vr ] hunk ./Distribution/PackageDescription/Check.hs 818 - , versionExpDepth vr > 2 ] + , usesNewVersionRangeSyntax vr ] hunk ./Distribution/PackageDescription/Check.hs 820 - versionExpDepth :: VersionRange -> Int - versionExpDepth = foldVersionRange' - 1 (const 1) - (const 1) (const 1) - (const 1) (const 1) - (const (const 1)) - (+) (+) + usesNewVersionRangeSyntax :: VersionRange -> Bool + usesNewVersionRangeSyntax = + (> 2) -- uses the new syntax if depth is more than 2 + . foldVersionRange' + (1 :: Int) + (const 1) + (const 1) (const 1) + (const 1) (const 1) + (const (const 1)) + (+) (+) + (const 3) -- uses new ()'s syntax hunk ./Distribution/PackageDescription/Check.hs 846 - (||) (||) + (||) (||) id hunk ./Distribution/PackageDescription/Check.hs 854 - intersectVersionRanges unionVersionRanges + intersectVersionRanges unionVersionRanges id hunk ./Distribution/PackageDescription/Check.hs 893 +-- | A variation on the normal 'Text' instance, shows any ()'s in the original +-- textual syntax. We need to show these otherwise it's confusing to users when +-- we complain of their presense but do not pretty print them! +-- +displayRawVersionRange :: VersionRange -> String +displayRawVersionRange = + Disp.render + . fst + . foldVersionRange' -- precedence: + -- All the same as the usual pretty printer, except for the parens + ( Disp.text "-any" , 0 :: Int) + (\v -> (Disp.text "==" <> disp v , 0)) + (\v -> (Disp.char '>' <> disp v , 0)) + (\v -> (Disp.char '<' <> disp v , 0)) + (\v -> (Disp.text ">=" <> disp v , 0)) + (\v -> (Disp.text "<=" <> disp v , 0)) + (\v _ -> (Disp.text "==" <> dispWild v , 0)) + (\(r1, p1) (r2, p2) -> (punct 2 p1 r1 <+> Disp.text "||" <+> punct 2 p2 r2 , 2)) + (\(r1, p1) (r2, p2) -> (punct 1 p1 r1 <+> Disp.text "&&" <+> punct 1 p2 r2 , 1)) + (\(r, _ ) -> (Disp.parens r, 0)) -- parens + + where + dispWild (Version b _) = + Disp.hcat (Disp.punctuate (Disp.char '.') (map Disp.int b)) + <> Disp.text ".*" + punct p p' | p < p' = Disp.parens + | otherwise = id + +displayRawDependency :: Dependency -> String +displayRawDependency (Dependency pkg vr) = + display pkg ++ " " ++ displayRawVersionRange vr + + hunk ./Distribution/Version.hs 116 - | UnionVersionRanges VersionRange VersionRange - | IntersectVersionRanges VersionRange VersionRange + | UnionVersionRanges VersionRange VersionRange + | IntersectVersionRanges VersionRange VersionRange + | VersionRangeParens VersionRange -- just '(exp)' parentheses syntax hunk ./Distribution/Version.hs 257 - + fold (VersionRangeParens v) = fold v + hunk ./Distribution/Version.hs 280 + -> (a -> a) -- ^ @\"(_)"\@ parentheses hunk ./Distribution/Version.hs 283 - wildcard union intersect = fold + wildcard union intersect parens = fold hunk ./Distribution/Version.hs 302 + fold (VersionRangeParens v) = parens (fold v) hunk ./Distribution/Version.hs 683 + id hunk ./Distribution/Version.hs 728 - return a) + return (VersionRangeParens a)) hunk ./tests/Test/Distribution/Version.hs 7 +import qualified Text.PrettyPrint as Disp +import Text.PrettyPrint ((<>), (<+>)) + hunk ./tests/Test/Distribution/Version.hs 77 - , property prop_parse_disp + , property prop_parse_disp1 + , property prop_parse_disp2 + , property prop_parse_disp3 hunk ./tests/Test/Distribution/Version.hs 111 + , (2, liftM VersionRangeParens arbitrary) hunk ./tests/Test/Distribution/Version.hs 203 + expandWildcard (VersionRangeParens v) = expandWildcard v hunk ./tests/Test/Distribution/Version.hs 214 - unionVersionRanges intersectVersionRanges + unionVersionRanges intersectVersionRanges id hunk ./tests/Test/Distribution/Version.hs 229 + canonicalise (VersionRangeParens v) = canonicalise v hunk ./tests/Test/Distribution/Version.hs 291 +--FIXME: see equivalentVersionRange for details hunk ./tests/Test/Distribution/Version.hs 344 - + hunk ./tests/Test/Distribution/Version.hs 522 +--FIXME: this is wrong. consider version ranges "<=1" and "<1.0" +-- this algorithm cannot distinguish them because there is no version +-- that is included by one that is excluded by the other. +-- Alternatively we must reconsider the semantics of '<' and '<=' +-- in version ranges / version intervals. Perhaps the canonical +-- representation should use just < v and interpret "<= v" as "< v.0". hunk ./tests/Test/Distribution/Version.hs 574 -prop_parse_disp :: VersionRange -> Bool -prop_parse_disp vr = - simpleParse (display vr) == Just (canonicalise vr) +prop_parse_disp1 :: VersionRange -> Bool +prop_parse_disp1 vr = + fmap stripParens (simpleParse (display vr)) == Just (canonicalise vr) hunk ./tests/Test/Distribution/Version.hs 592 + swizzle (VersionRangeParens v) = swizzle v hunk ./tests/Test/Distribution/Version.hs 606 - unionVersionRanges intersectVersionRanges + unionVersionRanges intersectVersionRanges id + + stripParens :: VersionRange -> VersionRange + stripParens (VersionRangeParens v) = stripParens v + stripParens (UnionVersionRanges v1 v2) = + UnionVersionRanges (stripParens v1) (stripParens v2) + stripParens (IntersectVersionRanges v1 v2) = + IntersectVersionRanges (stripParens v1) (stripParens v2) + stripParens v = v + +prop_parse_disp2 :: VersionRange -> Bool +prop_parse_disp2 vr = + fmap (display :: VersionRange -> String) (simpleParse (display vr)) + == Just (display vr) + +prop_parse_disp3 :: VersionRange -> Bool +prop_parse_disp3 vr = + fmap displayRaw (simpleParse (display vr)) == Just (display vr) + +displayRaw :: VersionRange -> String +displayRaw = + Disp.render + . foldVersionRange' -- precedence: + -- All the same as the usual pretty printer, except for the parens + ( Disp.text "-any") + (\v -> Disp.text "==" <> disp v) + (\v -> Disp.char '>' <> disp v) + (\v -> Disp.char '<' <> disp v) + (\v -> Disp.text ">=" <> disp v) + (\v -> Disp.text "<=" <> disp v) + (\v _ -> Disp.text "==" <> dispWild v) + (\r1 r2 -> r1 <+> Disp.text "||" <+> r2) + (\r1 r2 -> r1 <+> Disp.text "&&" <+> r2) + (\r -> Disp.parens r) -- parens + + where + dispWild (Version b _) = + Disp.hcat (Disp.punctuate (Disp.char '.') (map Disp.int b)) + <> Disp.text ".*" hunk ./Distribution/PackageDescription.hs 10 --- several parts to this structure. It has top level info and then 'Library' --- and 'Executable' sections each of which have associated 'BuildInfo' data --- that's used to build the library or exe. To further complicate things there --- is both a 'PackageDescription' and a 'GenericPackageDescription'. This --- distinction relates to cabal configurations. When we initially read a --- @.cabal@ file we get a 'GenericPackageDescription' which has all the --- conditional sections. Before actually building a package we have to decide +-- several parts to this structure. It has top level info and then 'Library', +-- 'Executable', and 'Testsuite' sections each of which have associated +-- 'BuildInfo' data that's used to build the library, exe, or test. To further +-- complicate things there is both a 'PackageDescription' and a +-- 'GenericPackageDescription'. This distinction relates to cabal +-- configurations. When we initially read a @.cabal@ file we get a +-- 'GenericPackageDescription' which has all the conditional sections. +-- Before actually building a package we have to decide hunk ./Distribution/PackageDescription.hs 74 + -- * Tests + Testsuite(..), + TestType(..), + emptyTestsuite, + matchesType, + hasTests, + withTest, + testModules, + hunk ./Distribution/PackageDescription.hs 112 -import Distribution.ModuleName (ModuleName) -import Distribution.Version (Version(Version), VersionRange, anyVersion) +import Distribution.ModuleName (ModuleName, fromString) +import Distribution.Version + ( Version(Version), VersionRange, anyVersion, noVersion + , intersectVersionRanges, isNoVersion) hunk ./Distribution/PackageDescription.hs 159 + testsuites :: [Testsuite], hunk ./Distribution/PackageDescription.hs 195 + testsuites = [], hunk ./Distribution/PackageDescription.hs 327 +-- --------------------------------------------------------------------------- +-- The Testsuite type + +data Testsuite = Testsuite { + testName :: String, + testIs :: String, + testType :: TestType, + testBuildInfo :: BuildInfo + } + deriving (Show, Read, Eq) + +data TestType = ExeTest VersionRange | LibTest VersionRange + deriving (Show, Read, Eq) + +instance Text TestType where + disp (ExeTest v) = text "executable" <+> disp v + disp (LibTest v) = text "library" <+> disp v + + parse = do t <- ident + Parse.skipSpaces + v <- parse Parse.<++ return noVersion + if t == "executable" then return (ExeTest v) else + if t == "library" then return (LibTest v) else + Parse.pfail + +instance Monoid Testsuite where + mempty = Testsuite { + testName = mempty, + testIs = mempty, + testType = ExeTest noVersion, + testBuildInfo = mempty + } + + mappend a b = Testsuite { + testName = combine testName, + testIs = combine testIs, + testType = if testType b == ExeTest noVersion + then testType a else testType b, + testBuildInfo = testBuildInfo a `mappend` testBuildInfo b + } + where combine f = case (f a, f b) of + ("", x) -> x + (x, "") -> x + (x, y) -> error "Ambiguous values for test field: '" + ++ x ++ "' and '" ++ y ++ "'" + +emptyTestsuite :: Testsuite +emptyTestsuite = mempty + +-- | Do these test types match? Two test types match if they use the same +-- constructor and have overlapping version ranges. 'matchesType' is used to +-- determine if an action supports a particular test. +matchesType :: TestType -> TestType -> Bool +matchesType (ExeTest v1) (ExeTest v2) = + not $ isNoVersion $ intersectVersionRanges v1 v2 +matchesType (ExeTest _) _ = False +matchesType (LibTest v1) (LibTest v2) = + not $ isNoVersion $ intersectVersionRanges v1 v2 +matchesType (LibTest _) _ = False + +-- | Does this package have any testsuites? +hasTests :: PackageDescription -> Bool +hasTests = any (buildable . testBuildInfo) . testsuites + +-- | Perform actions on each buildable 'Testsuite' in a package. For each +-- 'Testsuite', all actions with matching 'TestType' are performed. If no +-- action has a matching type, then an error message is produced. +withTest :: PackageDescription -> [(TestType, Testsuite -> IO ())] -> IO () +withTest pkg_descr fs = flip mapM_ (testsuites pkg_descr) $ \test -> do + let handlers = map snd $ filter (matchesType (testType test) . fst) fs + if not $ buildable (testBuildInfo test) + then return () + else if null handlers + then error $ "error in test " ++ testName test ++ + ": no support for test type " ++ show (disp $ testType test) + else mapM_ (\f -> f test) handlers + +-- | Get all the module names from a testsuite. +testModules :: Testsuite -> [ModuleName] +testModules test = otherModules (testBuildInfo test) ++ libraryModule + where libraryModule = case testType test of + ExeTest _ -> [] + LibTest _ -> [fromString $ testIs test] + hunk ./Distribution/PackageDescription.hs 686 - condExecutables :: [(String, CondTree ConfVar [Dependency] Executable)] + condExecutables :: [(String, CondTree ConfVar [Dependency] Executable)], + condTestsuites :: [(String, CondTree ConfVar [Dependency] Testsuite)] hunk ./Distribution/PackageDescription/Configuration.hs 66 - , CondTree(..), ConfVar(..), Condition(..) ) + , CondTree(..), ConfVar(..), Condition(..), Testsuite(..) ) hunk ./Distribution/PackageDescription/Configuration.hs 417 -flattenTaggedTargets :: TargetSet PDTagged -> (Maybe Library, [(String, Executable)]) -flattenTaggedTargets (TargetSet targets) = foldr untag (Nothing, []) targets +flattenTaggedTargets :: TargetSet PDTagged -> + (Maybe Library, [(String, Executable)], [(String, Testsuite)]) +flattenTaggedTargets (TargetSet targets) = foldr untag (Nothing, [], []) targets hunk ./Distribution/PackageDescription/Configuration.hs 421 - untag (_, Lib _) (Just _, _) = bug "Only one library expected" - untag (deps, Lib l) (Nothing, exes) = (Just l', exes) + untag (_, Lib _) (Just _, _, _) = bug "Only one library expected" + untag (deps, Lib l) (Nothing, exes, tests) = (Just l', exes, tests) hunk ./Distribution/PackageDescription/Configuration.hs 427 - untag (deps, Exe n e) (mlib, exes) + untag (deps, Exe n e) (mlib, exes, tests) hunk ./Distribution/PackageDescription/Configuration.hs 429 - | otherwise = (mlib, exes ++ [(n, e')]) + | otherwise = (mlib, exes ++ [(n, e')], tests) hunk ./Distribution/PackageDescription/Configuration.hs 434 + untag (deps, Test n t) (mlib, exes, tests) + | any ((== n) . fst) tests = bug "Testsuite with same name found" + | otherwise = (mlib, exes, tests ++ [(n, t')]) + where + t' = t { + testBuildInfo = (testBuildInfo t) + { targetBuildDepends = fromDepMap deps } + } hunk ./Distribution/PackageDescription/Configuration.hs 449 -data PDTagged = Lib Library | Exe String Executable | PDNull deriving Show +data PDTagged = Lib Library | Exe String Executable | Test String Testsuite | PDNull deriving Show hunk ./Distribution/PackageDescription/Configuration.hs 457 + Test n t `mappend` Test n' t' | n == n' = Test n (t `mappend` t') hunk ./Distribution/PackageDescription/Configuration.hs 494 - (GenericPackageDescription pkg flags mlib0 exes0) = + (GenericPackageDescription pkg flags mlib0 exes0 tests0) = hunk ./Distribution/PackageDescription/Configuration.hs 496 - Right ((mlib, exes'), targetSet, flagVals) -> + Right ((mlib, exes', tests'), targetSet, flagVals) -> hunk ./Distribution/PackageDescription/Configuration.hs 499 + , testsuites = tests' hunk ./Distribution/PackageDescription/Configuration.hs 510 - -- Combine lib and exes into one list of @CondTree@s with tagged data + -- Combine lib, exes, and tests into one list of @CondTree@s with tagged data hunk ./Distribution/PackageDescription/Configuration.hs 513 + ++ map (\(name,tree) -> mapTreeData (Test name) tree) tests0 hunk ./Distribution/PackageDescription/Configuration.hs 518 - let (mlib, exes) = flattenTaggedTargets targetSet in + let (mlib, exes, tests) = flattenTaggedTargets targetSet in hunk ./Distribution/PackageDescription/Configuration.hs 520 - map (\(n,e) -> (exeFillInDefaults e) { exeName = n }) exes), + map (\(n,e) -> (exeFillInDefaults e) { exeName = n }) exes, + map (\(n,t) -> (testFillInDefaults t) { testName = n }) tests), hunk ./Distribution/PackageDescription/Configuration.hs 560 -flattenPackageDescription (GenericPackageDescription pkg _ mlib0 exes0) = +flattenPackageDescription (GenericPackageDescription pkg _ mlib0 exes0 tests0) = hunk ./Distribution/PackageDescription/Configuration.hs 563 - , buildDepends = ldeps ++ reverse edeps + , testsuites = reverse tests + , buildDepends = ldeps ++ reverse edeps ++ reverse tdeps hunk ./Distribution/PackageDescription/Configuration.hs 572 + (tests, tdeps) = foldr flattenTst ([],[]) tests0 hunk ./Distribution/PackageDescription/Configuration.hs 576 + flattenTst (n, t) (es, ds) = + let (e, ds') = ignoreConditions t in + ( (testFillInDefaults $ e { testName = n }) : es, ds' ++ ds ) hunk ./Distribution/PackageDescription/Configuration.hs 595 +testFillInDefaults :: Testsuite -> Testsuite +testFillInDefaults tst@(Testsuite { testBuildInfo = bi }) = + tst { testBuildInfo = biFillInDefaults bi } + hunk ./Distribution/PackageDescription/Parse.hs 209 +-- --------------------------------------------------------------------------- +-- The Testsuite type + + +testsuiteFieldDescrs :: [FieldDescr Testsuite] +testsuiteFieldDescrs = + [ simpleField "test" + showToken parseTokenQ + testName (\xs test -> test {testName=xs}) + , simpleField "type" + disp parse + testType (\xs test -> test {testType=xs}) + , simpleField "test-is" + showToken parseTokenQ + testIs (\xs test -> test {testIs=xs}) + ] + ++ map biToTest binfoFieldDescrs + where biToTest = liftField testBuildInfo (\bi test -> test {testBuildInfo=bi}) + +storeXFieldsTest :: UnrecFieldParser Testsuite +storeXFieldsTest (f@('x':'-':_), val) t@(Testsuite { testBuildInfo = bi }) = + Just $ t {testBuildInfo = bi{ customFieldsBI = (f,val):(customFieldsBI bi)}} +storeXFieldsTest _ _ = Nothing + hunk ./Distribution/PackageDescription/Parse.hs 534 - (repos, flags, mlib, exes) <- getBody + (repos, flags, mlib, exes, tests) <- getBody hunk ./Distribution/PackageDescription/Parse.hs 538 - checkForUndefinedFlags flags mlib exes + checkForUndefinedFlags flags mlib exes tests hunk ./Distribution/PackageDescription/Parse.hs 541 - flags mlib exes + flags mlib exes tests hunk ./Distribution/PackageDescription/Parse.hs 625 - -- body ::= { repo | flag | library | executable }+ -- at most one lib + -- body ::= { repo | flag | library | executable | test }+ -- at most one lib hunk ./Distribution/PackageDescription/Parse.hs 631 - ,[(String, CondTree ConfVar [Dependency] Executable)]) + ,[(String, CondTree ConfVar [Dependency] Executable)] + ,[(String, CondTree ConfVar [Dependency] Testsuite)]) hunk ./Distribution/PackageDescription/Parse.hs 641 - (repos, flags, lib, exes) <- getBody - return (repos, flags, lib, exes ++ [(exename, flds)]) + (repos, flags, lib, exes, tests) <- getBody + return (repos, flags, lib, exes ++ [(exename, flds)], tests) + + | sec_type == "test" -> do + when (null sec_label) $ lift $ syntaxError line_no + "'test' needs one argument (the testsuite's name)" + testname <- lift $ runP line_no "test" parseTokenQ sec_label + flds <- collectFields parseTestFields sec_fields + skipField + (repos, flags, lib, exes, tests) <- getBody + return (repos, flags, lib, exes, tests ++ [(testname, flds)]) hunk ./Distribution/PackageDescription/Parse.hs 658 - (repos, flags, lib, exes) <- getBody + (repos, flags, lib, exes, tests) <- getBody hunk ./Distribution/PackageDescription/Parse.hs 661 - return (repos, flags, Just flds, exes) + return (repos, flags, Just flds, exes, tests) hunk ./Distribution/PackageDescription/Parse.hs 672 - (repos, flags, lib, exes) <- getBody - return (repos, flag:flags, lib, exes) + (repos, flags, lib, exes, tests) <- getBody + return (repos, flag:flags, lib, exes, tests) hunk ./Distribution/PackageDescription/Parse.hs 697 - (repos, flags, lib, exes) <- getBody - return (repo:repos, flags, lib, exes) + (repos, flags, lib, exes, tests) <- getBody + return (repo:repos, flags, lib, exes, tests) hunk ./Distribution/PackageDescription/Parse.hs 709 - Nothing -> return ([], [], Nothing, []) + Nothing -> return ([], [], Nothing, [], []) hunk ./Distribution/PackageDescription/Parse.hs 750 + parseTestFields :: [Field] -> PM Testsuite + parseTestFields = lift . parseFields testsuiteFieldDescrs storeXFieldsTest emptyTestsuite + hunk ./Distribution/PackageDescription/Parse.hs 757 + [(String, CondTree ConfVar [Dependency] Testsuite)] -> hunk ./Distribution/PackageDescription/Parse.hs 759 - checkForUndefinedFlags flags mlib exes = do + checkForUndefinedFlags flags mlib exes tests = do hunk ./Distribution/PackageDescription/Parse.hs 763 + mapM_ (checkCondTreeFlags definedFlags . snd) tests hunk ./Distribution/Simple/Build.hs 71 - , Library(..), Executable(..) ) + , Library(..), Executable(..), Testsuite(..), TestType(..) ) hunk ./Distribution/Simple/Build.hs 82 - , inplacePackageId ) + , inplacePackageId, withTestLBI ) hunk ./Distribution/Simple/Build.hs 91 +import Distribution.Version (Version(..), thisVersion) + hunk ./Distribution/Simple/Build.hs 147 + let testExeVer1 test clbi = do + info verbosity $ "Building testsuite " ++ testName test ++ "..." + buildExeTest verbosity pkg_descr lbi' test clbi + withTestLBI pkg_descr lbi' [(ExeTest $ thisVersion $ Version [1] [], testExeVer1)] + + hunk ./Distribution/Simple/Build.hs 185 +buildExeTest :: Verbosity -> PackageDescription -> LocalBuildInfo + -> Testsuite -> ComponentLocalBuildInfo + -> IO () +buildExeTest verbosity pkg_descr lbi test clbi = + buildExe verbosity pkg_descr lbi exe clbi + where exe = Executable { exeName = testName test + , modulePath = testIs test + , buildInfo = testBuildInfo test + } + hunk ./Distribution/Simple/Configure.hs 84 - , FlagName(..) ) + , FlagName(..), Testsuite(..) ) hunk ./Distribution/Simple/Configure.hs 442 + configTest test = (testName test, + configComponent(testBuildInfo test)) hunk ./Distribution/Simple/Configure.hs 469 + testsuiteConfigs = configTest `fmap` testsuites pkg_descr', hunk ./Distribution/Simple/LocalBuildInfo.hs 53 + withTestLBI, hunk ./Distribution/Simple/LocalBuildInfo.hs 69 - , Executable(exeName) ) + , Executable(exeName), withTest, Testsuite(..), TestType(..) ) hunk ./Distribution/Simple/LocalBuildInfo.hs 99 + testsuiteConfigs :: [(String, ComponentLocalBuildInfo)], hunk ./Distribution/Simple/LocalBuildInfo.hs 167 +withTestLBI :: PackageDescription -> LocalBuildInfo + -> [(TestType, Testsuite -> ComponentLocalBuildInfo -> IO ())] -> IO () +withTestLBI pkg_descr lbi fs = + let wrapper f test = case lookup (testName test) (testsuiteConfigs lbi) of + Just clbi -> f test clbi + Nothing -> die $ "internal error: the package contains a testsuite " + ++ testName test ++ " but there is no corresponding " + ++ "configuration data" + in withTest pkg_descr $ map (\(t, f) -> (t, wrapper f)) fs hunk ./Distribution/Simple/PreProcess.hs 65 - , Library(..), withLib, libModules ) + , Library(..), withLib, libModules, Testsuite(..), TestType(..), withTest ) hunk ./Distribution/Simple/PreProcess.hs 86 - ( Version(..), anyVersion, orLaterVersion ) + ( Version(..), anyVersion, orLaterVersion, thisVersion ) hunk ./Distribution/Simple/PreProcess.hs 201 + unless (null (testsuites pkg_descr)) $ + setupMessage verbosity "Preprocessing testsuites for" (packageId pkg_descr) + let testExeVer1 theTest = do + let bi = testBuildInfo theTest + biHandlers = localHandlers bi + testDir = buildDir lbi testName theTest testName theTest ++ "-tmp" + sequence_ [ preprocessFile (hsSourceDirs bi ++ [autogenModulesDir lbi]) + testDir forSDist (ModuleName.toFilePath modu) + verbosity builtinSuffixes biHandlers + | modu <- otherModules bi] + preprocessFile (hsSourceDirs bi) testDir forSDist + (dropExtensions (testIs theTest)) + verbosity builtinSuffixes biHandlers + withTest pkg_descr [(ExeTest $ thisVersion $ Version [1] [], testExeVer1)] adddir ./tests/PackageTests/TestStanza addfile ./tests/PackageTests/TestStanza/Check.hs hunk ./tests/PackageTests/TestStanza/Check.hs 1 +module PackageTests.TestStanza.Check where hunk ./tests/PackageTests/TestStanza/Check.hs 3 +import Test.HUnit +import System.FilePath +import PackageTests.PackageTester +import Data.List (isInfixOf, intercalate) +import Distribution.Version +import Distribution.PackageDescription.Parse + ( readPackageDescription ) +import Distribution.PackageDescription.Configuration + ( finalizePackageDescription ) +import Distribution.Package + ( PackageIdentifier(..), PackageName(..), Dependency(..) ) +import Distribution.PackageDescription + ( PackageDescription(..), BuildInfo(..), Testsuite(..), Library(..) + , TestType(..), emptyPackageDescription, emptyBuildInfo, emptyLibrary + , emptyTestsuite, BuildType(..) ) +import Distribution.Verbosity (silent) +import Distribution.License (License(..)) +import Distribution.ModuleName (fromString) +import Distribution.System (buildPlatform) +import Distribution.Compiler + ( CompilerId(..), CompilerFlavor(..) ) +import Distribution.Text + +suite :: Version -> Test +suite cabalVersion = TestCase $ do + let directory = "PackageTests" "TestStanza" + pdFile = directory "my" <.> "cabal" + spec = PackageSpec directory [] + result <- cabal_configure spec + let message = "cabal configure should recognize test section" + test = "unknown section type" + `isInfixOf` + (intercalate " " $ lines $ outputText result) + assertEqual message False test + genPD <- readPackageDescription silent pdFile + let compiler = CompilerId GHC $ Version [6, 12, 2] [] + anyV = intersectVersionRanges anyVersion anyVersion + anticipatedFinalPD = emptyPackageDescription + { package = PackageIdentifier + { pkgName = PackageName "TestStanza" + , pkgVersion = Version [0, 1] [] + } + , license = BSD3 + , author = "Thomas Tuegel" + , stability = "stable" + , description = "Check that Cabal recognizes the Test stanza defined below." + , category = "PackageTests" + , descCabalVersion = anyVersion + , buildType = Just Simple + , buildDepends = + [ Dependency (PackageName "base") anyV ] + , library = Just emptyLibrary + { exposedModules = [fromString "MyLibrary"] + , libBuildInfo = emptyBuildInfo + { targetBuildDepends = + [ Dependency (PackageName "base") anyVersion ] + , hsSourceDirs = ["."] + } + } + , testsuites = [ emptyTestsuite + { testName = "dummy" + , testIs = "dummy.hs" + , testType = ExeTest (thisVersion $ Version [1] []) + , testBuildInfo = emptyBuildInfo + { targetBuildDepends = + [ Dependency (PackageName "base") anyVersion ] + , hsSourceDirs = ["."] + } + } + ] + } + case finalizePackageDescription [] (const True) buildPlatform compiler [] genPD of + Left xs -> let depMessage = "should not have missing dependencies:\n" ++ + (unlines $ map (show . disp) xs) + in assertEqual depMessage True False + Right (f, _) -> assertEqual "parsed package description does not match anticipated" + f anticipatedFinalPD addfile ./tests/PackageTests/TestStanza/Setup.hs hunk ./tests/PackageTests/TestStanza/Setup.hs 1 +import Distribution.Simple +main = defaultMain + addfile ./tests/PackageTests/TestStanza/my.cabal hunk ./tests/PackageTests/TestStanza/my.cabal 1 +name: TestStanza +version: 0.1 +license: BSD3 +author: Thomas Tuegel +stability: stable +category: PackageTests +build-type: Simple hunk ./tests/PackageTests/TestStanza/my.cabal 9 +description: + Check that Cabal recognizes the Test stanza defined below. + +Library + exposed-modules: MyLibrary + build-depends: base + +Test dummy + test-is: dummy.hs + type: executable == 1 + build-depends: base hunk ./tests/suite.hs 25 +import PackageTests.TestStanza.Check hunk ./tests/suite.hs 38 - hunit "PackageTests/BuildDeps/InternalLibrary0/" (PackageTests.BuildDeps.InternalLibrary0.Check.suite cabalVersion) + hunit "PackageTests/BuildDeps/InternalLibrary0/" (PackageTests.BuildDeps.InternalLibrary0.Check.suite cabalVersion), + hunit "PackageTests/TestStanza/" + (PackageTests.TestStanza.Check.suite cabalVersion) + -- ^ The Test stanza test will eventually be required + -- only for higher versions. hunk ./Distribution/Simple/Configure.hs 324 + pkg_descr0'' = + if fromFlag (configTests cfg) + then pkg_descr0 + else pkg_descr0 { condTestsuites = [] } hunk ./Distribution/Simple/Configure.hs 336 - pkg_descr0 + pkg_descr0'' hunk ./Distribution/Simple/Setup.hs 285 - configConfigurationsFlags :: FlagAssignment + configConfigurationsFlags :: FlagAssignment, + configTests :: Flag Bool -- ^Enable testsuite compilation hunk ./Distribution/Simple/Setup.hs 306 - configStripExes = Flag True + configStripExes = Flag True, + configTests = Flag False hunk ./Distribution/Simple/Setup.hs 460 + ,option "" ["tests"] + "dependency checking and compilation for testsuites listed in the package description file." + configTests (\v flags -> flags { configTests = v }) + (boolOpt [] []) hunk ./Distribution/Simple/Setup.hs 570 - configConfigurationsFlags = mempty + configConfigurationsFlags = mempty, + configTests = mempty hunk ./Distribution/Simple/Setup.hs 600 - configConfigurationsFlags = combine configConfigurationsFlags + configConfigurationsFlags = combine configConfigurationsFlags, + configTests = combine configTests hunk ./Distribution/PackageDescription/Configuration.hs 429 + | any ((== n) . fst) tests = bug "Test sharing name of exe found" hunk ./Distribution/PackageDescription/Configuration.hs 436 - | any ((== n) . fst) tests = bug "Testsuite with same name found" + | any ((== n) . fst) tests = bug "Test with same name found" + | any ((== n) . fst) exes = bug "Test sharing name of exe found" hunk ./Distribution/PackageDescription/Check.hs 207 + , check (not (null testDuplicates)) $ + PackageBuildImpossible $ "Duplicate test sections " + ++ commaSep testDuplicates + , check (not (null testsThatAreExes)) $ + PackageBuildImpossible $ "These test sections share names with executable sections: " + ++ commaSep testsThatAreExes hunk ./Distribution/PackageDescription/Check.hs 217 + ++ concatMap checkTestsuite (testsuites pkg) hunk ./Distribution/PackageDescription/Check.hs 227 - exeDuplicates = dups (map exeName (executables pkg)) + exeNames = map exeName $ executables pkg + testNames = map testName $ testsuites pkg + exeDuplicates = dups exeNames + testDuplicates = dups testNames + testsThatAreExes = filter (flip elem exeNames) testNames hunk ./Distribution/PackageDescription/Check.hs 269 +checkTestsuite :: Testsuite -> [PackageCheck] +checkTestsuite test = + catMaybes [ + + check (not $ null moduleDuplicates) $ + PackageBuildWarning $ + "Duplicate modules in testsuite '" ++ testName test ++ "': " + ++ commaSep (map display moduleDuplicates) + ] + where moduleDuplicates = dups $ testModules test + hunk ./Distribution/PackageDescription.hs 82 + matches, hunk ./Distribution/PackageDescription.hs 395 -withTest :: PackageDescription -> [(TestType, Testsuite -> IO ())] -> IO () -withTest pkg_descr fs = flip mapM_ (testsuites pkg_descr) $ \test -> do - let handlers = map snd $ filter (matchesType (testType test) . fst) fs - if not $ buildable (testBuildInfo test) - then return () - else if null handlers - then error $ "error in test " ++ testName test ++ - ": no support for test type " ++ show (disp $ testType test) - else mapM_ (\f -> f test) handlers +withTest :: PackageDescription -> (Testsuite -> IO ()) -> IO () +withTest pkg_descr f = mapM_ f $ testsuites pkg_descr + +-- | Do the given 'TestType's match, i.e., are they the same type with +-- overlapping 'VersionRange's? +matches :: TestType -> TestType -> Bool +matches (ExeTest v) (ExeTest v') = + not $ isNoVersion $ intersectVersionRanges v v' +matches (LibTest v) (LibTest v') = + not $ isNoVersion $ intersectVersionRanges v v' +matches _ _ = False hunk ./Distribution/Simple/Build.hs 71 - , Library(..), Executable(..), Testsuite(..), TestType(..) ) + , Library(..), Executable(..), Testsuite(..), TestType(..) + , matches ) hunk ./Distribution/Simple/Build.hs 92 +import Distribution.Text + hunk ./Distribution/Simple/Build.hs 150 - let testExeVer1 test clbi = do - info verbosity $ "Building testsuite " ++ testName test ++ "..." - buildExeTest verbosity pkg_descr lbi' test clbi - withTestLBI pkg_descr lbi' [(ExeTest $ thisVersion $ Version [1] [], testExeVer1)] + withTestLBI pkg_descr lbi' $ \test clbi -> + if testType test `matches` (ExeTest $ thisVersion $ Version [1] []) + then do + info verbosity $ "Building testsuite " ++ testName test ++ "..." + buildExeTest verbosity pkg_descr lbi' test clbi + else die $ "No support for building test type: " ++ + show (disp $ testType test) hunk ./Distribution/Simple/LocalBuildInfo.hs 69 - , Executable(exeName), withTest, Testsuite(..), TestType(..) ) + , Executable(exeName), withTest, Testsuite(..) ) hunk ./Distribution/Simple/LocalBuildInfo.hs 168 - -> [(TestType, Testsuite -> ComponentLocalBuildInfo -> IO ())] -> IO () -withTestLBI pkg_descr lbi fs = - let wrapper f test = case lookup (testName test) (testsuiteConfigs lbi) of + -> (Testsuite -> ComponentLocalBuildInfo -> IO ()) -> IO () +withTestLBI pkg_descr lbi f = + let wrapper test = case lookup (testName test) (testsuiteConfigs lbi) of hunk ./Distribution/Simple/LocalBuildInfo.hs 175 - in withTest pkg_descr $ map (\(t, f) -> (t, wrapper f)) fs + in withTest pkg_descr wrapper hunk ./Distribution/Simple/PreProcess.hs 65 - , Library(..), withLib, libModules, Testsuite(..), TestType(..), withTest ) + , Library(..), withLib, libModules, Testsuite(..), TestType(..) + , withTest, matches ) hunk ./Distribution/Simple/PreProcess.hs 86 +import Distribution.Text hunk ./Distribution/Simple/PreProcess.hs 205 - let testExeVer1 theTest = do - let bi = testBuildInfo theTest - biHandlers = localHandlers bi - testDir = buildDir lbi testName theTest testName theTest ++ "-tmp" - sequence_ [ preprocessFile (hsSourceDirs bi ++ [autogenModulesDir lbi]) - testDir forSDist (ModuleName.toFilePath modu) - verbosity builtinSuffixes biHandlers - | modu <- otherModules bi] - preprocessFile (hsSourceDirs bi) testDir forSDist - (dropExtensions (testIs theTest)) - verbosity builtinSuffixes biHandlers - withTest pkg_descr [(ExeTest $ thisVersion $ Version [1] [], testExeVer1)] + withTest pkg_descr $ \test -> + if testType test `matches` (ExeTest $ thisVersion $ Version [1] []) + then do + let bi = testBuildInfo test + biHandlers = localHandlers bi + testDir = buildDir lbi testName test testName test ++ "-tmp" + sequence_ [ preprocessFile (hsSourceDirs bi ++ [autogenModulesDir lbi]) + testDir forSDist (ModuleName.toFilePath modu) + verbosity builtinSuffixes biHandlers + | modu <- otherModules bi] + preprocessFile (hsSourceDirs bi) testDir forSDist + (dropExtensions (testIs test)) + verbosity builtinSuffixes biHandlers + else die $ "No support for pre-processing test type: " ++ + show (disp $ testType test) hunk ./Cabal.cabal 105 + Distribution.Simple.Test, hunk ./Distribution/Simple.hs 107 +import Distribution.Simple.Test (test) hunk ./Distribution/Simple.hs 325 -testAction hooks flags args = do - let distPref = fromFlag $ testDistPref flags - localbuildinfo <- getBuildConfig hooks distPref - let pkg_descr = localPkgDescr localbuildinfo - runTests hooks args False pkg_descr localbuildinfo +testAction hooks flags args + = do let distPref = fromFlag $ testDistPref flags + hookedAction preTest testHook postTest + (getBuildConfig hooks distPref) + hooks flags args hunk ./Distribution/Simple.hs 421 + testHook = defaultTestHook, hunk ./Distribution/Simple.hs 543 +defaultTestHook :: PackageDescription -> LocalBuildInfo + -> UserHooks -> TestFlags -> IO () +defaultTestHook pkg_descr localbuildinfo _ flags = + test pkg_descr localbuildinfo flags + addfile ./Distribution/Simple/Test.hs hunk ./Distribution/Simple/Test.hs 1 +----------------------------------------------------------------------------- +-- | +-- Module : Distribution.Simple.Test +-- Copyright : Thomas Tuegel 2010 +-- +-- Maintainer : cabal-devel@haskell.org +-- Portability : portable +-- +-- This is the entry point into testing a built package. Performs the +-- \"@.\/setup test@\" action. It runs testsuites designated in the package +-- description and reports on the results. hunk ./Distribution/Simple/Test.hs 13 +{- All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Isaac Jones nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -} + +module Distribution.Simple.Test ( test ) where + +import Distribution.PackageDescription + ( PackageDescription(..), Testsuite(..), TestType(..) + , hasTests, matches ) +import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..) ) +import Distribution.Simple.BuildPaths ( exeExtension ) +import Distribution.Simple.Setup ( TestFlags(..), fromFlag ) +import Distribution.Simple.Utils +import Distribution.Text +import Distribution.Verbosity ( Verbosity, silent ) +import Distribution.Version ( anyVersion, thisVersion, Version(..) ) + +import Control.Monad ( unless ) +import System.FilePath ( (), (<.>) ) +import System.Exit ( ExitCode(..) ) + +-- |Perform the \"@.\/setup test@\" action. +test :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> TestFlags -- ^flags sent to test + -> IO () +test pkg_descr lbi flags = do + let verbosity = fromFlag $ testVerbosity flags + exeTestType = (ExeTest $ thisVersion $ Version [1] []) + doTest t = + if testType t `matches` exeTestType + then doExeTest t + else do + _ <- die $ "No support for running test type: " ++ + show (disp $ testType t) + return False + doExeTest t = do + (out, _, exit) <- rawSystemStdInOut silent exe [] + Nothing False + case exit of + ExitSuccess -> do + notice verbosity $ "Testsuite " ++ testName t ++ + " successful." + doOutput info out + return True + ExitFailure code -> do + notice verbosity $ "Testsuite " ++ testName t ++ + " failure with exit code " ++ + show code ++ "!" + doOutput notice out + return False + where exe = buildDir lbi testName t + testName t <.> exeExtension + doOutput :: (Verbosity -> String -> IO ()) + -> String -> IO () + doOutput f o = if null o then return () else + f verbosity $ "Testsuite " ++ testName t ++ + " output:\n" ++ o + unless (hasTests pkg_descr) $ notice verbosity + "Package has no tests or was configured with tests disabled." + results <- mapM doTest $ testsuites pkg_descr + let successful = length $ filter id results + total = length $ testsuites pkg_descr + notice verbosity $ show successful ++ " of " ++ show total ++ + " testsuites successful." hunk ./Distribution/Simple/UserHooks.hs 69 - HaddockFlags) + HaddockFlags, TestFlags) hunk ./Distribution/Simple/UserHooks.hs 82 - -- | Used for @.\/setup test@ - runTests :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO (), hunk ./Distribution/Simple/UserHooks.hs 162 - postHaddock :: Args -> HaddockFlags -> PackageDescription -> LocalBuildInfo -> IO () + postHaddock :: Args -> HaddockFlags -> PackageDescription -> LocalBuildInfo -> IO (), + + -- |Hook to run before test command. + preTest :: Args -> TestFlags -> IO HookedBuildInfo, + -- |Over-ride this hook to get different behavior during test. + testHook :: PackageDescription -> LocalBuildInfo -> UserHooks -> TestFlags -> IO (), + -- |Hook to run after test command. + postTest :: Args -> TestFlags -> PackageDescription -> LocalBuildInfo -> IO () hunk ./Distribution/Simple/UserHooks.hs 176 - runTests = ru, hunk ./Distribution/Simple/UserHooks.hs 208 - postHaddock = ru + postHaddock = ru, + preTest = rn, + testHook = ru, + postTest = ru hunk ./Distribution/PackageDescription.hs 392 --- | Perform actions on each buildable 'Testsuite' in a package. For each --- 'Testsuite', all actions with matching 'TestType' are performed. If no --- action has a matching type, then an error message is produced. +-- | Perform an action on each buildable 'Testsuite' in a package. hunk ./Distribution/PackageDescription.hs 394 -withTest pkg_descr f = mapM_ f $ testsuites pkg_descr +withTest pkg_descr f = + mapM_ f $ filter (buildable . testBuildInfo) $ + testsuites pkg_descr hunk ./Distribution/PackageDescription.hs 83 + exeTestVer1, hunk ./Distribution/PackageDescription.hs 117 - , intersectVersionRanges, isNoVersion) + , intersectVersionRanges, isNoVersion, thisVersion ) hunk ./Distribution/PackageDescription.hs 408 +exeTestVer1 :: TestType +exeTestVer1 = ExeTest $ thisVersion $ Version [1] [] + hunk ./Distribution/Simple/Build.hs 70 - ( PackageDescription(..), BuildInfo(..) - , Library(..), Executable(..), Testsuite(..), TestType(..) - , matches ) + ( PackageDescription(..), BuildInfo(..), Library(..), Executable(..) + , Testsuite(..), matches, exeTestVer1 ) hunk ./Distribution/Simple/Build.hs 91 -import Distribution.Text - -import Distribution.Version (Version(..), thisVersion) - hunk ./Distribution/Simple/Build.hs 94 - ( display ) + ( display, disp ) hunk ./Distribution/Simple/Build.hs 146 - if testType test `matches` (ExeTest $ thisVersion $ Version [1] []) + if testType test `matches` exeTestVer1 hunk ./Distribution/Simple/PreProcess.hs 65 - , Library(..), withLib, libModules, Testsuite(..), TestType(..) - , withTest, matches ) + , Library(..), withLib, libModules, Testsuite(..), withTest, matches + , exeTestVer1 ) hunk ./Distribution/Simple/PreProcess.hs 88 - ( Version(..), anyVersion, orLaterVersion, thisVersion ) + ( Version(..), anyVersion, orLaterVersion ) hunk ./Distribution/Simple/PreProcess.hs 206 - if testType test `matches` (ExeTest $ thisVersion $ Version [1] []) + if testType test `matches` exeTestVer1 hunk ./Distribution/Simple/Test.hs 46 - ( PackageDescription(..), Testsuite(..), TestType(..) - , hasTests, matches ) + ( PackageDescription(..), Testsuite(..), hasTests, matches + , exeTestVer1 ) hunk ./Distribution/Simple/Test.hs 54 -import Distribution.Version ( anyVersion, thisVersion, Version(..) ) hunk ./Distribution/Simple/Test.hs 66 - exeTestType = (ExeTest $ thisVersion $ Version [1] []) hunk ./Distribution/Simple/Test.hs 67 - if testType t `matches` exeTestType + if testType t `matches` exeTestVer1 hunk ./Distribution/Simple/Test.hs 1 +{-# LANGUAGE CPP #-} +{-# OPTIONS_NHC98 -cpp #-} +{-# OPTIONS_JHC -fcpp #-} hunk ./Distribution/Simple/Test.hs 48 +import Distribution.Package ( PackageName(..), PackageIdentifier(..) ) hunk ./Distribution/Simple/Test.hs 55 -import Distribution.Simple.Utils +import Distribution.Simple.Utils ( die, info, notice ) hunk ./Distribution/Simple/Test.hs 57 -import Distribution.Verbosity ( Verbosity, silent ) +import Distribution.Verbosity ( Verbosity ) hunk ./Distribution/Simple/Test.hs 60 -import System.FilePath ( (), (<.>) ) +import System.Directory ( getTemporaryDirectory ) hunk ./Distribution/Simple/Test.hs 62 +import System.FilePath ( (), (<.>) ) +import System.IO ( openFile, hClose, IOMode(..) ) +#ifdef __GLASGOW_HASKELL__ +import System.Process + ( CreateProcess(..), createProcess, CmdSpec(..), StdStream(..) + , waitForProcess ) +#else +import System.Cmd ( system ) +#endif +import System.Time ( getClockTime, toUTCTime, CalendarTime(..) ) hunk ./Distribution/Simple/Test.hs 80 + PackageName pkg_name = pkgName $ package pkg_descr hunk ./Distribution/Simple/Test.hs 89 - (out, _, exit) <- rawSystemStdInOut silent exe [] - Nothing False + (outFile, exit) <- runTmpOutput exe $ "cabal-test-" ++ pkg_name + ++ "-" ++ testName t hunk ./Distribution/Simple/Test.hs 95 - doOutput info out + doOutput info outFile hunk ./Distribution/Simple/Test.hs 101 - doOutput notice out + doOutput notice outFile hunk ./Distribution/Simple/Test.hs 107 - doOutput f o = if null o then return () else + doOutput f o = hunk ./Distribution/Simple/Test.hs 109 - " output:\n" ++ o + " output logged to " ++ o hunk ./Distribution/Simple/Test.hs 117 + +runTmpOutput :: FilePath -> FilePath -> IO (FilePath, ExitCode) +runTmpOutput cmd base = do + tmp <- getTemporaryDirectory + time <- getClockTime + let timeString = formatTime $ toUTCTime time + file = tmp base ++ "-" ++ timeString ++ ".log" + hOut <- openFile file WriteMode +#ifdef __GLASGOW_HASKELL__ + (Just hIn, _, _, proc) <- createProcess $ CreateProcess + { cmdspec = RawCommand cmd [] + , cwd = Nothing + , env = Nothing + , std_in = CreatePipe + , std_out = UseHandle hOut + , std_err = UseHandle hOut + , close_fds = False + } + hClose hIn + exit <- waitForProcess proc + hClose hOut +#else + exit <- system $ cmd ++ " >" ++ quote file ++ " 2>&1" +#endif + return (file, exit) + +formatTime :: CalendarTime -> String +formatTime time = + show (ctYear time) + ++ show (fromEnum $ ctMonth time) + ++ pad ctDay + ++ "-" + ++ pad ctHour + ++ pad ctMin + ++ pad ctSec + where pad f = (if f time < 10 then "0" else "") ++ show (f time) hunk ./Distribution/Simple.hs 325 -testAction hooks flags args - = do let distPref = fromFlag $ testDistPref flags - hookedAction preTest testHook postTest - (getBuildConfig hooks distPref) - hooks flags args +testAction hooks flags args = do + let distPref = fromFlag $ testDistPref flags + localBuildInfo <- getBuildConfig hooks distPref + let pkg_descr = localPkgDescr localBuildInfo + -- | It is safe to do 'runTests' before the new test handler because the + -- default action is a no-op and if the package uses the old test interface + -- the new handler will find no tests. + runTests hooks args False pkg_descr localBuildInfo + hookedAction preTest testHook postTest + (getBuildConfig hooks distPref) + hooks flags args hunk ./Distribution/Simple/UserHooks.hs 82 + -- | Used for @.\/setup test@ + runTests :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO (), hunk ./Distribution/Simple/UserHooks.hs 174 +{-# DEPRECATED runTests "Please use the new testing interface instead!" #-} + hunk ./Distribution/Simple/UserHooks.hs 180 + runTests = ru, hunk ./Distribution/Simple/GHC.hs 87 - ( LocalBuildInfo(..), ComponentLocalBuildInfo(..), - absoluteInstallDirs ) -import Distribution.Simple.InstallDirs hiding ( absoluteInstallDirs ) + ( LocalBuildInfo(..), ComponentLocalBuildInfo(..), + componentPackageDeps ) +import Distribution.Simple.InstallDirs hunk ./Distribution/Simple/GHC.hs 544 - libInstallPath = libdir $ absoluteInstallDirs pkg_descr lbi NoCopyDest - sharedLibInstallPath = libInstallPath mkSharedLibName pkgid - (compilerId (compiler lbi)) hunk ./Distribution/Simple/GHC.hs 602 - -- For dynamic libs, Mac OS/X needs to know the install location - -- at build time. - ++ (if buildOS == OSX - then ["-dylib-install-name", sharedLibInstallPath] - else []) hunk ./Distribution/Simple/GHC.hs 87 - ( LocalBuildInfo(..), ComponentLocalBuildInfo(..), - componentPackageDeps ) -import Distribution.Simple.InstallDirs + ( LocalBuildInfo(..), ComponentLocalBuildInfo(..) + , absoluteInstallDirs ) +import Distribution.Simple.InstallDirs hiding ( absoluteInstallDirs ) hunk ./Distribution/Simple/GHC.hs 544 + libInstallPath = libdir $ absoluteInstallDirs pkg_descr lbi NoCopyDest + sharedLibInstallPath = libInstallPath mkSharedLibName pkgid + (compilerId (compiler lbi)) hunk ./Distribution/Simple/GHC.hs 605 + -- For dynamic libs, Mac OS/X needs to know the install location + -- at build time. + ++ (if buildOS == OSX + then ["-dylib-install-name", sharedLibInstallPath] + else []) hunk ./Distribution/Simple.hs 57 +{- +Work around this warning: +libraries/Cabal/Distribution/Simple.hs:78:0: + Warning: In the use of `runTests' + (imported from Distribution.Simple.UserHooks): + Deprecated: "Please use the new testing interface instead!" +-} +{-# OPTIONS_GHC -fno-warn-deprecations #-} + hunk ./Distribution/Version.hs 280 - -> (a -> a) -- ^ @\"(_)"\@ parentheses + -> (a -> a) -- ^ @\"(_)\"@ parentheses hunk ./Distribution/Simple.hs 338 - -- | It is safe to do 'runTests' before the new test handler because the + -- It is safe to do 'runTests' before the new test handler because the hunk ./Distribution/PackageDescription.hs 11 --- 'Executable', and 'Testsuite' sections each of which have associated +-- 'Executable', and 'TestSuite' sections each of which have associated hunk ./Distribution/PackageDescription.hs 75 - Testsuite(..), + TestSuite(..), hunk ./Distribution/PackageDescription.hs 77 - emptyTestsuite, + emptyTestSuite, hunk ./Distribution/PackageDescription.hs 161 - testsuites :: [Testsuite], + testSuites :: [TestSuite], hunk ./Distribution/PackageDescription.hs 197 - testsuites = [], + testSuites = [], hunk ./Distribution/PackageDescription.hs 330 --- The Testsuite type +-- The TestSuite type hunk ./Distribution/PackageDescription.hs 332 -data Testsuite = Testsuite { +data TestSuite = TestSuite { hunk ./Distribution/PackageDescription.hs 354 -instance Monoid Testsuite where - mempty = Testsuite { +instance Monoid TestSuite where + mempty = TestSuite { hunk ./Distribution/PackageDescription.hs 362 - mappend a b = Testsuite { + mappend a b = TestSuite { hunk ./Distribution/PackageDescription.hs 375 -emptyTestsuite :: Testsuite -emptyTestsuite = mempty +emptyTestSuite :: TestSuite +emptyTestSuite = mempty hunk ./Distribution/PackageDescription.hs 389 --- | Does this package have any testsuites? +-- | Does this package have any test suites? hunk ./Distribution/PackageDescription.hs 391 -hasTests = any (buildable . testBuildInfo) . testsuites +hasTests = any (buildable . testBuildInfo) . testSuites hunk ./Distribution/PackageDescription.hs 393 --- | Perform an action on each buildable 'Testsuite' in a package. -withTest :: PackageDescription -> (Testsuite -> IO ()) -> IO () +-- | Perform an action on each buildable 'TestSuite' in a package. +withTest :: PackageDescription -> (TestSuite -> IO ()) -> IO () hunk ./Distribution/PackageDescription.hs 397 - testsuites pkg_descr + testSuites pkg_descr hunk ./Distribution/PackageDescription.hs 411 --- | Get all the module names from a testsuite. -testModules :: Testsuite -> [ModuleName] +-- | Get all the module names from a test suite. +testModules :: TestSuite -> [ModuleName] hunk ./Distribution/PackageDescription.hs 694 - condTestsuites :: [(String, CondTree ConfVar [Dependency] Testsuite)] + condTestSuites :: [(String, CondTree ConfVar [Dependency] TestSuite)] hunk ./Distribution/PackageDescription/Check.hs 217 - ++ concatMap checkTestsuite (testsuites pkg) + ++ concatMap checkTestSuite (testSuites pkg) hunk ./Distribution/PackageDescription/Check.hs 228 - testNames = map testName $ testsuites pkg + testNames = map testName $ testSuites pkg hunk ./Distribution/PackageDescription/Check.hs 269 -checkTestsuite :: Testsuite -> [PackageCheck] -checkTestsuite test = +checkTestSuite :: TestSuite -> [PackageCheck] +checkTestSuite test = hunk ./Distribution/PackageDescription/Check.hs 275 - "Duplicate modules in testsuite '" ++ testName test ++ "': " + "Duplicate modules in test suite '" ++ testName test ++ "': " hunk ./Distribution/PackageDescription/Configuration.hs 66 - , CondTree(..), ConfVar(..), Condition(..), Testsuite(..) ) + , CondTree(..), ConfVar(..), Condition(..), TestSuite(..) ) hunk ./Distribution/PackageDescription/Configuration.hs 418 - (Maybe Library, [(String, Executable)], [(String, Testsuite)]) + (Maybe Library, [(String, Executable)], [(String, TestSuite)]) hunk ./Distribution/PackageDescription/Configuration.hs 451 -data PDTagged = Lib Library | Exe String Executable | Test String Testsuite | PDNull deriving Show +data PDTagged = Lib Library | Exe String Executable | Test String TestSuite | PDNull deriving Show hunk ./Distribution/PackageDescription/Configuration.hs 501 - , testsuites = tests' + , testSuites = tests' hunk ./Distribution/PackageDescription/Configuration.hs 565 - , testsuites = reverse tests + , testSuites = reverse tests hunk ./Distribution/PackageDescription/Configuration.hs 597 -testFillInDefaults :: Testsuite -> Testsuite -testFillInDefaults tst@(Testsuite { testBuildInfo = bi }) = +testFillInDefaults :: TestSuite -> TestSuite +testFillInDefaults tst@(TestSuite { testBuildInfo = bi }) = hunk ./Distribution/PackageDescription/Parse.hs 210 --- The Testsuite type +-- The TestSuite type hunk ./Distribution/PackageDescription/Parse.hs 213 -testsuiteFieldDescrs :: [FieldDescr Testsuite] -testsuiteFieldDescrs = +testSuiteFieldDescrs :: [FieldDescr TestSuite] +testSuiteFieldDescrs = hunk ./Distribution/PackageDescription/Parse.hs 228 -storeXFieldsTest :: UnrecFieldParser Testsuite -storeXFieldsTest (f@('x':'-':_), val) t@(Testsuite { testBuildInfo = bi }) = +storeXFieldsTest :: UnrecFieldParser TestSuite +storeXFieldsTest (f@('x':'-':_), val) t@(TestSuite { testBuildInfo = bi }) = hunk ./Distribution/PackageDescription/Parse.hs 632 - ,[(String, CondTree ConfVar [Dependency] Testsuite)]) + ,[(String, CondTree ConfVar [Dependency] TestSuite)]) hunk ./Distribution/PackageDescription/Parse.hs 646 - "'test' needs one argument (the testsuite's name)" + "'test' needs one argument (the test suite's name)" hunk ./Distribution/PackageDescription/Parse.hs 750 - parseTestFields :: [Field] -> PM Testsuite - parseTestFields = lift . parseFields testsuiteFieldDescrs storeXFieldsTest emptyTestsuite + parseTestFields :: [Field] -> PM TestSuite + parseTestFields = lift . parseFields testSuiteFieldDescrs storeXFieldsTest emptyTestSuite hunk ./Distribution/PackageDescription/Parse.hs 757 - [(String, CondTree ConfVar [Dependency] Testsuite)] -> + [(String, CondTree ConfVar [Dependency] TestSuite)] -> hunk ./Distribution/Simple/Build.hs 71 - , Testsuite(..), matches, exeTestVer1 ) + , TestSuite(..), matches, exeTestVer1 ) hunk ./Distribution/Simple/Build.hs 148 - info verbosity $ "Building testsuite " ++ testName test ++ "..." + info verbosity $ "Building test suite " ++ testName test ++ "..." hunk ./Distribution/Simple/Build.hs 187 - -> Testsuite -> ComponentLocalBuildInfo + -> TestSuite -> ComponentLocalBuildInfo hunk ./Distribution/Simple/Configure.hs 84 - , FlagName(..), Testsuite(..) ) + , FlagName(..), TestSuite(..) ) hunk ./Distribution/Simple/Configure.hs 327 - else pkg_descr0 { condTestsuites = [] } + else pkg_descr0 { condTestSuites = [] } hunk ./Distribution/Simple/Configure.hs 473 - testsuiteConfigs = configTest `fmap` testsuites pkg_descr', + testSuiteConfigs = configTest `fmap` testSuites pkg_descr', hunk ./Distribution/Simple/LocalBuildInfo.hs 69 - , Executable(exeName), withTest, Testsuite(..) ) + , Executable(exeName), withTest, TestSuite(..) ) hunk ./Distribution/Simple/LocalBuildInfo.hs 99 - testsuiteConfigs :: [(String, ComponentLocalBuildInfo)], + testSuiteConfigs :: [(String, ComponentLocalBuildInfo)], hunk ./Distribution/Simple/LocalBuildInfo.hs 168 - -> (Testsuite -> ComponentLocalBuildInfo -> IO ()) -> IO () + -> (TestSuite -> ComponentLocalBuildInfo -> IO ()) -> IO () hunk ./Distribution/Simple/LocalBuildInfo.hs 170 - let wrapper test = case lookup (testName test) (testsuiteConfigs lbi) of + let wrapper test = case lookup (testName test) (testSuiteConfigs lbi) of hunk ./Distribution/Simple/LocalBuildInfo.hs 172 - Nothing -> die $ "internal error: the package contains a testsuite " + Nothing -> die $ "internal error: the package contains a test suite " hunk ./Distribution/Simple/PreProcess.hs 65 - , Library(..), withLib, libModules, Testsuite(..), withTest, matches + , Library(..), withLib, libModules, TestSuite(..), withTest, matches hunk ./Distribution/Simple/PreProcess.hs 203 - unless (null (testsuites pkg_descr)) $ - setupMessage verbosity "Preprocessing testsuites for" (packageId pkg_descr) + unless (null (testSuites pkg_descr)) $ + setupMessage verbosity "Preprocessing test suites for" (packageId pkg_descr) hunk ./Distribution/Simple/Setup.hs 286 - configTests :: Flag Bool -- ^Enable testsuite compilation + configTests :: Flag Bool -- ^Enable test suite compilation hunk ./Distribution/Simple/Setup.hs 461 - "dependency checking and compilation for testsuites listed in the package description file." + "dependency checking and compilation for test suites listed in the package description file." hunk ./Distribution/Simple/Test.hs 13 --- \"@.\/setup test@\" action. It runs testsuites designated in the package +-- \"@.\/setup test@\" action. It runs test suites designated in the package hunk ./Distribution/Simple/Test.hs 50 - ( PackageDescription(..), Testsuite(..), hasTests, matches + ( PackageDescription(..), TestSuite(..), hasTests, matches hunk ./Distribution/Simple/Test.hs 93 - notice verbosity $ "Testsuite " ++ testName t ++ + notice verbosity $ "Test suite " ++ testName t ++ hunk ./Distribution/Simple/Test.hs 98 - notice verbosity $ "Testsuite " ++ testName t ++ + notice verbosity $ "Test suite " ++ testName t ++ hunk ./Distribution/Simple/Test.hs 108 - f verbosity $ "Testsuite " ++ testName t ++ + f verbosity $ "Test suite " ++ testName t ++ hunk ./Distribution/Simple/Test.hs 112 - results <- mapM doTest $ testsuites pkg_descr + results <- mapM doTest $ testSuites pkg_descr hunk ./Distribution/Simple/Test.hs 114 - total = length $ testsuites pkg_descr + total = length $ testSuites pkg_descr hunk ./Distribution/Simple/Test.hs 116 - " testsuites successful." + " test suites successful." hunk ./Distribution/PackageDescription.hs 78 - matchesType, hunk ./Distribution/PackageDescription.hs 81 - matches, - exeTestVer1, + unwrapTestModule, + unwrapMainIs, hunk ./Distribution/PackageDescription.hs 113 -import Distribution.ModuleName (ModuleName, fromString) +import Distribution.ModuleName ( ModuleName ) hunk ./Distribution/PackageDescription.hs 115 - ( Version(Version), VersionRange, anyVersion, noVersion - , intersectVersionRanges, isNoVersion, thisVersion ) + ( Version(Version), VersionRange, anyVersion ) hunk ./Distribution/PackageDescription.hs 332 - testIs :: String, + mainIs :: Maybe String, + testModule :: Maybe ModuleName, hunk ./Distribution/PackageDescription.hs 339 -data TestType = ExeTest VersionRange | LibTest VersionRange +data TestType = ExeTest Version | LibTest Version hunk ./Distribution/PackageDescription.hs 348 - v <- parse Parse.<++ return noVersion + v <- parse hunk ./Distribution/PackageDescription.hs 356 - testIs = mempty, - testType = ExeTest noVersion, + mainIs = Nothing, + testModule = Nothing, + testType = ExeTest $ Version [] [], hunk ./Distribution/PackageDescription.hs 364 - testIs = combine testIs, - testType = if testType b == ExeTest noVersion + mainIs = combine' mainIs, + testModule = combine' testModule, + testType = if testType b == ExeTest (Version [] []) hunk ./Distribution/PackageDescription.hs 375 + combine' f = case f b of + Nothing -> f a + _ -> f b hunk ./Distribution/PackageDescription.hs 382 --- | Do these test types match? Two test types match if they use the same --- constructor and have overlapping version ranges. 'matchesType' is used to --- determine if an action supports a particular test. -matchesType :: TestType -> TestType -> Bool -matchesType (ExeTest v1) (ExeTest v2) = - not $ isNoVersion $ intersectVersionRanges v1 v2 -matchesType (ExeTest _) _ = False -matchesType (LibTest v1) (LibTest v2) = - not $ isNoVersion $ intersectVersionRanges v1 v2 -matchesType (LibTest _) _ = False - hunk ./Distribution/PackageDescription.hs 392 --- | Do the given 'TestType's match, i.e., are they the same type with --- overlapping 'VersionRange's? -matches :: TestType -> TestType -> Bool -matches (ExeTest v) (ExeTest v') = - not $ isNoVersion $ intersectVersionRanges v v' -matches (LibTest v) (LibTest v') = - not $ isNoVersion $ intersectVersionRanges v v' -matches _ _ = False +unwrapTestModule :: TestSuite -> ModuleName +unwrapTestModule test = case testModule test of + Just m -> m + Nothing -> error $ "Required field 'test-module' not provided for library " + ++ "test suite " ++ testName test hunk ./Distribution/PackageDescription.hs 398 -exeTestVer1 :: TestType -exeTestVer1 = ExeTest $ thisVersion $ Version [1] [] +unwrapMainIs :: TestSuite -> FilePath +unwrapMainIs test = case mainIs test of + Just f -> f + Nothing -> error $ "Required field 'main-is' not provided for executable " + ++ "test suite " ++ testName test hunk ./Distribution/PackageDescription.hs 409 - LibTest _ -> [fromString $ testIs test] + LibTest _ -> [ unwrapTestModule test ] hunk ./Distribution/PackageDescription/Parse.hs 215 - [ simpleField "test" + [ simpleField "test-suite" hunk ./Distribution/PackageDescription/Parse.hs 221 - , simpleField "test-is" - showToken parseTokenQ - testIs (\xs test -> test {testIs=xs}) + , simpleField "main-is" + (maybe empty showFilePath) (fmap Just parseFilePathQ) + mainIs (\xs test -> test {mainIs=xs}) + , simpleField "test-module" + (maybe empty disp) (fmap Just parseModuleNameQ) + testModule (\xs test -> test {testModule=xs}) hunk ./Distribution/PackageDescription/Parse.hs 647 - | sec_type == "test" -> do + | sec_type == "test-suite" -> do hunk ./Distribution/PackageDescription/Parse.hs 649 - "'test' needs one argument (the test suite's name)" + "'test-suite' needs one argument (the test suite's name)" hunk ./Distribution/Simple/Build.hs 71 - , TestSuite(..), matches, exeTestVer1 ) + , TestSuite(..), TestType(..), unwrapMainIs ) hunk ./Distribution/Simple/Build.hs 91 +import Distribution.Version ( Version(..), withinRange, withinVersion ) hunk ./Distribution/Simple/Build.hs 147 - if testType test `matches` exeTestVer1 + case testType test of + ExeTest v -> if withinRange v (withinVersion $ Version [1,0] []) hunk ./Distribution/Simple/Build.hs 152 - else die $ "No support for building test type: " ++ - show (disp $ testType test) + else die $ "No support for building test suite type: " + ++ show (disp $ testType test) + _ -> die $ "No support for building test suite type: " + ++ show (disp $ testType test) hunk ./Distribution/Simple/Build.hs 193 -buildExeTest verbosity pkg_descr lbi test clbi = +buildExeTest verbosity pkg_descr lbi test clbi = do + let exe = Executable + { exeName = testName test + , modulePath = unwrapMainIs test + , buildInfo = testBuildInfo test + } hunk ./Distribution/Simple/Build.hs 200 - where exe = Executable { exeName = testName test - , modulePath = testIs test - , buildInfo = testBuildInfo test - } hunk ./Distribution/Simple/PreProcess.hs 65 - , Library(..), withLib, libModules, TestSuite(..), withTest, matches - , exeTestVer1 ) + , Library(..), withLib, libModules, TestSuite(..), withTest + , TestType(..), unwrapMainIs ) hunk ./Distribution/Simple/PreProcess.hs 88 - ( Version(..), anyVersion, orLaterVersion ) + ( Version(..), anyVersion, orLaterVersion, withinRange + , withinVersion ) hunk ./Distribution/Simple/PreProcess.hs 207 - if testType test `matches` exeTestVer1 - then do - let bi = testBuildInfo test - biHandlers = localHandlers bi - testDir = buildDir lbi testName test testName test ++ "-tmp" - sequence_ [ preprocessFile (hsSourceDirs bi ++ [autogenModulesDir lbi]) - testDir forSDist (ModuleName.toFilePath modu) - verbosity builtinSuffixes biHandlers - | modu <- otherModules bi] - preprocessFile (hsSourceDirs bi) testDir forSDist - (dropExtensions (testIs test)) - verbosity builtinSuffixes biHandlers - else die $ "No support for pre-processing test type: " ++ - show (disp $ testType test) + case testType test of + ExeTest v -> + if withinRange v (withinVersion $ Version [1,0] []) + then do + let bi = testBuildInfo test + biHandlers = localHandlers bi + testDir = buildDir lbi testName test + testName test ++ "-tmp" + sourceDirs = hsSourceDirs bi + ++ [autogenModulesDir lbi] + sequence_ [ preprocessFile sourceDirs testDir forSDist + (ModuleName.toFilePath modu) verbosity + builtinSuffixes biHandlers + | modu <- otherModules bi] + preprocessFile (hsSourceDirs bi) testDir forSDist + (dropExtensions (unwrapMainIs test)) + verbosity builtinSuffixes biHandlers + else die $ "No support for preprocessing test suite " + ++ "type: " ++ show (disp $ testType test) + _ -> die $ "No support for preprocessing test suite type: " + ++ show (disp $ testType test) hunk ./Distribution/Simple/Test.hs 50 - ( PackageDescription(..), TestSuite(..), hasTests, matches - , exeTestVer1 ) + ( PackageDescription(..), TestSuite(..), hasTests, TestType(..) ) hunk ./Distribution/Simple/Test.hs 57 +import Distribution.Version ( Version(..), withinVersion, withinRange ) hunk ./Distribution/Simple/Test.hs 81 - doTest t = - if testType t `matches` exeTestVer1 + doTest t = case testType t of + ExeTest v -> if withinRange v (withinVersion $ Version [1,0] []) hunk ./Distribution/Simple/Test.hs 85 - _ <- die $ "No support for running test type: " ++ - show (disp $ testType t) + _ <- die $ "No support for running test suite type: " + ++ show (disp $ testType t) + return False + _ -> do + _ <- die $ "No support for running test suite type: " + ++ show (disp $ testType t) hunk ./Distribution/Simple/Test.hs 1 -{-# LANGUAGE CPP #-} -{-# OPTIONS_NHC98 -cpp #-} -{-# OPTIONS_JHC -fcpp #-} hunk ./Distribution/Simple/Test.hs 60 -import System.IO ( openFile, hClose, IOMode(..) ) -#ifdef __GLASGOW_HASKELL__ -import System.Process - ( CreateProcess(..), createProcess, CmdSpec(..), StdStream(..) - , waitForProcess ) -#else -import System.Cmd ( system ) -#endif +import System.IO ( withFile, IOMode(..) ) +import System.Process ( runProcess, waitForProcess ) hunk ./Distribution/Simple/Test.hs 119 - hOut <- openFile file WriteMode -#ifdef __GLASGOW_HASKELL__ - (Just hIn, _, _, proc) <- createProcess $ CreateProcess - { cmdspec = RawCommand cmd [] - , cwd = Nothing - , env = Nothing - , std_in = CreatePipe - , std_out = UseHandle hOut - , std_err = UseHandle hOut - , close_fds = False - } - hClose hIn - exit <- waitForProcess proc - hClose hOut -#else - exit <- system $ cmd ++ " >" ++ quote file ++ " 2>&1" -#endif - return (file, exit) + withFile file WriteMode $ \hOut -> do + proc <- runProcess cmd [] Nothing Nothing Nothing + (Just hOut) (Just hOut) + exit <- waitForProcess proc + return (file, exit) hunk ./Distribution/Simple/Test.hs 128 - ++ show (fromEnum $ ctMonth time) + ++ pad (fromEnum . ctMonth) hunk ./Distribution/Simple/Test.hs 51 -import Distribution.Simple.Utils ( die, info, notice ) +import Distribution.Simple.Utils ( die, notice ) hunk ./Distribution/Simple/Test.hs 53 -import Distribution.Verbosity ( Verbosity ) +import Distribution.Verbosity ( normal ) hunk ./Distribution/Simple/Test.hs 56 -import Control.Monad ( unless ) +import Control.Monad ( unless, when ) hunk ./Distribution/Simple/Test.hs 60 -import System.IO ( withFile, IOMode(..) ) +import System.IO ( withFile, IOMode(..), hFlush, stdout ) hunk ./Distribution/Simple/Test.hs 84 + when (verbosity >= normal) $ do + putStr $ testName t ++ ": " + hFlush stdout hunk ./Distribution/Simple/Test.hs 91 - notice verbosity $ "Test suite " ++ testName t ++ - " successful." - doOutput info outFile + when (verbosity >= normal) $ do + putStr $ "Passed! Output logged to: " + ++ outFile ++ "\n" + hFlush stdout hunk ./Distribution/Simple/Test.hs 97 - notice verbosity $ "Test suite " ++ testName t ++ - " failure with exit code " ++ - show code ++ "!" - doOutput notice outFile + when (verbosity >= normal) $ do + putStr $ "Failed with exit code: " ++ show code + ++ "! Output logged to: " ++ outFile ++ "\n" + hFlush stdout hunk ./Distribution/Simple/Test.hs 104 - doOutput :: (Verbosity -> String -> IO ()) - -> String -> IO () - doOutput f o = - f verbosity $ "Test suite " ++ testName t ++ - " output logged to " ++ o hunk ./tests/PackageTests/TestStanza/Check.hs 15 - ( PackageDescription(..), BuildInfo(..), Testsuite(..), Library(..) + ( PackageDescription(..), BuildInfo(..), TestSuite(..), Library(..) hunk ./tests/PackageTests/TestStanza/Check.hs 17 - , emptyTestsuite, BuildType(..) ) + , emptyTestSuite, BuildType(..) ) hunk ./tests/PackageTests/TestStanza/Check.hs 62 - , testsuites = [ emptyTestsuite + , testSuites = [ emptyTestSuite hunk ./tests/PackageTests/TestStanza/Check.hs 64 - , testIs = "dummy.hs" - , testType = ExeTest (thisVersion $ Version [1] []) + , mainIs = Just "dummy.hs" + , testType = ExeTest $ Version [1,0] [] + , testModule = Nothing hunk ./tests/PackageTests/TestStanza/my.cabal 16 -Test dummy - test-is: dummy.hs - type: executable == 1 +test-suite dummy + main-is: dummy.hs + type: executable 1.0 hunk ./Distribution/PackageDescription/Check.hs 277 + + , check nullMainIs $ PackageBuildImpossible + $ "Required field 'main-is' not found in test suite " ++ testName test + + , check (not nullMainIs && mainIsWrongExt) $ PackageBuildImpossible + $ "The 'main-is' field must specify a '.hs' or '.lhs' file " + ++ "(even if it is generated by a preprocessor)." hunk ./Distribution/PackageDescription/Check.hs 285 - where moduleDuplicates = dups $ testModules test + where + moduleDuplicates = dups $ testModules test + nullMainIs = case testType test of + ExeTest _ f -> null f + LibTest _ _ -> False + mainIsWrongExt = case testType test of + ExeTest _ f -> takeExtension f `notElem` [".hs", ".lhs"] + LibTest _ _ -> False hunk ./Distribution/PackageDescription.hs 81 - unwrapTestModule, - unwrapMainIs, hunk ./Distribution/PackageDescription.hs 106 -import qualified Data.Char as Char (isAlphaNum, toLower) +import Distribution.ParseUtils ( parseFilePathQ, parseModuleNameQ ) +import qualified Data.Char as Char (isAlphaNum, toLower, isAlpha) hunk ./Distribution/PackageDescription.hs 331 - mainIs :: Maybe String, - testModule :: Maybe ModuleName, hunk ./Distribution/PackageDescription.hs 336 -data TestType = ExeTest Version | LibTest Version +data TestType = ExeTest Version FilePath | LibTest Version ModuleName hunk ./Distribution/PackageDescription.hs 338 + +instance Monoid TestType where + mempty = ExeTest (Version [] []) "" + mappend a b = if b == mempty then a else b hunk ./Distribution/PackageDescription.hs 344 - disp (ExeTest v) = text "executable" <+> disp v - disp (LibTest v) = text "library" <+> disp v + disp (ExeTest v _) = text "exitcode-stdio-" <> disp v + disp (LibTest v _) = text "library-" <> disp v hunk ./Distribution/PackageDescription.hs 347 - parse = do t <- ident - Parse.skipSpaces - v <- parse - if t == "executable" then return (ExeTest v) else - if t == "library" then return (LibTest v) else - Parse.pfail + parse = do + t <- Parse.munch1 (\c -> Char.isAlpha c || '-' == c || '_' == c) + v <- parse + Parse.skipSpaces + if t == "exitcode-stdio-" + then do + f <- parseFilePathQ + return $ ExeTest v f + else if t == "library-" + then do + m <- parseModuleNameQ + return $ LibTest v m + else Parse.pfail hunk ./Distribution/PackageDescription.hs 364 - mainIs = Nothing, - testModule = Nothing, - testType = ExeTest $ Version [] [], + testType = mempty, hunk ./Distribution/PackageDescription.hs 370 - mainIs = combine' mainIs, - testModule = combine' testModule, - testType = if testType b == ExeTest (Version [] []) - then testType a else testType b, + testType = testType a `mappend` testType b, hunk ./Distribution/PackageDescription.hs 378 - combine' f = case f b of - Nothing -> f a - _ -> f b hunk ./Distribution/PackageDescription.hs 392 -unwrapTestModule :: TestSuite -> ModuleName -unwrapTestModule test = case testModule test of - Just m -> m - Nothing -> error $ "Required field 'test-module' not provided for library " - ++ "test suite " ++ testName test - -unwrapMainIs :: TestSuite -> FilePath -unwrapMainIs test = case mainIs test of - Just f -> f - Nothing -> error $ "Required field 'main-is' not provided for executable " - ++ "test suite " ++ testName test - hunk ./Distribution/PackageDescription.hs 396 - ExeTest _ -> [] - LibTest _ -> [ unwrapTestModule test ] + ExeTest _ _ -> [] + LibTest _ m -> [ m ] hunk ./Distribution/PackageDescription/Parse.hs 63 -import Data.Char (isSpace) +import Data.Char (isSpace, isAlpha) hunk ./Distribution/PackageDescription/Parse.hs 65 +import Data.Monoid ( Monoid(..) ) hunk ./Distribution/PackageDescription/Parse.hs 73 +import qualified Distribution.Compat.ReadP as Parse hunk ./Distribution/PackageDescription/Parse.hs 80 +import Distribution.ModuleName ( ModuleName ) hunk ./Distribution/PackageDescription/Parse.hs 82 - ( anyVersion, isAnyVersion, withinRange ) + ( anyVersion, isAnyVersion, withinRange, Version(..) ) hunk ./Distribution/PackageDescription/Parse.hs 215 +data TempTestType + = TempExeTest + { tempVersion :: (Maybe Version) + , tempMainIs :: (Maybe FilePath) + , tempTestModule :: (Maybe ModuleName) + } + | TempLibTest + { tempVersion :: (Maybe Version) + , tempMainIs :: (Maybe FilePath) + , tempTestModule :: (Maybe ModuleName) + } + deriving (Show, Read, Eq) hunk ./Distribution/PackageDescription/Parse.hs 228 -testSuiteFieldDescrs :: [FieldDescr TestSuite] +instance Monoid TempTestType where + mempty = TempExeTest Nothing Nothing Nothing + + mappend a b = case tempVersion b of + Nothing -> a + { tempMainIs = tempMainIs a `orElse` tempMainIs b + , tempTestModule = tempTestModule a `orElse` tempTestModule b + } + Just _ -> b + { tempMainIs = tempMainIs a `orElse` tempMainIs b + , tempTestModule = tempTestModule a `orElse` tempTestModule b + } + +orElse :: Maybe a -> Maybe a -> Maybe a +orElse a b = case a of + Nothing -> b + Just _ -> a + +instance Text TempTestType where + disp (TempExeTest Nothing _ _) = text "exitcode-stdio" + disp (TempLibTest Nothing _ _) = text "library" + disp (TempExeTest (Just v) _ _) = text "exitcode-stdio-" <> disp v + disp (TempLibTest (Just v) _ _) = text "library-" <> disp v + + parse = do + t <- Parse.munch1 (\c -> isAlpha c || '-' == c || '_' == c) + v <- parse + if t == "exitcode-stdio-" + then return $ TempExeTest (Just v) Nothing Nothing + else if t == "library-" + then return $ TempLibTest (Just v) Nothing Nothing + else Parse.pfail + +testSuiteFieldDescrs :: [FieldDescr (TestSuite, TempTestType)] hunk ./Distribution/PackageDescription/Parse.hs 265 - testName (\xs test -> test {testName=xs}) + (testName . fst) (\xs (suite, tt) -> (suite {testName=xs}, tt)) hunk ./Distribution/PackageDescription/Parse.hs 268 - testType (\xs test -> test {testType=xs}) + snd (\xs (suite, tt) -> (suite, tt `mappend` xs)) hunk ./Distribution/PackageDescription/Parse.hs 271 - mainIs (\xs test -> test {mainIs=xs}) + (tempMainIs . snd) (\xs (suite, tt) -> (suite, tt `mappend` TempExeTest Nothing xs Nothing)) hunk ./Distribution/PackageDescription/Parse.hs 274 - testModule (\xs test -> test {testModule=xs}) + (tempTestModule . snd) (\xs (suite, tt) -> (suite, tt `mappend` TempLibTest Nothing Nothing xs)) hunk ./Distribution/PackageDescription/Parse.hs 277 - where biToTest = liftField testBuildInfo (\bi test -> test {testBuildInfo=bi}) - -storeXFieldsTest :: UnrecFieldParser TestSuite -storeXFieldsTest (f@('x':'-':_), val) t@(TestSuite { testBuildInfo = bi }) = - Just $ t {testBuildInfo = bi{ customFieldsBI = (f,val):(customFieldsBI bi)}} -storeXFieldsTest _ _ = Nothing + where biToTest = liftField (testBuildInfo . fst) (\bi (suite, tt) -> (suite {testBuildInfo=bi}, tt)) hunk ./Distribution/PackageDescription/Parse.hs 279 +storeXFieldsTest :: UnrecFieldParser (TestSuite, TempTestType) +storeXFieldsTest (f@('x':'-':_), val) (t@(TestSuite { testBuildInfo = bi }), tt) = + Just $ (t {testBuildInfo = bi{ customFieldsBI = (f,val):(customFieldsBI bi)}}, tt) +storeXFieldsTest _ x = Just x + +validateTestSuite :: LineNo -> (TestSuite, TempTestType) -> ParseResult TestSuite +validateTestSuite line (suite, tt) = + case tt of + TempExeTest Nothing _ _ -> parseFail $ flip FromString (Just line) + $ "Required field 'type' not specified for test suite " + ++ testName suite + TempLibTest Nothing _ _ -> parseFail $ flip FromString (Just line) + $ "Required field 'type' not specified for test suite " + ++ testName suite + TempExeTest _ Nothing _ -> parseFail $ flip FromString (Just line) + $ "Required field 'main-is' not specified for test suite " + ++ testName suite ++ " in test type: " ++ show tt + TempExeTest (Just v) (Just f) _ -> return $ suite { testType = ExeTest v f } + TempLibTest _ _ Nothing -> parseFail $ flip FromString (Just line) + $ "Required field 'test-module' not specified for test suite " + ++ testName suite + TempLibTest (Just v) _ (Just m) -> return $ suite { testType = LibTest v m } + hunk ./Distribution/PackageDescription/Parse.hs 820 - parseTestFields = lift . parseFields testSuiteFieldDescrs storeXFieldsTest emptyTestSuite + parseTestFields fields = do + x <- lift $ parseFields testSuiteFieldDescrs storeXFieldsTest + (emptyTestSuite, mempty) fields + lift $ validateTestSuite (lineNo $ head fields) x hunk ./Distribution/Simple/Build.hs 71 - , TestSuite(..), TestType(..), unwrapMainIs ) + , TestSuite(..), TestType(..) ) hunk ./Distribution/Simple/Build.hs 148 - ExeTest v -> if withinRange v (withinVersion $ Version [1,0] []) + ExeTest v f -> if withinRange v (withinVersion $ Version [1,0] []) hunk ./Distribution/Simple/Build.hs 150 + let exe = Executable + { exeName = testName test + , modulePath = f + , buildInfo = testBuildInfo test + } hunk ./Distribution/Simple/Build.hs 156 - buildExeTest verbosity pkg_descr lbi' test clbi + buildExe verbosity pkg_descr lbi' exe clbi hunk ./Distribution/Simple/Build.hs 195 -buildExeTest :: Verbosity -> PackageDescription -> LocalBuildInfo - -> TestSuite -> ComponentLocalBuildInfo - -> IO () -buildExeTest verbosity pkg_descr lbi test clbi = do - let exe = Executable - { exeName = testName test - , modulePath = unwrapMainIs test - , buildInfo = testBuildInfo test - } - buildExe verbosity pkg_descr lbi exe clbi - hunk ./Distribution/Simple/PreProcess.hs 66 - , TestType(..), unwrapMainIs ) + , TestType(..) ) hunk ./Distribution/Simple/PreProcess.hs 208 - ExeTest v -> + ExeTest v f -> hunk ./Distribution/Simple/PreProcess.hs 222 - (dropExtensions (unwrapMainIs test)) + (dropExtensions f) hunk ./Distribution/Simple/Test.hs 73 - ExeTest v -> if withinRange v (withinVersion $ Version [1,0] []) + ExeTest v _ -> if withinRange v (withinVersion $ Version [1,0] []) hunk ./Distribution/PackageDescription/Parse.hs 816 + -- Note: we don't parse the "executable" field here, hence the tail hack. hunk ./Distribution/PackageDescription/Parse.hs 818 - parseExeFields = lift . parseFields executableFieldDescrs storeXFieldsExe emptyExecutable + parseExeFields = lift . parseFields (tail executableFieldDescrs) storeXFieldsExe emptyExecutable hunk ./Distribution/PackageDescription/Parse.hs 939 +--TODO: make this use section syntax +-- add equivalent for GenericPackageDescription hunk ./Distribution/GetOpt.hs 102 - ,sepBy ", " (map (fmtLong ad) los) + ,concatMap (fmtLong ad) (take 1 los) hunk ./Distribution/Simple/Setup.hs 396 - "O" ("enable-optimization": case showOrParseArgs of - -- Allow British English spelling: - ShowArgs -> []; ParseArgs -> ["enable-optimisation"]) + "O" ["enable-optimization","enable-optimisation"] hunk ./Distribution/Simple/Setup.hs 399 - ("disable-optimization": case showOrParseArgs of - -- Allow British English spelling: - ShowArgs -> []; ParseArgs -> ["disable-optimisation"]) + ["disable-optimization","disable-optimisation"] hunk ./Distribution/Simple/Setup.hs 1027 - ,option "" ["hyperlink-source"] + ,option "" ["hyperlink-source","hyperlink-sources"] hunk ./Distribution/Simple/Setup.hs 74 + TestLogging(..), hunk ./Distribution/Simple/Setup.hs 1196 - testVerbosity :: Flag Verbosity + testVerbosity :: Flag Verbosity, + testSuccessOut :: Flag TestLogging, + testFailOut :: Flag TestLogging hunk ./Distribution/Simple/Setup.hs 1205 - testVerbosity = Flag normal + testVerbosity = Flag normal, + testSuccessOut = Flag File, + testFailOut = Flag Both hunk ./Distribution/Simple/Setup.hs 1210 +data TestLogging = Terminal | File | Both | None | Empty + deriving (Enum, Eq, Show, Bounded) + +instance Monoid TestLogging where + mempty = Empty + mappend a Empty = a + mappend _ b = b hunk ./Distribution/Simple/Setup.hs 1228 + ,optionTestLogging "log-success" "Log output from successful tests to" + testSuccessOut (\l flags -> flags { testSuccessOut = l }) + ,optionTestLogging "log-failure" "Log output from failing tests to" + testFailOut (\l flags -> flags { testFailOut = l }) hunk ./Distribution/Simple/Setup.hs 1234 +optionTestLogging :: String -> String -> (TestFlags -> Flag TestLogging) + -> (Flag TestLogging -> TestFlags -> TestFlags) + -> OptionField TestFlags +optionTestLogging name descrPrefix get set = + OptionField name $ [ choiceOpt + [ ( Flag Terminal + , ([], [name ++ "-terminal"]) + , descrPrefix ++ " the terminal" + ) + , ( Flag File + , ([], [name ++ "-file"]) + , descrPrefix ++ " file" + ) + , ( Flag Both + , ([], [name ++ "-both"]) + , descrPrefix ++ " both the terminal and file" + ) + , ( Flag None + , ([], [name ++ "-none"]) + , descrPrefix ++ " nowhere" + ) + ] + [] [] "" get set + ] + hunk ./Distribution/Simple/Setup.hs 1265 - testVerbosity = mempty + testVerbosity = mempty, + testSuccessOut = mempty, + testFailOut = mempty hunk ./Distribution/Simple/Setup.hs 1271 - testVerbosity = combine testVerbosity + testVerbosity = combine testVerbosity, + testSuccessOut = combine testSuccessOut, + testFailOut = combine testFailOut hunk ./Distribution/Simple/Test.hs 50 -import Distribution.Simple.Setup ( TestFlags(..), fromFlag ) +import Distribution.Simple.Setup ( TestFlags(..), fromFlag, TestLogging(..) ) hunk ./Distribution/Simple/Test.hs 57 -import System.Directory ( getTemporaryDirectory ) +import System.Directory ( getTemporaryDirectory, removeFile ) hunk ./Distribution/Simple/Test.hs 60 -import System.IO ( withFile, IOMode(..), hFlush, stdout ) +import System.IO ( withFile, IOMode(..), hFlush, stdout, hGetContents ) hunk ./Distribution/Simple/Test.hs 71 + successFlag = fromFlag $ testSuccessOut flags + failureFlag = fromFlag $ testFailOut flags hunk ./Distribution/Simple/Test.hs 93 - when (verbosity >= normal) $ do - putStr $ "Passed! Output logged to: " - ++ outFile ++ "\n" - hFlush stdout + go successFlag "Passed!" outFile hunk ./Distribution/Simple/Test.hs 96 - when (verbosity >= normal) $ do - putStr $ "Failed with exit code: " ++ show code - ++ "! Output logged to: " ++ outFile ++ "\n" - hFlush stdout + go failureFlag ("Failed with exit code: " + ++ show code ++ "!") outFile hunk ./Distribution/Simple/Test.hs 101 + go flag message outFile = do + when (verbosity >= normal) $ do + putStr $ message ++ " " ++ + if flag == File || flag == Both + then "Output logged to: " ++ outFile ++ "\n" + else "\n" + when (flag == Terminal || flag == Both) $ do + withFile outFile ReadMode $ \h -> do + output <- hGetContents h + putStrLn output + unless (flag == File || flag == Both) $ removeFile outFile + hFlush stdout hunk ./Distribution/Simple/Test.hs 58 -import System.Exit ( ExitCode(..) ) +import System.Exit ( ExitCode(..), exitFailure ) hunk ./Distribution/Simple/Test.hs 120 + when (successful < total) exitFailure hunk ./Distribution/PackageDescription/Check.hs 732 + -- check use of test suite stanzas + checkVersion [1,9,2] (not (null $ testSuites pkg)) $ + PackageDistInexcusable $ + "The package uses test suite stanzas. To use this new syntax, " + ++ "the package needs to specify at least 'cabal-version: >= 1.9.2'." + hunk ./Distribution/PackageDescription/Check.hs 739 - checkVersion [1,8] (not (null versionRangeExpressions)) $ + , checkVersion [1,8] (not (null versionRangeExpressions)) $ hunk ./Distribution/PackageDescription/Parse.hs 263 - [ simpleField "test-suite" - showToken parseTokenQ - (testName . fst) (\xs (suite, tt) -> (suite {testName=xs}, tt)) - , simpleField "type" + [ simpleField "type" hunk ./Distribution/Simple/Test.hs 144 + hunk ./Distribution/ParseUtils.hs 600 - where ver = parse <++ return noVersion + where ver :: ReadP r Version + ver = parse <++ return noVersion hunk ./Distribution/ParseUtils.hs 606 - where tw = do compiler <- parseCompilerFlavorCompat - skipSpaces - version <- parse <++ return anyVersion - skipSpaces - return (compiler,version) + where + tw :: ReadP r (CompilerFlavor,VersionRange) + tw = do compiler <- parseCompilerFlavorCompat + skipSpaces + version <- parse <++ return anyVersion + skipSpaces + return (compiler,version) hunk ./Distribution/Simple/Build/Macros.hs 44 - , "#define VERSION_",pkgname,show (display version),"\n" + ,"#define VERSION_",pkgname," ",show (display version),"\n" hunk ./Distribution/Simple/PreProcess.hs 252 - bsrcFiles <- findFileWithExtension builtinSuffixes searchLoc baseFile + bsrcFiles <- findFileWithExtension builtinSuffixes (buildLoc : searchLoc) baseFile hunk ./Distribution/Simple/Program/HcPkg.hs 248 + ierror :: a hunk ./Distribution/Simple/PreProcess.hs 234 +--TODO: try to list all the modules that could not be found +-- not just the first one. It's annoying and slow due to the need +-- to reconfigure after editing the .cabal file each time. + hunk ./Distribution/Simple/PreProcess.hs 255 + -- just to make sure one actually exists at all for this module. + -- Note: by looking in the target/output build dir too, we allow + -- source files to appear magically in the target build dir without + -- any corresponding "real" source file. This lets custom Setup.hs + -- files generate source modules directly into the build dir without + -- the rest of the build system being aware of it (somewhat dodgy) hunk ./Cabal.cabal 47 - containers >= 0.1 && < 0.4, + containers >= 0.1 && < 0.5, hunk ./Distribution/PackageDescription/Configuration.hs 4 -{-# OPTIONS_GHC -cpp #-} +-- -fno-warn-deprecations for use of Map.foldWithKey +{-# OPTIONS_GHC -cpp -fno-warn-deprecations #-}