diff --git a/doc/developing-packages.rst b/doc/developing-packages.rst index 12bf9bc694a536081f3898af14ac4b7982b9fb66..42412c12a366771f8fbecc4c2c0fd2d669849535 100644 --- a/doc/developing-packages.rst +++ b/doc/developing-packages.rst @@ -4,52 +4,57 @@ Quickstart .. TIP:: If this is your first time using `cabal` you should check out the `Getting Started guide <getting-started.html>`__. -Let's assume we have created a project directory and already have a -Haskell module or two. +Starting from scratch, we're going to walk you through creating a simple +Haskell application. -Every project needs a name, we'll call this example "proglet". +**TL;DR;** ``mkdir proglet && cd proglet && cabal init --simple --exe && cabal run proglet`` + + +Introduction +------------ + +Every application needs a name, we'll call ours "proglet" and start by +creating an empty directory. .. highlight:: console :: + $ mkdir proglet $ cd proglet/ - $ ls - Proglet.hs -It is assumed that (apart from external dependencies) all the files that -make up a package live under a common project root directory. This -simple example has all the project files in one directory, but most -packages will use one or more subdirectories. -To turn this into a Cabal package we need two extra files in the -project's root directory: +Using ``cabal init`` +-------------------- -- ``proglet.cabal``: containing package metadata and build information. +The ``cabal init`` command creates the necessary files for a Cabal package, +it has both an ``--interactive`` (default) and ``--non-interactive`` +mode. The interactive mode will walk you through many of the package +options and metadata, the non-interactive mode will simply pick reasonable +defaults which is sufficient if you're just trying something out. -- ``Setup.hs``: usually containing a few standardized lines of code, - but can be customized if necessary. +.. highlight:: console -We can create both files manually or we can use ``cabal init`` to create -them for us. +:: -Using "cabal init" ------------------- + $ cabal init --non-interactive + # You can also use -n which is the short version of --non-interactive -The ``cabal init --interactive`` command is interactive. If we answer -"no" to using the "sensible defaults" it asks a number of questions. +If you want, you can also try out the interactive mode, for now chose +"Executable" when asked what type of package you want to build. + +.. highlight:: console :: - $ cabal init --interactive - Should I generate a simple project with sensible defaults? [default: y] n + $ cabal init + ... What does the package build: 1) Executable 2) Library 3) Library and Executable 4) Test suite Your choice? - ... One of the important questions is whether the package contains a library and/or an executable. Libraries are collections of Haskell modules that @@ -66,25 +71,55 @@ and executable; or: test suite) cabal asks us a number of questions starting wit which version of the cabal specification to use, our package's name (for example, "proglet"), and our package's version. -It also asks questions about various other bits of package metadata. For -a package that you never intend to distribute to others, these fields -can be left blank. +:: + + Generating CHANGELOG.md... + Generating Main.hs... + Generating proglet.cabal... + +Use the ``ls`` command to see the creaed files: + +:: + + $ ls + CHANGELOG.md Main.hs proglet.cabal -Finally, ``cabal init --interactive`` creates the initial ``proglet.cabal`` -and ``Setup.hs`` files, and depending on your choice of license, a -``LICENSE`` file as well. + +Running the program +------------------- + +Now that we have our Haskell code and the extra files that Cabal needs we +can build and run our application. :: - Generating LICENSE... - Generating Setup.hs... - Generating proglet.cabal... + $ cabal build + Resolving dependencies... + ... + Linking /path/to/proglet ... + + $ cabal run proglet + ... + Hello, Haskell! + +Since we have an executable we can use ``cabal run proglet`` which will build +our executable (and re-build it if we've made any changes) and then run the +binary. The ``cabal run`` command works for any ``component-name`` (tests for +example), not just the main executable. + + +About the Cabal package structure +--------------------------------- + +It is assumed that all the files that make up a package live under a common +root directory (apart from external dependencies). This simple example has +all the package files in one directory, but most packages use one or more +subdirectories. + +Cabal needs one extra file in the package's root directory: - You may want to edit the .cabal file and add a Description field. +- ``proglet.cabal``: contains package metadata and build information. -At this stage the ``proglet.cabal`` is not quite complete and before you -are able to build the package you will need to edit the file and add -some build information about the library or executable. Editing the .cabal file ----------------------- @@ -93,33 +128,42 @@ Editing the .cabal file Load up the ``.cabal`` file in a text editor. The first part of the ``.cabal`` file has the package metadata and towards the end of the file -you will find the :pkg-section:`executable` or :pkg-section:`library` section. +you will find the :pkg-section:`executable` or :pkg-section:`library` +section. You will see that the fields that have yet to be filled in are commented -out. Cabal files use "``--``" Haskell-style comment syntax. (Note that -comments are only allowed on lines on their own. Trailing comments on -other lines are not allowed because they could be confused with program -options.) +out. Cabal files use "``--``" Haskell-style comment syntax. + +.. NOTE:: + Comments are only allowed on lines on their own. Trailing comments on + other lines are not allowed because they could be confused with program + options. -If you selected earlier to create a library package then your ``.cabal`` -file will have a section that looks like this: :: - library - exposed-modules: Proglet + executable proglet + main-is: Main.hs -- other-modules: - -- build-depends: + -- other-extensions: + build-depends: base >=4.11 && <4.12 + -- hs-source-dirs: + default-language: Haskell2010 + -Alternatively, if you selected an executable then there will be a -section like: +If you selected earlier to create a library package then your ``.cabal`` +file will have a section that looks like this: :: - executable proglet - -- main-is: + library + exposed-modules: MyLib -- other-modules: -- build-depends: + build-depends: base >=4.11 && <4.12 + -- hs-source-dirs: + default-language: Haskell2010 + The build information fields listed (but commented out) are just the few most important and common fields. There are many others that are covered @@ -135,9 +179,17 @@ not specified in the library section. Executables often follow the name of the package too, but this is not required and the name is given explicitly. + Modules included in the package ------------------------------- +For an executable, ``cabal init`` creates the ``Main.hs`` file which +contains your program's ``Main`` module. It will also fill in the +:pkg-field:`executable:main-is` field with the file name of your program's +``Main`` module, including the ``.hs`` (or ``.lhs``) extension. Other +modules included in the executable should be listed in the +:pkg-field:`other-modules` field. + For a library, ``cabal init`` looks in the project directory for files that look like Haskell modules and adds all the modules to the :pkg-field:`library:exposed-modules` field. For modules that do not form part @@ -145,12 +197,6 @@ of your package's public interface, you can move those modules to the :pkg-field:`other-modules` field. Either way, all modules in the library need to be listed. -For an executable, ``cabal init`` does not try to guess which file -contains your program's ``Main`` module. You will need to fill in the -:pkg-field:`executable:main-is` field with the file name of your program's -``Main`` module (including ``.hs`` or ``.lhs`` extension). Other modules -included in the executable should be listed in the :pkg-field:`other-modules` -field. Modules imported from other packages ------------------------------------ @@ -173,23 +219,23 @@ package, so we must list it: library exposed-modules: Proglet other-modules: - build-depends: containers, base == 4.* + build-depends: containers, base >=4.11 && <4.12 In addition, almost every package also depends on the ``base`` library package because it exports the standard ``Prelude`` module plus other basic modules like ``Data.List``. -You will notice that we have listed ``base == 4.*``. This gives a +You will notice that we have listed ``base >=4.11 && <4.12``. This gives a constraint on the version of the base package that our package will work with. The most common kinds of constraints are: -- ``pkgname >= n`` -- ``pkgname ^>= n`` (since Cabal 2.0) -- ``pkgname >= n && < m`` -- ``pkgname == n.*`` (since Cabal 1.6) +- ``pkgname >=n`` +- ``pkgname ^>=n`` (since Cabal 2.0) +- ``pkgname >=n && <m`` +- ``pkgname ==n.*`` (since Cabal 1.6) -The last is just shorthand, for example ``base == 4.*`` means exactly -the same thing as ``base >= 4 && < 5``. Please refer to the documentation +The last is just shorthand, for example ``base ==4.*`` means exactly +the same thing as ``base >=4 && <5``. Please refer to the documentation on the :pkg-field:`build-depends` field for more information. Also, you can factor out shared ``build-depends`` (and other fields such @@ -211,7 +257,8 @@ your libraries and executable sections. For example: Proglet Note that the ``import`` **must** be the first thing in the stanza. For more -information see the :ref:`common-stanzas` section. +information see the `Common stanzas`_ section. + Building the package -------------------- @@ -223,14 +270,20 @@ which also downloads and builds all required dependencies: $ cabal build -If the package contains an executable, it can be installed: +If the package contains an executable, you can run it with: + +.. code-block:: console + + $ cabal run + +and the executable can also be installed for convenince: .. code-block:: console $ cabal install -The executable program lands in a special directory for binaries -that may or may not already be on your system's ``PATH``. +When installed, the executable program lands in a special directory +for binaries that may or may not already be on your system's ``PATH``. If it is, the executable can be run by typing its filename on commandline. For installing libraries see the :ref:`adding-libraries` section. @@ -246,6 +299,7 @@ packages and details needed for distributing packages to other people. The previous chapter covers building and installing packages -- your own packages or ones developed by other people. + Package concepts ================ @@ -302,7 +356,7 @@ of digits such as "1.0.1" or "2.0". There are a range of common conventions for "versioning" packages, that is giving some meaning to the version number in terms of changes in the package, such as e.g. `SemVer <http://semver.org>`__; however, for packages intended to be -distributed via Hackage Haskell's `Package Versioning Policy <https://pvp.haskell.org/>`_ applies +distributed via Hackage Haskell's `Package Versioning Policy`_ applies (see also the `PVP/SemVer FAQ section <https://pvp.haskell.org/faq/#semver>`__). The combination of package name and version is called the *package ID* @@ -367,9 +421,9 @@ Operating system packages Unit of distribution -------------------- -The Cabal package is the unit of distribution. What this means is that -each Cabal package can be distributed on its own in source or binary -form. Of course there may be dependencies between packages, but there is +The Cabal package is the unit of distribution. This means that +each Cabal package can be distributed on its own, in source or binary +form. There may be dependencies between packages, but there is usually a degree of flexibility in which versions of packages can work together so distributing them independently makes sense.