Simple way to have the GHC API for application deployed on Windows
Asked Answered
A

1

11

I want to deploy an application on Windows that needs to access the GHC API. Using the first simple example from the Wiki:

http://www.haskell.org/haskellwiki/GHC/As_a_library

results in the following error (compiled on one machine with haskell platform and executed on another clean windows install): test.exe: can't find a package database at C:\haskell\lib\package.conf.d

I'd like to deploy my application as a simple zip file and not require the user to have anything installed. Is there a straightforward way to include the needed GHC things in that zip file so it will work?

Arc answered 18/3, 2011 at 17:47 Comment(4)
you can manually specify path to package.conf.d instead of calling libdir. i.e. runGhc (Just "path\to\ghc\lib")Implacental
Thanks, but my question is more about how to accomplish a minimum embedding of ghc in my application on windows then the specific error mentioned.Arc
In that case I don't understand what is the problem actually. It seems that you only need to copy lib and mingw to your zip and provide runGhc with relative path to this lib (and don't forget to remove unused packages and libraries with profiling information from lib).Implacental
@max please post your comment as an answer so I can accept it. That does appear to be sufficient. The next challenge of course is somehow minimizing the lib directory as the one in my dev environment is over 682 MB.Arc
I
2

This program will copy necessary files to the specified directory (will work only on windows):

import Data.List (isSuffixOf)
import System.Environment (getArgs)
import GHC.Paths (libdir)
import System.Directory
import System.FilePath 
import System.Cmd

main = do
  [to] <- getArgs
  let libdir' = to </> "lib"
  createDirectoryIfMissing True libdir'
  copy libdir libdir'
  rawSystem "xcopy"
    [ "/e", "/q"
    , dropFileName libdir </> "mingw"
    , to </> "mingw\\"]


-- | skip some files while copying
uselessFile f
  = or $ map (`isSuffixOf` f)
    [ "."
    , "_debug.a"
    , "_p.a", ".p_hi"    -- libraries built with profiling
    , ".dyn_hi", ".dll"] -- dynamic libraries


copy from to
  = getDirectoryContents from
  >>= mapM_ copy' . filter (not . uselessFile)
  where
    copy' f = do
      let (from', to') = (from </> f, to </> f)
      isDir <- doesDirectoryExist from'
      if isDir
          then createDirectory to' >> copy from' to'
          else copyFile from' to'

After running it with destination directory as argument you will have a local copy of lib and mingw (about 300 Mb total).

You can remove unused libraries from lib to save more space.

Implacental answered 31/3, 2011 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.