utdemir/ghc-musl

Cannot build 'summoner-tui'

Closed this issue · 11 comments

I'm trying to use ghc-musl to build summoner-tui. However, I see the following error when trying to do this:

Linking /mnt/dist-newstyle/build/x86_64-linux/ghc-8.8.1/summoner-tui-2.0.0.0/x/summon-tui/build/summon-tui/summon-tui ...
/nix/store/b1zj8ydpycg7vncj40mafr177bs66gw1-binutils-2.31.1/bin/ld: cannot find -ltinfo
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
cabal: Failed to build exe:summon-tui from summoner-tui-2.0.0.0.

Thanks! I'll include terminfo in the containers.

@utdemir Thank you so much!

I added ncurses library (both static and shared versions), and published -v5 images to dockerhub. I was able to compile summoner-tui statically via cloning summoner repository and applying below diff:

diff --git a/stack.yaml b/stack.yaml
index dbec01c..97fdac4 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -8,3 +8,9 @@ extra-deps:
   - generic-data-0.8.0.0
   - hspec-hedgehog-0.0.1.1
   - validation-selective-0.0.0.0
+
+compiler: ghc-8.8.1
+
+docker:
+  enable: true
+  image: utdemir/ghc-musl:v5-libgmp-ghc881
diff --git a/summoner-tui/summoner-tui.cabal b/summoner-tui/summoner-tui.cabal
index 14c3a42..5a71fb4 100644
--- a/summoner-tui/summoner-tui.cabal
+++ b/summoner-tui/summoner-tui.cabal
@@ -97,3 +97,4 @@ executable summon-tui
   ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
+                       -static -optl-static -optl-pthread -fPIC

Hope it'll work out for you, let me know if there's any other issues!

@utdemir Awesome news!

@utdemir Unfortunately, it doesn't work expected... It builds, but it prints some library error. When trying to run a simple command, I see:

$ ./summon-tui-linux-static new foo
  Configurations from /home/shersh/.summoner.toml will be used.
summon-tui-linux-static: setupTerm: Couldn't look up terminfo entry "xterm-256color"

When I expected to see the project scaffolding settings screen:

Screenshot from 2020-03-30 17-43-01

@chshersh I looked into it a bit, it looks like ncurses requires a terminfo database, and uses TERMINFO_DIRS environment variable to look up. This is seemingly a common problem with the use of ncurses. It's not specifically about static linking, but since installing ncurses for dynamic linking purposes also usually installs the terminfo files; it's only appears when ncurses is linked statically inside the binary and lacking the terminfo files.

I saw a related issue(fish-shell/fish-shell#1271) where they were thinking about embedding terminfo definitions inside ncurses. However the build definition from nixpkgs does not seem to have that functionality. I will take a look at adding that functionality to nixpkgs, but probably it won't be before the next weekend. However if you send a PR to nixpkgs or open an issue and it gets fixed, I can easily modify this repository to take advantage of the new functionality any time.

@chshersh Alternatively, can you check if you have a terminfo database on your system, and summoner-tui works if you set TERMINFO_DIRS accordingly? Maybe we just need to set the default lookup path in the statically linked library somehow.

@utdemir I can confirm that specifying TERMINFO_DIRS make statically built summoner-tui succeed. The following command works on my OS (Ubuntu 18.04):

TERMINFO_DIRS=/lib/terminfo ./summon-tui-linux-static new foo

But if I understand correctly from what I read, the path to the terminfo database can be different on different machines.

Thanks! I guess the solution would be to compile ncurses either with

  • --with-terminfo-dirs: lookup to a few hardcoded paths with directories from the most common operating systems (/lib/terminfo, /etc/terminfo, /usr/share/terminfo)
  • --with-fallback: embed some terminfo definitions directly to the library.

I'll go ahead with the first option. Hopefully I'll be able to do it via an override without sending a PR to upstream nixpkgs.

Edit: Yes, it looks like it's as easy as: ncurses.overrideDerivation (old: { configureFlags = old.configureFlags ++ [ "--with-terminfo-dirs=/lib/terminfo:/etc/terminfo:/usr/share/terminfo" ]; }). I'll test it and update the containers again.

@chshersh I uploaded v6 with the change I mentioned above. I also tried building summoner-tui again, and ran the resulting image on an Ubuntu container; and it worked, including the fancy TUI!

The resulting binary should be usable on common OS's, let me know if there's any other issues!

@utdemir Thanks for your work ❤️ I was able to build working statically linked executable for Summoner TUI.