How to make a Makefile for a program for Haskell Language?

Viewed 4842

i'm new in Haskell language and i want to create a makefile for a haskell program that i'm working on it right now. But i'm not sure how to do that.

Thank you :)

1 Answers

Almost no Haskell project uses a Makefile, because that's clunky, hard to read and error-prone.

For simple one-off projects, you don't really need any dedicated build system at all: GHC can itself figure out the dependency between modules:

sagemuej@sagemuej-X302LA:/tmp$ cat >> Hello.hs
module Main where

import Greeting

main = putStrLn greeting

sagemuej@sagemuej-X302LA:/tmp$ cat >> Greeting.hs
module Greeting where

greeting = "Hello, World!"

sagemuej@sagemuej-X302LA:/tmp$ ghc Hello.hs 
[1 of 2] Compiling Greeting         ( Greeting.hs, Greeting.o )
[2 of 2] Compiling Main             ( Hello.hs, Hello.o )
Linking Hello ...

sagemuej@sagemuej-X302LA:/tmp$ ./Hello 
Hello, World!

...or simply

sagemuej@sagemuej-X302LA:/tmp$ runhaskell Hello.hs
Hello, World!

For more involved projects and definitely for libraries, you want to use Cabal. I.e. you need a .cabal file, e.g. for the above “project” hello.cabal. Such a file can be generated semi-automatically by the cabal tool:

sagemuej@sagemuej-X302LA:/tmp$ mkdir hello
sagemuej@sagemuej-X302LA:/tmp$ mv Hello.hs hello
sagemuej@sagemuej-X302LA:/tmp$ mv Greeting.hs hello
sagemuej@sagemuej-X302LA:/tmp$ cd hello/
sagemuej@sagemuej-X302LA:/tmp/hello$ cabal init
Package name? hello
This package name is already used by another package on hackage. Do you want to choose a different name? [default: y] n
Package version? [default: 0.1.0.0] 
Please choose a license:
   1) GPL-2
   2) GPL-3
   3) LGPL-2.1
   4) LGPL-3
   5) AGPL-3
   6) BSD2
 * 7) BSD3
   8) MIT
   9) ISC
  10) MPL-2.0
  11) Apache-2.0
  12) PublicDomain
  13) AllRightsReserved
  14) Other (specify)
Your choice? [default: BSD3] 12
Author name? [default: Justus Sagemüller] 
Maintainer email? [default: sagemueller@geo.uni-koeln.de] 
Project homepage URL? 
Project synopsis? hello
Project category:
 * 1) (none)
   2) Codec
   3) Concurrency
   4) Control
   5) Data
   6) Database
   7) Development
   8) Distribution
   9) Game
  10) Graphics
  11) Language
  12) Math
  13) Network
  14) Sound
  15) System
  16) Testing
  17) Text
  18) Web
  19) Other (specify)
Your choice? [default: (none)] 17
What does the package build:
   1) Library
   2) Executable
Your choice? 2
What is the main module of the executable:
 * 1) Main.hs (does not yet exist, but will be created)
   2) Main.lhs (does not yet exist, but will be created)
   3) Other (specify)
Your choice? [default: Main.hs (does not yet exist, but will be created)] 3
Please specify? Hello.hs
Source directory:
 * 1) (none)
   2) src
   3) Other (specify)
Your choice? [default: (none)] 
What base language is the package written in:
 * 1) Haskell2010
   2) Haskell98
   3) Other (specify)
Your choice? [default: Haskell2010] 
Add informative comments to each field in the cabal file (y/n)? [default: n] 

Guessing dependencies...
Generating Setup.hs...
Generating ChangeLog.md...
Generating hello.cabal...

You may want to edit the .cabal file and add a Description field.

The file will at this point contain:

sagemuej@sagemuej-X302LA:/tmp/hello$ cat hello.cabal 
-- Initial hello.cabal generated by cabal init.  For further documentation,
--  see http://haskell.org/cabal/users-guide/

name:                hello
version:             0.1.0.0
synopsis:            hello
-- description:         
license:             PublicDomain
author:              Justus Sagemüller
maintainer:          sagemueller@geo.uni-koeln.de
category:            Text
build-type:          Simple
extra-source-files:  ChangeLog.md
cabal-version:       >=1.10

executable hello
  main-is:             Hello.hs
  -- other-modules:       
  -- other-extensions:    
  build-depends:       base >=4.10 && <4.11
  -- hs-source-dirs:      
  default-language:    Haskell2010

That's not quite complete, you still need to add Greeting.hs to the project: (without the filename extension)

...
executable hello
  main-is:             Hello.hs
  other-modules:       Greeting
  -- other-extensions:
...

But that's it, you can now do

sagemuej@sagemuej-X302LA:/tmp/hello$ cabal build
Resolving dependencies...
Configuring hello-0.1.0.0...
Preprocessing executable 'hello' for hello-0.1.0.0..
Building executable 'hello' for hello-0.1.0.0..
[1 of 2] Compiling Greeting         ( Greeting.hs, dist/build/hello/hello-tmp/Greeting.o )
[2 of 2] Compiling Main             ( Hello.hs, dist/build/hello/hello-tmp/Main.o )
Linking dist/build/hello/hello ...

Or, to just run the script, cabal run, or cabal install to make it always available on your system.

Related