Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Truly portable Haskell installation on Windows

Is it possible to have a truly portable Haskell installation on Windows so everything Haskell related happens under a single directory. I want to be able to have Haskell installation on a USB stick so I can use it on any other Windows computer just by plugging it in.

That would mean when I say cabal install somePackage everything happens locally and relative to that single directory (n.b. for different computers there might be a different drive letter assigned to the USB drive). I would like to be able to run that cabal install somePackage on any Windows computer. Also, it would be nice if I could copy the contents of the USB stick to a local hard disk and it still works from there (on some Windows machines USB sticks are mounted read only).

I am aware of the following related StackOverflow questions here and here. Can I setup cabal's config file in such a way it uses relative paths? What about other Haskell tools (e.g. winghci)?

So, how should I do it? Install Haskell Platform in a portable mode and then do what?

like image 401
Glaukon Avatar asked Nov 20 '22 14:11

Glaukon


1 Answers

Follow the process as described below:

  1. Use portable install to install Haskell Platform in e.g. h:\dev\hp. Select Do not create shortcuts. For Haskell Stack Setup, choose h:\dev\hp\local\bin as the destination folder. Deselect Add to user %PATH%.

  2. You should get the following (first level) directory structure:

    dev
      hp
        8.0.1
        local
          bin (this where stack.exe gets installed)
    
  3. Create additional subfolders:

    mkdir projects
    mkdir user
    cd user
    mkdir AppData
    mkdir AppData\Roaming
    
    dev
      hp
        projects
        user
          AppData
            Roaming
    
  4. Download and extract junction utility in the user folder. Create user\create-symlink.bat with the following contents. Then run it.

    %~dp0junction -nobanner -accepteula -d "%~dp0Application Data"
    %~dp0junction -nobanner -accepteula "%~dp0Application Data" %~dp0AppData\Roaming
    junction "Application Data" AppData\Roaming
    
  5. Create haskell.bat in the h:\dev\hp folder with the following contents:

    @ECHO OFF
    set HSROOT=%~dp08.0.1
    SET USERPROFILE=%~dp0user
    SET Path=%HSROOT%\bin;%HSROOT%\winghci;%~dp0local\bin;%HSROOT%\mingw\bin;%HSROOT%\msys\usr\bin;%HSROOT%\lib;%HSROOT%\lib\extralibs\bin;%Path%
    CMD /k "cd %~dp0projects"
    
  6. Run haskell.bat and in the command line type these commands. This should create additional folder structure under user\AppData\Roaming

    cabal update
    cabal user-config init
    stack setup
    
  7. To make cabal's config file (user\AppData\Roaming\cabal\config) relocatable, edit it and change the tags as follows:

    remote-repo-cache: $prefix\..\..\user\AppData\Roaming\cabal\packages
    world-file: $prefix\..\..\user\AppData\Roaming\cabal\world
    extra-prog-path: $prefix\..\msys\usr\bin
    extra-lib-dirs: $prefix\..\mingw\lib
    extra-include-dirs: $prefix\..\mingw\include
    build-summary: $prefix\..\..\user\AppData\Roaming\cabal\logs\build.log
    
  8. Using your favourite text editor do multi-file search and replace on the following files: user\AppData\Roaming\ghc\i386-mingw32-8.0.1\package.conf.d\*.conf

    • Search for absolute paths and replace them using $topdir (It evaluates to a directory under 8.0.1, I think it is h:\dev\hp\8.0.1\lib). So, for example if you see h:\\dev\\hp\user\\Application Data replace it with $topdir\\..\\..\\user\\AppData\\Roaming. Or, if you see h:\dev\hp\8.0.1, then replace it with $topdir\...
  9. Do the same search and replace process in the stack's snapshot folders, e.g. user\AppData\Roaming\stack\snapshots\XXX\pkgdb:

  10. Update the global and user and stack package cache:

    `ghc-pkg recache --global`
    `ghc-pkg recache --user`
    `ghc-pkg recache --package-db="h:\dev\hp\user\AppData\Roaming\stack\snapshots\XXX\pkgdb"`
    
  11. If you install new packages, you might need to repeat the search&replace step. Or you can try cabal install --enable-relocatable <package> and see if that works instead.

  12. You should be able to rename the installation folder, copy it to new location on the same machine, or on the different machine altogether and it should all work. Just use the haskell.bat to set up the environment and get a command prompt from which you should be able to run ghc, cabal, stack, winghci, etc.

  13. There is one issue still remaining. If you try to install a package that requires gcc to be built, you might get the following error:

    Configuring network-2.6.3.1...
    bash.exe: warning: could not find /tmp, please create!
    configure: WARNING: unrecognized options: --with-compiler
    checking build system type... bash.exe: warning: could not find /tmp, please create!
    bash.exe: warning: could not find /tmp, please create!
    i686-pc-mingw32
    checking host system type... i686-pc-mingw32
    checking for gcc... h:\dev\hp\80227D~1.1Ăé´ÉŐĂőýŽÇ┬ćýŁŻ┬îŃąÇĂéňżö┬łŃŽ«ĂéŃąÇĂéň庤ťO
    checking whether the C compiler works... no
    configure: error: in `/cygdrive/c/DOCUME~1/UserName/LOCALS~1/Temp/stack4268/network-2.6.3.1':
    configure: error: C compiler cannot create executables
    See `config.log' for more details
    

    The reason is that configure script gets passed the wrong path to gcc (h:\dev\hp\80227D~1.1Ăé´ÉŐĂőýŽÇ┬ćýŁŻ┬îŃąÇĂéňżö┬łŃŽ«ĂéŃąÇĂéň庤ťO). I know how to build the offending package manually, but don't know how to install it:

    stack unpack network-2.6.3.1
    cd network-2.6.3.1
    stack init
    # edit `configure` script and put `CC=` on the first line to kill system supplied path to `gcc`
    stack build
    
like image 66
Glaukon Avatar answered Dec 26 '22 20:12

Glaukon