package.yaml
Now let's have a look at the package.yaml
of our hello-world
project:
name: hello-world
version: 0.1.0.0
github: "githubuser/hello-world"
license: BSD3
author: "Author name here"
maintainer: "example@example.com"
copyright: "2023 Author name here"
extra-source-files:
- README.md
- CHANGELOG.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/githubuser/hello-world#readme>
dependencies:
- base >= 4.7 && < 5
ghc-options:
- -Wall
- -Wcompat
- -Widentities
- -Wincomplete-record-updates
- -Wincomplete-uni-patterns
- -Wmissing-export-lists
- -Wmissing-home-modules
- -Wpartial-fields
- -Wredundant-constraints
library:
source-dirs: src
executables:
hello-world-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- hello-world
tests:
hello-world-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- hello-world
The file starts with package information used when publishing the package on Hackage. This includes the package name, its version, the URL where the package is published on Github, the name of the license used, the author, the maintainer, and copyright information.
extra-source-files
is a list of files that are not part of the Haskell source
code but should be included in the package when creating an archive for example
for upload to Hackage.
synopsis
and description
are short and long descriptions of the package.
category
is the category under which this package should be found when
searching the packages on Hackage. We'll ignore these settings because we won't
publish our package to Hackage.
Now let's look at the sections we do care about.
dependencies
is a list of package names that our project depends on. base
is
already included as an entry in this list because most projects depend on the
standard library. This line also says that our project needs the standard
library version 4.7 or higher but less than version 5. If we need arrays, maps,
and monad transformers in your project, we'd add the lines
- array
- containers
- mtl
to the dependencies
list.
ghc-options
specifies compiler options to be used for our project. We'll
ignore them here. Leave them alone.
library
tells Stack where in our project the modules are to be found that
constitute the library component of our project. Remember, these are the modules
that other packages can import if we upload our package to Hackage and those
other packages specify our package as a dependency. source-dirs
specifies the
directory or directories where the library files are found. It is common to have
just a single directory here, and to leave it at the default, src
.
executables
configures a list of executable programs to be built from our
package. Given that our package is called hello-world
, the default executable
to be created is hello-world-exe
. You can change this executable name to
anything you want. It is also possible to specify multiple executables to be
built. Each needs to be represented by its separate section under executables
,
similar to the one for hello-world-exe
.
Each executable section has an entry main
that states the name of the main
module. By default, this is Main.hs
.
Next we have source-dirs
, which states where the source code for this
executable, including Main.hs
, can be found. By default, this is app
. Once
again, the code can be spread over multiple source directories, but it is common
to use only one.
Then we have a ghc-options
section again. The top-level ghc-options
section
sets the compiler options for the whole project, including the library. The
ghc-options
for an executable affect only this executable.
Finally, we have a list of dependencies
. Once again, the dependencies
on the
top level of the file are dependencies needed by all the code in our project,
including the library. The dependencies
of an executable are dependencies
needed only for building this executable. Each executable is a self-contained
project within our package. It doesn't even know anything about the library
component of our package. If it needs the code in the library component of our
package, which is quite common, it needs to specify our package itself as a
dependency. stack new
does this for us by default, by including hello-world
in the dependencies
list of hello-world-exe
.
The final section is a tests
section. The structure of this section is
identical to the executables
section. The difference is in how Stack treats
these two sections. The executables under executables
are built when running
stack build
, run when running stack run
, and installed on our system when
running stack install
. The executables under tests
are run when running
stack test
. Since we won't be writing any tests in this course, you can delete
the tests
section from package.yaml
and delete the test
directory from the
project.