如何使用Stack在OS X上创建静态可执行文件?

jml*_*jml 6 macos haskell-stack

我想为Darwin创建一个静态可执行文件,用于一个我编写的名为difftodo的小型实用程序。difftodo间接取决于pcre,我希望人们能够下载二进制文件并运行它而不必先执行brew install pcre

如果我不使用选项进行编译,则会得到一个可动态链接pcre的二进制文件:

$ otool -L /Users/jml/src/difftodo/.stack-work/install/x86_64-osx/lts-7.1/8.0.1/bin/git-todo
/Users/jml/src/difftodo/.stack-work/install/x86_64-osx/lts-7.1/8.0.1/bin/git-todo:
        /usr/local/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.7.0)
        /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
Run Code Online (Sandbox Code Playgroud)

按照https://github.com/commercialhaskell/stack/issues/1032上的说明,我尝试了以下操作:

$ stack build --ghc-options -static --ghc-options -optl-static
difftodo-0.2.0: configure
Configuring difftodo-0.2.0...
difftodo-0.2.0: build
Preprocessing library difftodo-0.2.0...
ld: illegal text reloc in '_c1TGM_info' to '_stg_sel_1_upd_info' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
`gcc' failed in phase `Linker'. (Exit code: 1)

--  While building package difftodo-0.2.0 using:
      /Users/jml/.stack/setup-exe-cache/x86_64-osx/setup-Simple-Cabal-1.24.0.0-ghc-8.0.1 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.0.0 build lib:difftodo exe:all-todos exe:diff-todo exe:git-todo --ghc-options " -ddump-hi -ddump-to-file"
    Process exited with code: ExitFailure 1
Run Code Online (Sandbox Code Playgroud)

我完全不理解这种失败。

创建静态Mac OS XC构建意味着在OS X上创建完全静态的二进制文件是不可能的,也是不可取的。但是,我很高兴能够动态链接至libSystem等等,只是不指向我所依赖的第三方库。

请注意,我有一个可用的pcre静态版本:

$ ls -la /usr/local/opt/pcre/lib/
total 2700
drwxr-xr-x 18 jml admin    612 Oct  1 11:02 .
drwxr-xr-x 13 jml admin    442 Oct  1 11:02 ..
-r--r--r--  1 jml admin 443872 Oct  1 11:02 libpcre.1.dylib
-r--r--r--  1 jml admin 492016 Oct  1 11:02 libpcre.a
...
Run Code Online (Sandbox Code Playgroud)

http://gelisam.blogspot.co.uk/2014/12/how-to-package-up-binaries-for.html描述了一种解决此问题的方法:编辑可执行文件中的链接表并将其与图书馆。我宁愿有一个可执行文件。