Stack: Supporting additional compilers

Created on 26 Oct 2017  路  8Comments  路  Source: commercialhaskell/stack

Is there documentation on how to create compiler packages that integrate with stack? Something similar to how @tolysz packages GHCJS?

I'm interested in using stack to create stable compilation for cross compiling to aarch64. @angerman already has some cross-compiling bindists. These require the packages provided in head.hackage. Is it feasible to package these together to offer stable cross compilation?

Most helpful comment

Not sure if I can help, as I'm currently not a heavy user of stack. A few things to note though:

  • the bindists will soon move away from the configure && make install approach and towards a relocatable install package (e.g. unpack and run bin/ghc). There are some caveats here, but I hope that this will at least work on macOS and linux reliably. This is because the current binary-dist logic is tailored heavily towards stage2 (host == target) compilers, and not really towards cross compilers.
  • the bindists implicitly depend on their toolchains. This has been abstracted a bit via the toolchain-wrappers. A lot of that is only there to ensure that $triple-PROG is called, instead of just PROG. Or pass flats to the program (e.g. --cross-compile to hsc2hs).
  • @Tehnix, provided an install script in mobilehaskell/hackage-overlay#4, which might help for some inspiration?
  • hackage overlays are essentially hackage indices, with a set of patched applied to a few known packages. head.hackage currently has patches for the Semigroup-Monoid-Proposal changes in HEAD. And the hackage.mobilehaskell overlay provides patches specific to cross compilation (e.g. zlib), while waiting for changes to be upstreamed. Stackage might have a different approach to this.
    I'm not absolutely sure about mix and match of overlays. There is certainly an issue if multiple overlays contain patches to the same package.

All 8 comments

You can point stack at custom GHC bindists via https://docs.haskellstack.org/en/stable/yaml_configuration/#setup-info

Pretty sure you can use the package-indices option to point at the other package set. Not sure exactly what the config would look like. Please post it up here and maybe also elsewhere if you get it worked out.

Ideally the cross compiling page could be updated with this info.

I'm somewhat struggling in this area right now as well (but not with anything arch related, just with building GHCJS packages). https://github.com/tolysz/prepare-ghcjs has info on how @tolysz builds packages, in case that's of any help.

Not sure if I can help, as I'm currently not a heavy user of stack. A few things to note though:

  • the bindists will soon move away from the configure && make install approach and towards a relocatable install package (e.g. unpack and run bin/ghc). There are some caveats here, but I hope that this will at least work on macOS and linux reliably. This is because the current binary-dist logic is tailored heavily towards stage2 (host == target) compilers, and not really towards cross compilers.
  • the bindists implicitly depend on their toolchains. This has been abstracted a bit via the toolchain-wrappers. A lot of that is only there to ensure that $triple-PROG is called, instead of just PROG. Or pass flats to the program (e.g. --cross-compile to hsc2hs).
  • @Tehnix, provided an install script in mobilehaskell/hackage-overlay#4, which might help for some inspiration?
  • hackage overlays are essentially hackage indices, with a set of patched applied to a few known packages. head.hackage currently has patches for the Semigroup-Monoid-Proposal changes in HEAD. And the hackage.mobilehaskell overlay provides patches specific to cross compilation (e.g. zlib), while waiting for changes to be upstreamed. Stackage might have a different approach to this.
    I'm not absolutely sure about mix and match of overlays. There is certainly an issue if multiple overlays contain patches to the same package.

Anything I can do to help!

It would also seem that setup-info would need to be able to support more fields. We could probably get the GHC distribution with the ghc field, but would be missing things @angerman mentions that the toolchain-wrapper currently handles.

Honestly, it would be super neat to be able to point to a specific compiler with stack that'd take care of all my (admittedly quick) script currently does. Just a lot of path juggling tbh.

@Tehnix Certainly a PR adding support for these additional fields would be greatly appreciated!

@angerman Thanks for the info!

I'm not sure if this is correct, but I've added the following to my stack.yaml:

resolver: lts-9.10

setup-info:
  ghc:
    aarch64-apple-ios:
      8.3.20171002:
        url: http://hackage.mobilehaskell.org/x86_64-apple-darwin/aa5f532d20/ghc-8.3.20171020-aarch64-apple-ios.tar.xz

