What is the difference between `stack clean` and removing the `.stack-work` directory? - haskell

1 Context
I am involved in a Haskell project that involves lots of C-bits and FFI. So I find myself frequently running and re-running commands like
$ stack build
$ stack build --force-dirty
$ stack clean
$ rm ./.stack-work
over and over in order for the C-bits to be linked properly to the Haskell bits. Put differently, sometimes things just work when running stack build, and sometimes they don't (in which case I'm forced to cycle through the above commands over and over until my project builds properly).
This means I don't have a proper understanding of how stack (through ghc) assembles the C-bits before assembling the Haskell bits. So here is one question to help me start clearing up my confusion:
2 Question
Are there any noteworthy difference between running stack clean and deleting the contents of the .stack-work directory? Are there cases where deleting the .stack-work directory is needed as a good precaution to ensure that you are actually running a clean build?

As you can see by reading the source here:
https://github.com/commercialhaskell/stack/blob/master/src/Stack/Clean.hs
There are two levels, full and shallow. I think shallow seems to be the default. It seems to be able to clean specific packages, or if you don't provide no options at all, it'll clean everything but extra-deps in local packages.

Related

Is it possible with stack to avoid unregistering and re-compiling most (if not all) of the dependencies when switching between `--profile` on and off?

It takes several hours to recompile about 100 dependencies if I accidentally let stack unregister them when switching between --profile on and off.
I don't mean the initial building of the packages with both, but subsequent builds.
Currently I try to work around by having different copies of .stack-work. I'm trying to use hardlinks too via cp -al. But I hope stack could also just not throw away hours worth of compiled dependencies so willingly without so much as a warning. Or even better, if it kept both without unregistering.
I have Version 1.4.1, Git revision 3d29b8c68a x86_64 hpack-0.17.0

Should I use stack to build and upload to Hackage?

Over time I've developed a messy system level Haskell installation that I'm not sure how to completely clean up. But for the most part this isn't of much concern as I simply use stack to manage per-project Haskell configurations. However as my project requirements diverge from my system Haskell setup, I wonder what the best way is to build and upload packages for Hackage.
Specifically (1) should I be using
stack exec -- cabal sdist
stack exec -- cabal upload
instead of simply
cabal sdist
cabal upload
and (2) should is there any reason to install a project version of cabal (with stack build cabal?)
Or is there some better stack-based approach to building and distributing to Hackage that doesn't involve invoking cabal directly?
Adding an answer based on my earlier comment.
stack offers equivalent functionality via its
stack sdist
stack upload
commands, which don't require interfacing with cabal directly in stack-based projects.
A full list of commands supported by stack can be obtained via:
$ stack --help
and the official documentation.
Individual commands also support --help to see what command line flags they support.

(haskell) stack init does not finish. how to ignore all bounds in existing cabal files?

I am converting a project (consisting of several cabalized packages) to stack. "stack init" does not seem to be able to "calculate a build plan" (it takes ages).
Perhaps this gets easier when all version bounds are ignored. But how can I do this - other than actually removing them from the cabal files manually?
EDIT: there is "allow-newer" in http://docs.haskellstack.org/en/stable/yaml_configuration/ but this only helps if the initial stack.yaml file is already there.
Anyway, I could work around my particular problem by manually removing some packages (that is, subdirs) to be built.
My actual comand line was
stack init --verbose --resolver=lts-5 $(cat DIRS) --solver

Error building GHC on Windows

While attempting to bootstrap Haskell on Windows without the Haskell Platform I ran into the following error
C:\git\Haskell\ghc\libraries\haskeline\dist-install\build/libHShaskeline-0.7.1.2.a: could not read symbols: Archive has no index; run ranlib to add one
Note that C:\git\Haskell\ghc is where I put the ghc git repo.
However whenever I looked at the file it appeared to be building correctly.
I have attempted completely clean rebuilds, and deleting the whole repo and regetting it, everything short of deleting anything related to this build and starting fresh.
I eventually figured out what was causing the issue, I realized it when I found the following notice on the Windows Platform notes for GHC.
However, the makefiles do use whatever ld and ar happen to be in your path.
This didn't seem right, and reading the configure script I noticed the following lines:
mingwbin="$hardtop/inplace/mingw/bin/"
LD="${mingwbin}ld.exe"
Note that mingwbin refers to the location that the tarballs are extracted to. Looking at the timestamps of the executables did not match up to the version that which ld returned (in /mingw/bin).
Given the note that meant that at some point /inplace/mingw/bin/ld.exe was being used while at another point /mingw/bin/ld.exe was being used, possibly causing the issue.
Running the following command before make resolved the issue.
export PATH=/c/git/Haskell/git/inplace/mingw/bin:$PATH

GHC Install Without Root

So I'd like to set up a linux machine for Haskell development with one huge caveat -- no root privs on this machine. We could of course get the admins to install GHC for us, eventually. However, in the long-term then we need to hassle them when we want to upgrade, etc. So much better to do everything in userland. Which also means that we'll want to install c libs we link to in userland as well, etc. to keep everything as hassle-free as possible.
So, the question is, how, soup-to-nuts, would I go about doing a purely userland install of GHC? The machine will have gcc, and the usual toolchain. If necessary, we can start with a typical ghc install to get the ball rolling, but it would be nice not to.
Additionally, any tips on managing an environment like this would be appreciated, especially involving how such a setup can be manageable with multiple devs/accounts.
I did this too. I created a directory ~/usr and passed --prefix=$HOME/usr to all configure scripts. Using the Haskell Platform makes this process even smoother.
You obviously need a directory that all pertinent users have at least read permission on. Say /home/foo, with subdirectories bin, lib, share, .cabal. Then ./configure --prefix=/home/foo and make && make install, and make sure that /home/foo/* is before /usr/* in everybody's PATH, LIBRARY_PATH etc. You should probably start with installing gcc and c-libs there, and when everything C is installed, install ghc.
I managed to install ghc through stack by following these instructions. It worked like a charm; the only additional thing I had to do was to install the GMP library and to add it to the LD_LIBRARY_PATH.
If you want to use stack to install ghc or ghci, follow this offical manual:
download the tar.gz file from the release link (curl/wget/even scp can upload your local file to a remote server)
extract the file with tar xvzf and enter the folder test if ./stack run properly
add
export PATH="<stack_path>:$PATH"
to ~/.bashrc
Every time you start the terminal, do source ~/.bashrc
install ghci locally
stack ghci
It will install ghci automatically and launch it.

Resources