Supposethat you are in a directory containing a single Cabal packagewhich you wish to build. You can configure and build it using Nix-stylelocal builds with this command (configuring is not necessary):
Many Cabal projects involve multiple packages which need to be builttogether. To build multiple Cabal packages, you need to first create acabal.project file which declares where all the local packagedirectories live. For example, in the Cabal repository, there is a rootdirectory with a folder per package, e.g., the folders Cabal andcabal-install. The cabal.project file specifies each folder aspart of the project:
The expectation is that a cabal.project is checked into your sourcecontrol, to be used by all developers of a project. If you need to makelocal changes, they can be placed in cabal.project.local (whichshould not be checked in.)
One of the primary innovations of Nix-style local builds is thedistinction between local packages, which users edit and recompile andmust be built per-project, versus external packages, which can be cachedacross projects. To be more precise:
Local packages, as well as the external packages (below) which depend onthem, are built inplace, meaning that they are always builtspecifically for the project and are not installed globally. Inplacepackages are not cached and not given unique hashes, which makes themsuitable for packages which you want to edit and recompile.
When an external package does not depend on an inplace package, it canbe built and installed to a global store, which can be shared acrossprojects. These build products are identified by a hash that over all ofthe inputs which would influence the compilation of a package (flags,dependency selection, etc.). Just as in Nix, these hashes uniquelyidentify the result of a build; if we compute this identifier and wefind that we already have this ID built, we can just use the alreadybuilt version.
In cabal-install 2.0 and above, Nix-style local builds also take advantage of anew Cabal library feature, per-componentbuilds,where each component of a package is configured and built separately.This can massively speed up rebuilds of packages with lots of components(e.g., a package that defines multiple executables), as only oneexecutable needs to be rebuilt. Packages that use Custom setup scriptsare not currently built on a per-component basis.
A major deficiency in the current implementation of new-build is thatthere is no programmatic way to access the location of build products.The location of the build products is intended to be an internalimplementation detail of new-build, but we also understand that manyunimplemented features can only be reasonably worked around byaccessing build products directly.
The paths are a bit longer in 2.0 and above but the benefit is that you cantransparently have multiple builds with different versions of GHC. Weplan to add the ability to create aliases for certain buildconfigurations, and more convenient paths to access particularly usefulbuild products like executables.
Nix-style local builds sport a robust caching system which help reducethe time it takes to execute a rebuild cycle. While the details of howcabal-install does caching are an implementation detail and maychange in the future, knowing what gets cached is helpful forunderstanding the performance characteristics of invocations tonew-build. The cached intermediate results are stored indist-newstyle/cache; this folder can be safely deleted to clear thecache.
cabal new-configure takes a set of arguments and writes acabal.project.local file based on the flags passed to this command.cabal new-configure FLAGS; cabal new-build is roughly equivalent tocabal new-build FLAGS, except that with new-configure the flagsare persisted to all subsequent calls to new-build.
cabal new-configure is intended to be a convenient way to write outa cabal.project.local for simple configurations; e.g.,cabal new-configure -w ghc-7.8 would ensure that all subsequentbuilds with cabal new-build are performed with the compilerghc-7.8. For more complex configuration, we recommend writing thecabal.project.local file directly (or placing it incabal.project!)
The options of all of these flags apply only to local packages in aproject; this behavior is different than that of cabal install,which applies flags to every package that would be built. The motivationfor this is to avoid an innocuous addition to the flags of a packageresulting in a rebuild of every package in the store (which might needto happen if a flag actually applied to every transitive dependency). Toapply options to an external package, use a package stanza in acabal.project file.
In component targets, package: and ctype: (valid component typesare lib, flib, exe, test and bench) can be used todisambiguate when multiple packages define the same component, or thesame component name is used in a package (e.g., a package foodefines both an executable and library named foo). We always preferinterpreting a target as a package name rather than as a component name.
Beyond a list of targets, cabal new-build accepts all the flags thatcabal new-configure takes. Most of these flags are only taken intoconsideration when building local packages; however, some flags maycause extra store packages to be built (for example,--enable-profiling will automatically make sure profiling librariesfor all transitive dependencies are built and installed.)
To avoid ghci specific flags from triggering unneeded global rebuilds theseflags are now stripped from the internal configuration. As a result--ghc-options will no longer (reliably) work to pass flags to ghci (orother repls). Instead, you should use the new --repl-options flag tospecify these options to the invoked repl. (This flag also works on cabalrepl and Setup repl on sufficiently new versions of Cabal.)
cabal new-run [TARGET [ARGS]] runs the executable specified by thetarget, which can be a component, a package or can be left blank, aslong as it can uniquely identify an executable within the project.Tests and benchmarks are also treated as executables.
cabal new-freeze writes out a freeze file which records all ofthe versions and flags which that are picked by the solver under thecurrent index and flags. Default name of this file iscabal.project.freeze but in combination with a--project-file=my.project flag (see project-file)the name will be my.project.freeze.A freeze file has the same syntax as cabal.project and lookssomething like this:
For end-user executables, it is recommended that you distribute thecabal.project.freeze file in your source repository so that allusers see a consistent set of dependencies. For libraries, this is notrecommended: users often need to build against different versions oflibraries than what you developed against.
By default, it removes the entire folder, but it can also spare the configurationand caches if the --save-config option is given, in which case it only removesthe build artefacts (.hi, .o along with any other temporary files generatedby the compiler, along with the build output).
cabal new-sdist [FLAGS] [TARGETS] takes the crucial files needed to build TARGETSand puts them into an archive format ready for upload to Hackage. These archives are stableand two archives of the same format built from the same source will hash to the same value.
new-sdist is inherently incompatible with sdist hooks, not due to implementation but dueto fundamental core invariants (same source code should result in the same tarball, byte forbyte) that must be satisfied for it to function correctly in the larger new-build ecosystem.autogen-modules is able to replace uses of the hooks to add generated modules, along withthe custom publishing of Haddock documentation to Hackage.
cabal.project files support a variety of options which configure thedetails of your build. The general syntax of a cabal.project file issimilar to that of a Cabal file: there are a number of fields, some ofwhich live inside stanzas:
In general, the accepted field names coincide with the accepted commandline flags that cabal install and other commands take. For example,cabal new-configure --enable-profiling will write out a projectfile with profiling: True.
All local packages are vendored, in the sense that if other packages(including external ones from Hackage) depend on a package with the nameof a local package, the local package is preferentially used. Thismotivates the default settings:
Run nat jobs simultaneously when building. If $ncpus isspecified, run the number of jobs equal to the number of CPUs.Package building is often quite parallel, so turning on parallelismcan speed up build times quite a bit!
Specifies the name of the directory where build products forbuild will be stored; defaults to dist-newstyle. If arelative name is specified, this directory is resolved relativeto the root of the project (i.e., where the cabal.projectfile lives.)
Specifies the name of the project file used to specify therest of the top-level configuration; defaults to cabal.project.This name not only specifies the name of the main project file,but also the auxiliary project files cabal.project.freezeand cabal.project.local; for example, if you specify--project-file=my.project, then the other files that willbe probed are my.project.freeze and my.project.local.
A package can be specified multiple times in constraints, inwhich case the specified constraints are intersected. This isuseful, since the syntax does not allow you to specify multipleconstraints at once. For example, to specify both version bounds andflag assignments, you would write:
Like constraints, but the solver will attempt to satisfythese preferences on a best-effort basis. The resulting install is locallyoptimal with respect to preferences; specifically, no single packagecould be replaced with a more preferred version that still satisfiesthe hard constraints.
One way to use preferences is to take a known working set ofconstraints (e.g., via cabal new-freeze) and record them aspreferences. In this case, the solver will first attempt to use thisconfiguration, and if this violates hard constraints, it will try tofind the minimal number of upgrades to satisfy the hard constraintsagain.
3a8082e126