package-indices:
- name: Hackage
  download-prefix: http://hackage.haskell.org/package/
  http: http://hackage.haskell.org/
- name: Hackage Head
  download-prefix: http://head.hackage.haskell.org/package/
  http: http://head.hackage.haskell.org/01-index.tar.gz

This gives me link errors complaining about the wrong architecture.

I tried adding some of the flags @angerman mentioned via ghc-options, but haven't had much luck.

resolver: lts-9.10

ghc-options:
  "*": "-pgml xcrun -optl --sdk iphoneos ld -arch arm64"

setup-info:
  ghc:
    aarch64-apple-ios:
      8.3.20171020:
        url: http://hackage.mobilehaskell.org/x86_64-apple-darwin/aa5f532d20/ghc-8.3.20171020-aarch64-apple-ios.tar.xz
# url: http://hackage.mobilehaskell.org/x86_64-apple-darwin/aa5f532d20/ghc-8.3.20171002-aarch64-apple-ios.tar.xz

# compiler: ghc-8.3.20171020
# compiler-check: match-exact

package-indices:
- name: Hackage
  download-prefix: http://hackage.haskell.org/package/
  http: http://hackage.haskell.org/
- name: Hackage Head
  download-prefix: http://head.hackage.haskell.org/package/
  http: http://head.hackage.haskell.org/01-index.tar.gz

This results in errors since the flags aren't formatted properly. Does this look like the right direction?

It seems some of the programs also found in the toolchain-wrapper are specified in the settings file for the GHC stack pulls down, i.e. /Users/tehnix/.stack/programs/x86_64-osx/ghc-8.0.2/lib/ghc-8.0.2/settings,

[("GCC extra via C opts", " -fwrapv -fno-builtin"),
 ("C compiler command", "/usr/bin/gcc"),
 ("C compiler flags", " -m64 -fno-stack-protector"),
 ("C compiler link flags", " -m64"),
 ("C compiler supports -no-pie", "NO"),
 ("Haskell CPP command","/usr/bin/gcc"),
 ("Haskell CPP flags","-E -undef -traditional -Wno-invalid-pp-token -Wno-unicode -Wno-trigraphs"),
 ("ld command", "/usr/bin/ld"),
 ("ld flags", " -arch x86_64"),
 ("ld supports compact unwind", "YES"),
 ("ld supports build-id", "NO"),
 ("ld supports filelist", "YES"),
 ("ld is GNU ld", "NO"),
 ("ar command", "/usr/bin/ar"),
 ("ar flags", "clqs"),
 ("ar supports at file", "NO"),
 ("touch command", "touch"),
 ("dllwrap command", "/bin/false"),
 ("windres command", "/bin/false"),
 ("libtool command", "libtool"),
 ("perl command", "/usr/bin/perl"),
 ("cross compiling", "NO"),
 ("target os", "OSDarwin"),
 ("target arch", "ArchX86_64"),
 ("target word size", "8"),
 ("target has GNU nonexec stack", "False"),
 ("target has .ident directive", "True"),
 ("target has subsections via symbols", "True"),
 ("Unregisterised", "NO"),
 ("LLVM llc command", "llc"),
 ("LLVM opt command", "opt")
 ]

The ones generated by the wrapper roughly consist of,

$triple-ar
$triple-cabal
$triple-clang
$triple-ld
$triple-ld.gold
$triple-libtool
$triple-nm
$triple-ranlib

We can see that ar, ld, libtool and clang (via ("C compiler command", "/usr/bin/gcc") are already there, so perhaps this would be the place to build upon it, instead of in the setup-info?

This is probably an issue somewhere in the build system. The ones in the settings should match the $target (triple) prefixed ones.

What my plan is for cabal, is to teach it a --host flag. Which takes the triple, and tries to find the programs with the host triple prefix, prior to falling back to the non-prefixed ones.

In general, if you are able to set the tools in the .stack.yml explicitly, you could just list the prefixed ones. And it might already work?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sjakobi picture sjakobi  路  3Comments

bitemyapp picture bitemyapp  路  3Comments

fizruk picture fizruk  路  3Comments

Cosmius picture Cosmius  路  3Comments

domenkozar picture domenkozar  路  3Comments