Cabal / Stack ignores ghc-options for custom Setup scripts - haskell

I'm trying to get Stack working on an Arch system. I've done the usual:
pacman -S ghc stack cabal-install
And then placed the following in ~/.stack/config.yaml, so that the system GHC is used and dynamic libraries are used (the packages above do not include static libraries):
system-ghc: true
ghc-options:
"$everything": -dynamic
configure-options:
"$everything":
- -dynamic
But when I try to install something, (i.e. stack install wai) I see that it attempts to build a custom Setup script:
/usr/bin/ghc-8.6.5 -rtsopts -threaded -clear-package-db -global-package-db -hide-all-packages -package base -main-is StackSetupShim.mainOverride -package Cabal-2.4.0.1 /home/alba/.stack/setup-exe-src/setup-mPHDZzAJ.hs /home/alba/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs -o /home/alba/.stack/setup-exe-cache/x86_64-linux/tmp-Cabal-simple_mPHDZzAJ_2.4.0.1_ghc-8.6.5
And my options are not honored, so the build tries to use static libraries (and fails). Is there any way to get Stack/Cabal to use certain options when building Setup.hs?

EDIT: I found the relevant issues; it doesn't seem to be possible:
stack: Can't use system GHC without static libraries at all (#3409)
cabal: executable-dynamic: True should apply to build-type: Custom setup #1720
Related: It seems cabal will always attempt to build static + dynamic in some cases, even if you tell it otherwise.
For now, a partial solution I ended up using is to force the option with a wrapper.
At ~/.local/bin/ghc-8.6.5 put:
#!/bin/sh
exec /usr/bin/ghc-8.6.5 -dynamic "$#"
Then:
cd ~/.local/bin
chmod +x ghc-8.6.5
ln -s ghc{-8.6.5,}
ln -s {/usr/bin,.}/ghc-pkg-8.6.5
ln -s {/usr/bin,.}/runghc-8.6.5
ln -s {/usr/bin,.}/haddock-ghc-8.6.5
Make sure it's in your PATH and you're good to go.

Related

Removing dependency on Terminfo package from a GHC compiled binary

I'd like to remove terminfo package from the default dependencies of my GHC installation, as the generated executable does not run in a particular environment without libtinfo, saying:
./Main: error while loading shared libraries: libtinfo.so.6: cannot
open shared object file: No such file or directory
So, is there any neat way to remove dependency on terminfo package?
The only way I found is to use -hide-all-packages of ghc and then enumerate all required default packages via -package option:
ghc -hide-all-packages -package-db ~/.cabal/store/ghc-8.10.7/package.db \
-package base -package containers -package array -package template-haskell \
-package unix -package filepath -package process -package directory \
-package time --make Main.hs
Options like -hide-package or -ignore-package doesn't work.
$ ghc -ignore-package terminfo -ignore-package ghc --make Main.hs
Loaded package environment from /home/keigoi/.ghc/x86_64-linux-8.10.7/environments/default
<command line>: cannot satisfy -package-id ghc-8.10.7:
ghc-8.10.7 is ignored due to an -ignore-package flag
(use -v for more information)
Any ideas?
Some thoughts and additional findings:
(*) I have no idea why the generated binary depends on it -- the package is required by GHC API, which is not always necessary I think and I didn't use it.
Actually, binaries generated from the fresh installation (as of GHC 8.10 or 9.2 from ghcup) does not depend on libtinfo.
Under the circumstance that ~/.ghc/x86_64-linux-8.10.7/environments/default does not exist, the generated binary has no dependency to libtinfo. This file is generated when you initialize Cabal. After that, the compiled binary will depend on libtinfo.so.
(**) Commands like strip seems not to elimite that dependency.

GHC option for performance related files out directory

I made instrumental build which generates profiling information. I use stack. GHC options in .cabal file are:
ghc-options: -Wall
-O2
-threaded
-prof
-fprof-auto
-rtsopts
-fprof-cafs
"-with-rtsopts=-N -s -h -i0.1 -p -M1G -SMyApplication-S.log"
so running application generates files: MyApplication-S.log, MyApplication.hp, MyApplication.prof, but in current working directory - which is the problem, sure (also I need to run it on Windows and Linux). Is it possible to specify directory of those output files with some option? Because, without it I will get "Can't open ... file..." error due to permission error - Haskell Runtime tries to save all of them in current folder (on Linux and on Windows standard folders for binaries are not allowed for writing).
After reading of GHC source code (Profiling.c and RtsFlags.c) I found that it's possible with -po option:
ghc-options: -Wall
-O2
-threaded
-prof
-fprof-auto
-rtsopts
-fprof-cafs
"-with-rtsopts=-N -s -h -i0.1 -p -po/My/Dir/MyApplication -M1G -S/My/Dir/MyApplication-S.log"
So, will be created same 3 files but now in /My/Dir folder.

Setting cabal configuration options in a stack project

