compileBuildInfo :: Verbosity
                 -> FilePath -- ^output directory
                 -> [FilePath] -- ^library source dirs, if building exes
                 -> [ModuleName] -- ^Modules
                 -> BuildInfo
                 -> LocalBuildInfo
                 -> IO ()
--TODO: should not be using mLibSrcDirs at all
compileBuildInfo verbosity destDir mLibSrcDirs mods bi lbi = do
    -- Pass 1: copy or cpp files from build directory to scratch directory
    let useCpp = EnableExtension CPP `elem` allExtensions bi
    let srcDir = buildDir lbi
        srcDirs = nub $ srcDir : hsSourceDirs bi ++ mLibSrcDirs
    info verbosity $ "Source directories: " ++ show srcDirs
    flip mapM_ mods $ \ m -> do
        fs <- findFileWithExtension suffixes srcDirs (ModuleName.toFilePath m)
        case fs of
          Nothing ->
            die ("can't find source for module " ++ display m)
          Just srcFile -> do
            let ext = takeExtension srcFile
            copyModule verbosity useCpp bi lbi srcFile
                (destDir </> ModuleName.toFilePath m <.> ext)
    -- Pass 2: compile foreign stubs in scratch directory
    stubsFileLists <- fmap catMaybes $ sequence
      [ findFileWithExtension suffixes [destDir] (ModuleName.toFilePath modu)
      | modu <- mods]
    compileFiles verbosity bi lbi destDir stubsFileLists
compileBuildInfo :: Verbosity
                 -> FilePath -- ^output directory
                 -> [FilePath] -- ^library source dirs, if building exes
                 -> [ModuleName] -- ^Modules
                 -> BuildInfo
                 -> LocalBuildInfo
                 -> IO ()
compileBuildInfo verbosity destDir mLibSrcDirs mods bi lbi = do
    -- Pass 1: copy or cpp files from build directory to scratch directory
    let useCpp = EnableExtension CPP `elem` allExtensions bi
    let srcDir = buildDir lbi
        srcDirs = nub $ srcDir : hsSourceDirs bi ++ mLibSrcDirs
    info verbosity $ "Source directories: " ++ show srcDirs
    flip mapM_ mods $ \ m -> do
        fs <- findFileWithExtension suffixes srcDirs (ModuleName.toFilePath m)
        case fs of
          Nothing ->
            die ("can't find source for module " ++ display m)
          Just srcFile -> do
            let ext = takeExtension srcFile
            copyModule verbosity useCpp bi lbi srcFile
                (destDir </> ModuleName.toFilePath m <.> ext)
    -- Pass 2: compile foreign stubs in scratch directory
    stubsFileLists <- fmap catMaybes $ sequence
      [ findFileWithExtension suffixes [destDir] (ModuleName.toFilePath modu)
      | modu <- mods]
    compileFiles verbosity bi lbi destDir stubsFileLists
compileBuildInfo verbosity destDir mLibSrcDirs mods bi lbi = do
    -- Pass 1: copy or cpp files from build directory to scratch directory
    let useCpp = EnableExtension CPP `elem` allExtensions bi
    let srcDir = buildDir lbi
        srcDirs = nub $ srcDir : hsSourceDirs bi ++ mLibSrcDirs
    info verbosity $ "Source directories: " ++ show srcDirs
    flip mapM_ mods $ \ m -> do
        fs <- findFileWithExtension suffixes srcDirs (ModuleName.toFilePath m)
        case fs of
          Nothing ->
            die ("can't find source for module " ++ display m)
          Just srcFile -> do
            let ext = takeExtension srcFile
            copyModule verbosity useCpp bi lbi srcFile
                (destDir </> ModuleName.toFilePath m <.> ext)
    -- Pass 2: compile foreign stubs in scratch directory
    stubsFileLists <- fmap catMaybes $ sequence
      [ findFileWithExtension suffixes [destDir] (ModuleName.toFilePath modu)
      | modu <- mods]
    compileFiles verbosity bi lbi destDir stubsFileLists