Create a Static Haskell Linux Executable

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.

Finding haskell executable if statically linked via glibc or musl

One way of finding it, although it's limited to haskell based executable is using the --info option:

Example:

$ ./tldr +RTS --info -RTS
[("GHC RTS", "YES")
,("GHC version", "8.6.5")
,("RTS way", "rts_thr")
,("Build platform", "x86_64-alpine-linux")
,("Build architecture", "x86_64")
,("Build OS", "linux")
,("Build vendor", "alpine")
,("Host platform", "x86_64-alpine-linux")
,("Host architecture", "x86_64")
,("Host OS", "linux")
,("Host vendor", "alpine")
,("Target platform", "x86_64-alpine-linux")
,("Target architecture", "x86_64")
,("Target OS", "linux")
,("Target vendor", "alpine")
,("Word size", "64")
,("Compiler unregisterised", "NO")
,("Tables next to code", "YES")
]

From the x86_64-apline-linux, I can confirm that the build was based on Alpine Linux which is based on musl. You can explicitly confirm via ldd that it is indeed statically linked then:

$ ldd ./tldr
not a dynamic 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.

Force static compilation in stack

I have leveraged the Yaml include mechanism, here is my flags.yaml for static compilation:

- &deployed_exe
cc-options: -static
ld-options: -static -pthread
extra-lib-dirs: ./.system-work/lib
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -static

And my package.yamls:

_flags: !include "../flags.yaml"


executables:
test-bootstrap:
<<: *deployed_exe
main: Main.hs
source-dirs: app

I have a symbolic link I switch depending of my needs.

is it possible to create portable x86-64 Linux executable with ocamlopt ghc and gcc compiler?

I have not tested it myself, but I assume that the combination of -ccopt (from ocamlopt) and -static (from gcc) will do the trick.

  • from ocamlopt manual
-ccopt option
Pass the given option to the C compiler and linker. For instance,-ccopt -Ldir causes the C linker to search for C libraries in directory dir.
  • from gcc manual
-static
On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. On other systems, this option has no effect.



Related Topics



Leave a reply



Submit