In my stack project I have a myproject.cabal file. I would like to try the cabal option --disable-library-profiling documented here:
https://www.haskell.org/cabal/users-guide/installing-packages.html
However, I've been unable to figure out where that option must be used: wherever I put it, subsequent stack runs exit with failure (complaining in one way or another about the option).
My higher-level goal is to see if this speeds up ghc compilation for my project, but that's really secondary as far as this question goes: I'd really just like to know how these configuration options work (in the context of stack projects).
I'm using ghc 6.7. In particular, if I use cabal configure, the option ends up configured in ghc-options in my myproject.cabal file, but GHC then complains:
ghc: unrecognised flag: --disable-library-profiling
I'm already using other ghc-options without running into similar trouble -- stack completes successfully in this case:
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0 -j +RTS -A128m -n2m -RTS
but not in this case:
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0 -j +RTS -A128m -n2m -RTS --disable-library-profiling
The stack equivalent of --disable-library-profiling is:
$ stack build --no-library-profiling

"requested module differs from name found in the interface file"

What I want is: cabal to build my modules; make to build this one script.
The script links to Objective-C (see https://github.com/mchakravarty/language-c-inline/tree/master/tests/objc/marshal-array). when I build the script, it fails on the import:
$ make
Main.hs:1:1:
Bad interface file: dist/build/Commands/OSX/Events.hi
Something is amiss; requested module main:Commands.OSX.Events differs from name found in the interface file commands-0.0.0:Commands.OSX.Events
here are some file contents:
$ cat Makefile
PACKAGES = -package template-haskell -package language-c-quote -package language-c-inline -package commands
FRAMEWORKS = -framework Carbon -framework Cocoa -framework Foundation
LDFLAGS = $(PACKAGES) $(FRAMEWORKS)
Main: Main.o
cabal exec -- ghc -o Main Main.o $(LDFLAGS)
Main.o:
cabal build
cabal exec -- ghc -c Main.hs -idist/build/ -v
...
$ cat commands.cabal
exposed-modules: Commands.OSX.Events
hs-source-dirs: sources
...
$ ghc --show-iface dist/build/Commands/OSX/Events.hi
interface commands-0.0.0:Commands.OSX.Events 7083
...
$ cat sources/Commands/OSX/Events.hs
module Commands.OSX.Events where
...
$ cat Main.hs
import Commands.OSX.Events
...
the cabal build is successful, and executable compiles and runs successfully, if I just put everything in the same directory, and ignore cabal.
can I tell GHC that some module is part of some package?
can I make a cabal executable, with these external dependencies?
any other solutions?
explicitly naming the modules package worked:
ghc -package-name commands-0.0.0
http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/packages.html

Override -Werror when installing from Cabal

I'm trying to install the nano-hmac-0.2.0 package (a dependency of a package I want) from Hackage using Cabal and GHC 6.12.1, but it fails with the following error:
Data/Digest/OpenSSL/HMAC.hsc:1:0:
Warning: Module `Prelude' is deprecated:
You are using the old package `base' version 3.x.
Future GHC versions will not support base version 3.x. You
should update your code to use the new base version 4.x.
<no location info>:
Failing due to -Werror.
Sure enough, the package's .cabal file has the following line in it:
ghc-options: -Wall -Werror -O2 -fvia-C
I'd like to be able to override the -Werror option so I can install the package without manually modifying the .cabal file, but can't find a way that will work. In particular, I tried passing --ghc-options to Cabal to stick a -Wwarn in GHC's argument list, like this:
$ cabal install nano-hmac-0.2.0 -v2 --ghc-options='-Wwarn'
This doesn't do what I want, though; the verbose output verifies that -Wwarn is getting added to the beginning of GHC's argument list, but the -Werror from the .cabal file appears later and seems to override it:
/usr/bin/ghc -Wwarn --make -package-name nano-hmac-0.2.0 -hide-all-packages -fbuilding-cabal-package -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir dist/build -stubdir dist/build -package-id base-3.0.3.2-0092f5a086872e0cdaf979254933cd43 -package-id bytestring-0.9.1.5-125aff5b9d19ec30231ae2684b8c8577 -O -Wall -Werror -O2 -fvia-C -XForeignFunctionInterface -XBangPatterns -XCPP Data.Digest.OpenSSL.HMAC
I also tried passing --constraint='base >= 4' to Cabal to force it to use a more recent version of base and avoid the warning entirely, but I get the same failure, and I still see the following in the verbose output:
Dependency base ==3.0.3.2: using base-3.0.3.2
Is there a way to get rid of or override the -Werror coming from the .cabal file via the Cabal command line, or am I stuck modifying the .cabal file myself?
Is there a way to get rid of or override the -Werror coming from the .cabal file via the Cabal command line, or am I stuck modifying the .cabal file myself?
Indeed. There's no way in general. You may be able to override package constraints such that the warnings go away, however, in general, you must modify the .cabal file.
These days Hackage prevents people uploading packages with -Werror in their .cabal file, so the issue will go away over time.

Resources