Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions src/preamble/01_what_do_we_mean_when_we_say_cabal.md
Original file line number Diff line number Diff line change
@@ -1 +1,95 @@
# What do we mean when we say cabal?

Cabal is an umbrella term that can refer to either "cabal the spec" (.cabal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"the package spec"? I wasn't sure if you mean "specification of the cabal software system" or "cabal format spec" or "cabal protocol spec".

files), "cabal the library" (code that understands .cabal files), or "cabal the
tool" (the cabal-install package which provides the cabal executable).

## tl;dr

1. [cabal-install](#the-cabal-file) is the command line utility to help
configure, compile and install Haskell libraries and programs.

2. [The Cabal build system](#the-cabal-library), a library that is used for
reation of packages and the building of their contents. This build system is
used by cabal-install and other package manager, stack for example. For eg:
parsing .cabal files (among others).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, can we get rid of For eg: its a little too informal for a guide. If you are going to explain what some of libraries capabilities are you should list more than just parsing (I usually cite 3 examples as a rule of thumb).


3. [.cabal file](#the-binary-cabal-install-cli-tool) This is the format that
specifies the content of Haskell packages. A .cabal file specifies a Haskell
package with via some top level metadata about the package and build specific
information (exposed modules, external dependencies, language extensions,
compiler options) about the components that comprise the package.

## The .cabal file

The .cabal file contains information that drives the compilation and building of
Haskell packages. Usually the .cabal file lives at the root directory that
contains the haskell source code corresponding to the package. Usually this file
is named as `project-name.cabal`. It is a text-based, key-value format, that is
divided into subsections called stanzas. Each section consists of a number of
property descriptions.

The package properties describe the package as a whole, such as name, license,
author, dependenices, etc. It also contains optional information about optional
components such as
[library properties](../new_to_cabal/06_first_cabal_library.md),
Copy link

@jhrcek jhrcek Sep 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick:
"about optional components such as library properties" - sounds weird. Is "library property" an optional component?
I'd change this to [libraries]. Also in the "optional information about optional components" I'd drop the first "optional".
Since the component is optional, it means it can be left out, so no need to mention the optionality twice.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, agree. I'll remove the first optional.

[executables](../new_to_cabal/07_first_cabal_executable.md),
[test-suite](../leveling_up/02_first_cabal_test-suite.md),
[benchmark](src/leveling_up/03_first_cabal_benchmark.md). These components are
Comment on lines +35 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test-suites, benchmarks; they can be many, as well.

also called stanzas.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that currently GHC is virtually the only one, I'd clarify "(e.g., different versions of the GHC compiler or one of the past or future competitors)". Because there is no present competitor, sadly. :)

present in different Haskell implementations and wherever possible it is best to
take advantage of these to increase portability. For example one of the pieces
Comment on lines +41 to +42
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be a little less proscriptive and condense to "present in different Haskell implementations that can be used to increase portability.".

of information an 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.

## The CABAL library

CABAL stands for Common Architecture for Building Applications and Libraries.
This is the library that provides functionality that allows the information in
the .cabal files to be put to use. Without the Cabal library, the Cabal package
format is just that, a text file. The Cabal library contains the implementations
that allow for the parsing and operations based on the content of a .cabal file.
Cabal the library by convention is written with Capitalization case. Cabal can
take a haskell dependency graph (of external and internal modules) and use GHC
to build it.

## The binary cabal-install (cli tool)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is hard, because the exe is not called cabal-install and we don't want to mislead the users. How about "The commandline tool (cabal-instal)"? I'm not happy with that either.


The cabal binary or more accurately `cabal-install` is the command-line tool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd repeat the section title: "The commandline tool project called cabal-install, with the executable confusingly named cabal, provides user interface..."

that provides a user interface for dealing with Haskell packages. cabal-install
makes use of Cabal the library to do its job.

cabal-install is a frontend to Cabal. It makes it possible to build Haskell
Comment on lines +72 to +75
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two sentences are almost repeated.

projects whose sets of dependencies might conflict with each other within the
confines of a single system. Packages provide a constraint on the version of
various libraries (version range) that will work with their package. When
cabal-install is asked to build a project, by default it looks at the
dependencies specified in its .cabal file and uses a dependency solver to figure
out a set of packages and package versions that satisfy it. This set of packages
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say "packages with their versions" to be able to later on omit "and package versions".

is drawn from all package and all versions from Hackage as a whole. The chosen
versions of the dependenices will be installed and indexed in a database in the
cabal directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean ~/.cabal directory? I am pretty sure that's the correct one. It would be good to confirm this in the cabal docs either way.


Conflicts between dependencies are avoided by indexing the installed packages
according to their version and other relevant configuration options. This allows
different projects to retrieve the dependency versions they need.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add "dependency versions and build flavours".


stack is also a command-line tool that depends on the Cabal Library, and hence
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be high-minded and also compliment ourselves saying something like "stack is another mature command-line tool, with somewhat different goals and trade-offs, that depends...".

also consumes the information specified in Cabal Package format found in the
.cabal files.

# References

1. [Cabal hackage page](https://hackage.haskell.org/package/Cabal)
2. [cabal-install hackage page](https://hackage.haskell.org/package/cabal-install)