How to Produce Stand Alone Haskell Executable

Is it possible to produce stand alone haskell executable

You can use the flags -static -optl-pthread -optl-static to avoid dynamically linked dependencies when compiling a Haskell project. This should help you run the compiled executable on two linux machines that do not have the exact same library versions.

Haskell standalone executable without using 'stack exec'

As you may already be aware, stack build builds the executable, but then places it in a stack-specific path which can most easily be accessed using stack exec. However, there is another command: stack install, which then copies the executable to a convenient location. Normally the default location is in ~/.local/bin (I think), but you can use stack install --local-bin-path <PATH> to copy the executable to <PATH>. For instance, use stack install --local-bin-path . to place the executable in your current working directory, or use stack install --local-bin-path bin to place it in your ./bin/ directory. You can then run the executable using <PATH>/my-exe.

Stack: Compile stand-alone source file

You can use stack ghc -- <file names> to compile and link a set of files (it's briefly mentioned in Stack's user guide):

You'll sometimes want to just compile (or run) a single Haskell source file, instead of creating an entire Cabal package for it. You can use stack exec ghc or stack exec runghc for that. As simple helpers, we also provide the stack ghc and stack runghc commands, for these common cases.

The -- is to ensure the arguments we pass are sent to ghc, rather than being parsed as arguments to stack exec. It's the same thing as when trying to pass arguments to an executable you've made using the normal stack toolchain: stack exec myExe -foo passes -foo to exec, not myExe, stack exec myExe -- -foo behaves as desired.


For example:

Bar.hs

module Bar where

bar :: Int
bar = 5

Foo.hs

import Bar

main :: IO ()
main = print bar

Compilation (don't even need to specify Bar.hs in the build files, it's sourced automatically):

> stack ghc -- Foo.hs
[1 of 2] Compiling Bar ( Bar.hs, Bar.o )
[2 of 2] Compiling Main ( Foo.hs, Foo.o )
Linking Foo ...
> ./Foo
5

There's no problem with dependencies either - it looks like all the packages installed locally are available to the build (you can use containers or QuickCheck without any additional build params).

Building a self-contained binary executable in Haskell with the dependency pandoc-citeproc

Adding the embed_data_files flag in the cabal install exe:myprogram command won't work, as cabal-install will pass it to your executable, rather than forwarding it to pandoc-citeproc. The most convenient way to set it up for good is through the cabal.project file. If you don't have one, create it with the following minimal contents:

packages: ./*.cabal

package pandoc-citeproc
flags: +embed_data_files

cabal-install will then recompile pandoc-citeproc dependency with the flag next time you ask for a build.

Create a static Haskell Linux executable

This simple example "works for me":

$ cat A.hs
main = print "yes"

$ ghc -O2 --make -static -optc-static -optl-static A.hs -fvia-C -optl-pthread

$ ldd A
not a dynamic executable
$ ./A
"yes"

(and I've used this process, via .cabal, to ship executables for clients in the past couple of years).

I think the best bet is to file bugs, and get this working. The IHG can also fund work like this, but I'm fairly sure the GHC team would consider this a high priority, if you're trying to ship products.

How to compile an executable from Haskell Stack build?

Haskell-stack builds the executable in the hidden .stack-work directory. You can find out where the binaries are located that stack uses with:

$ stack path --local-install-root
/haskell/app/.stack-work/install/x86_64-linux/3fa5b3c3fbcd473981eef72c68d572129654cbb7c23af146b50d90e29c41b62f/8.6.5

In this directory, there is, if you build the application, a bin/ directory where the binary is located that has been built.

You can also run the application with:

$ stack run

Making small haskell executables?

With the development branch of GHC (anyone know exactly which version this was added in?):

$ ghc -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
700 hello
476 hello-small

Add the -dynamic flag for a dynamically linked RTS:

$ ghc -dynamic -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
24 hello
16 hello-small

See also: http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport

For comparison with C:

$ gcc hello.c -o hello
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
12 hello
8 hello-small


Related Topics



Leave a reply



Submit