-
Notifications
You must be signed in to change notification settings - Fork 714
[doc] Remove references to "Nix" in "How to build locally..." #11008
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,10 @@ | ||
.. _nix-style-builds: | ||
|
||
How to build locally like in Nix | ||
================================ | ||
|
||
Nix-style local builds are a new build system implementation inspired by Nix. | ||
The Nix-style local build system is commonly called "v2-build" for short | ||
after the ``cabal v2-*`` family of commands that control it. However, those | ||
names are only temporary now that Nix-style local builds have become the | ||
default. For those who do not wish to use the new | ||
functionality, the classic project style will not be removed immediately, | ||
but these legacy commands will require the usage of the ``v1-`` prefix as of | ||
Cabal 3.0 and will be removed in a future release. For a future-proof | ||
way to use these commands in a script or tutorial that anticipates the | ||
possibility of another UI paradigm being devised in the future, there | ||
are also ``v2-`` prefixed versions that will reference the same functionality | ||
until such a point as it is completely removed from Cabal. | ||
|
||
Nix-style local builds combine the best of non-sandboxed and sandboxed Cabal: | ||
|
||
1. Like sandboxed Cabal previously, we build sets of independent local | ||
packages deterministically and independent of any global state. | ||
v2-build will never tell you that it can't build your package | ||
because it would result in a "dangerous reinstall." Given a | ||
particular state of the Hackage index, your build is completely | ||
reproducible. For example, you no longer need to compile packages | ||
with profiling ahead of time; just request profiling and v2-build | ||
will rebuild all its dependencies with profiling automatically. | ||
|
||
2. Like non-sandboxed Cabal today, builds of external packages are | ||
cached in a global store, so that a package can be built once, | ||
and then reused anywhere else it is also used. No need to continually | ||
rebuild dependencies whenever you make a new sandbox: dependencies | ||
which can be shared, are shared. | ||
|
||
Nix-style local builds were first released as beta in cabal-install 1.24. | ||
They currently work with all versions of GHC supported by that release: GHC 7.0 and later. | ||
|
||
Some features described in this manual are not implemented. If you need | ||
them, please give us a shout and we'll prioritize accordingly. | ||
|
||
How to build packages | ||
===================== | ||
|
||
The following sections describe how to build and work with a package | ||
or a project consisting of multiple packages. | ||
|
||
.. toctree:: | ||
nix-local-build |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,10 +4,10 @@ Quickstart | |
========== | ||
|
||
Suppose that you are in a directory containing a single Cabal package | ||
which you wish to build (if you haven't set up a package yet check | ||
out :doc:`How to package Haskell code <how-to-package-haskell-code>` for | ||
instructions). You can configure and build it using Nix-style | ||
local builds with this command (configuring is not necessary): | ||
which you wish to build (if you haven't set up a package yet check out | ||
:doc:`How to package Haskell code <how-to-package-haskell-code>` for | ||
instructions). You can configure and build it with this command | ||
(configuring is not necessary): | ||
|
||
:: | ||
|
||
|
@@ -23,14 +23,14 @@ To run an executable defined in this package, use this command: | |
|
||
:: | ||
|
||
$ cabal run <executable name> [executable args] | ||
$ cabal run <executable name> -- [executable args] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! I think people quite often forget and then run into issues There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This actually can work without In particular,
https://cabal.readthedocs.io/en/3.14/cabal-commands.html#cabal-run Now, what to do about it: I'm ambivalent. If people think that this is confusing, I'm fine with |
||
|
||
Developing multiple packages | ||
---------------------------- | ||
|
||
Many Cabal projects involve multiple packages which need to be built | ||
together. To build multiple Cabal packages, you need to first create a | ||
``cabal.project`` file which declares where all the local package | ||
:doc:`cabal.project <cabal-project-description-file>` file which declares where all the local package | ||
directories live. For example, in the Cabal repository, there is a root | ||
directory with a folder per package, e.g., the folders ``Cabal`` and | ||
``cabal-install``. The ``cabal.project`` file specifies each folder as | ||
|
@@ -77,11 +77,7 @@ example, to build a test suite named ``package-tests``, use the command: | |
|
||
Targets can be qualified with package names. So to request | ||
``package-tests`` *from* the ``Cabal`` package, use | ||
``Cabal-tests:package-tests``. | ||
|
||
Unlike sandboxes, there is no need to setup a sandbox or ``add-source`` | ||
projects; just check in ``cabal.project`` to your repository and | ||
``build`` will just work. | ||
``Cabal:package-tests``. | ||
|
||
Cookbook | ||
======== | ||
|
@@ -137,25 +133,30 @@ development environments. | |
How it works | ||
============ | ||
|
||
The following sections are intended to provide you with a mental model | ||
for how building works: where dependencies are fetched from, where | ||
build products are stored, and what state (if any) is affected by | ||
performing actions with Cabal. | ||
|
||
Local versus external packages | ||
------------------------------ | ||
|
||
One of the primary innovations of Nix-style local builds is the | ||
distinction between local packages, which users edit and recompile and | ||
must be built per-project, versus external packages, which can be cached | ||
across projects. To be more precise: | ||
Cabal distinguishes between local packages, which users edit and | ||
recompile and must be built per-project, and external packages, which | ||
can be cached across projects. To be more precise: | ||
|
||
1. A **local package** is one that is listed explicitly in the | ||
``packages``, ``optional-packages`` or ``extra-packages`` fields of a | ||
project. Packages in the former two fields will usually have their | ||
source code stored in a folder in your project, while ``extra-packages`` lists | ||
packages residing on Hackage that are treated as being local anyway. | ||
|
||
Local packages, as well as the external packages (below) which depend on | ||
them, are built **inplace**, meaning that they are always built | ||
specifically for the project and are not installed globally. Inplace | ||
packages are not cached and not given unique hashes, which makes them | ||
suitable for packages which you want to edit and recompile. | ||
Local packages, as well as the external packages (below) which depend | ||
on them, are built **in-place**, meaning that they are always built | ||
locally for the project, and not installed in the global store (see | ||
below). In-place packages are not cached and not given unique hashes, | ||
which makes them suitable for packages which you want to edit and | ||
recompile. | ||
|
||
2. An **external package** is any package which is not listed in the | ||
``packages``, ``optional-packages`` and ``extra-packages`` fields. | ||
|
@@ -165,7 +166,7 @@ When an external package does not depend on an inplace package, it can | |
be built and installed to a **global** store, which can be shared across | ||
projects. These build products are identified by a hash based on all of | ||
the inputs which influence the compilation of a package (flags, | ||
dependency selection, etc.). Just as in Nix, these hashes uniquely | ||
dependency selection, etc.). These hashes uniquely | ||
identify the result of a build; if we compute this identifier and we | ||
find that we already have this ID built, we can just use the already | ||
built version. | ||
|
@@ -177,71 +178,50 @@ whatever reason (e.g., to reclaim disk space or because the global | |
store is corrupted), deleting this directory is safe (``build`` | ||
will just rebuild everything it needs on its next invocation). | ||
|
||
This split motivates some of the UI choices for Nix-style local build | ||
This split motivates some of the UI choices for Cabal's build | ||
commands. For example, flags passed to ``cabal build`` are only | ||
applied to *local* packages, so that adding a flag to | ||
``cabal build`` doesn't necessitate a rebuild of *every* transitive | ||
dependency in the global package store. | ||
|
||
In cabal-install 2.0 and above, Nix-style local builds also take advantage of a | ||
new Cabal library feature, `per-component | ||
builds <https://github.com/ezyang/ghc-proposals/blob/master/proposals/0000-componentized-cabal.rst>`__, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, we lose this link in this patch... It may be good to think about preserving it in some form. I don't think there's a comparable explanation in the manual itself currently. |
||
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 one | ||
executable needs to be rebuilt. Packages that use Custom setup scripts | ||
are not currently built on a per-component basis. | ||
When a package has multiple components (libraries, executables, etc.), | ||
each component 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 one executable needs to be | ||
rebuilt. Packages that use Custom setup scripts (see | ||
:ref:`more-complex-packages`) are not currently built on a | ||
per-component basis. | ||
|
||
Where are my build products? | ||
---------------------------- | ||
|
||
A major deficiency in the current implementation of ``cabal build`` is that | ||
there is no programmatic way to access the location of build products. | ||
The location of the build products is intended to be an internal | ||
implementation detail of ``cabal build``, but we also understand that many | ||
unimplemented features can only be reasonably worked around by | ||
accessing build products directly. | ||
|
||
The location where build products can be found varies depending on the | ||
version of cabal-install: | ||
|
||
- In cabal-install-1.24, the dist directory for a package ``p-0.1`` is | ||
stored in ``dist-newstyle/build/p-0.1``. For example, if you built an | ||
executable or test suite named ``pexe``, it would be located at | ||
``dist-newstyle/build/p-0.1/build/pexe/pexe``. | ||
|
||
- In cabal-install-2.0, the dist directory for a package ``p-0.1`` | ||
defining a library built with GHC 8.0.1 on 64-bit Linux is | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1``. When | ||
per-component builds are enabled (any non-Custom package), a | ||
subcomponent like an executable or test suite named ``pexe`` will be | ||
stored at | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/c/pexe``; thus, | ||
the full path of the executable is | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/c/pexe/build/pexe/pexe`` | ||
(you can see why we want this to be an implementation detail!) | ||
|
||
- In cabal-install-2.2 and above, the ``/c/`` part of the above path | ||
is replaced with one of ``/l/``, ``/x/``, ``/f/``, ``/t/``, or | ||
``/b/``, depending on the type of component (sublibrary, | ||
executable, foreign library, test suite, or benchmark | ||
respectively). So the full path to an executable named ``pexe`` | ||
compiled with GHC 8.0.1 on a 64-bit Linux is now | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/x/pexe/build/pexe/pexe``; | ||
for a benchmark named ``pbench`` it now is | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/b/pbench/build/pbench/pbench``; | ||
|
||
|
||
The paths are a bit longer in 2.0 and above but the benefit is that you can | ||
transparently have multiple builds with different versions of GHC. We | ||
plan to add the ability to create aliases for certain build | ||
configurations, and more convenient paths to access particularly useful | ||
build products like executables. | ||
The build products for a project are found under the ``dist-newstyle`` | ||
directory. The actual paths are intended to be an implementation | ||
detail; you can find the true path for e.g. an executable using the | ||
``cabal list-bin`` command. But for the sake of concreteness we describe | ||
Cabal's current policy for build product paths below. | ||
|
||
When per-component builds are enabled (any non-Custom package), a | ||
subcomponent like an executable or test suite named ``pexe`` will be | ||
stored at | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/<tag>/pexe``; thus, | ||
the full path of the executable is | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/<tag>/pexe/build/pexe/pexe`` | ||
(you can see why we want this to be an implementation detail!) | ||
|
||
Where ``<tag>`` is one of ``/l/``, ``/x/``, ``/f/``, ``/t/``, or | ||
``/b/``, depending on the type of component (sublibrary, | ||
executable, foreign library, test suite, or benchmark | ||
respectively). So the full path to an executable named ``pexe`` | ||
compiled with GHC 8.0.1 on a 64-bit Linux is now | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/x/pexe/build/pexe/pexe``; | ||
for a benchmark named ``pbench`` it is | ||
``dist-newstyle/build/x86_64-linux/ghc-8.0.1/p-0.1/b/pbench/build/pbench/pbench`` | ||
|
||
Caching | ||
------- | ||
|
||
Nix-style local builds support a robust caching system which helps to reduce | ||
Cabal supports a robust caching system which helps to reduce | ||
the time it takes to execute a rebuild cycle. While the details of how | ||
``cabal-install`` does caching are an implementation detail and may | ||
change in the future, knowing what gets cached is helpful for | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we rename both files so that the URL doesn't mention Nix as well?