module Language.ATS.Package.Build.C ( clibSetup , cpkgHome , allSubdirs ) where import Development.Shake.ATS import Development.Shake.C import GHC.Conc import Quaalude cpkgHome :: CCompiler -> IO FilePath cpkgHome cc' = getAppUserDataDirectory ("atspkg" ccToDir cc') allSubdirs :: FilePath -> IO [FilePath] allSubdirs [] = pure mempty allSubdirs d = do d' <- listDirectory d let d'' = (d ) <$> d' ds <- filterM doesDirectoryExist d'' ds' <- traverse allSubdirs ds pure $ join (ds : ds') ccForConfig :: CCompiler -> String ccForConfig = g . ccToString where g "icc" = "cc" g x = x makeExecutable' :: FilePath -> [FilePath] -> IO () makeExecutable' file dirs = do p <- findFile dirs file fold (makeExecutable <$> p) clibSetup :: Verbosity -- ^ Shake verbosity level -> CCompiler -- ^ C compiler -> String -- ^ Library name -> FilePath -- ^ Filepath to unpack to -> IO () clibSetup v cc' lib' p = do -- Find configure script and make it executable subdirs <- allSubdirs p configurePath <- findFile (p:subdirs) "configure" cmakeLists <- findFile (p:subdirs) "CMakeLists.txt" fold (makeExecutable <$> configurePath) makeExecutable' "install-sh" (p:subdirs) -- Set environment variables for configure script h <- cpkgHome cc' let procEnv = Just [("CC", ccForConfig cc'), ("CFLAGS" :: String, "-I" <> h "include -Wno-error -O2"), ("PATH", "/usr/bin:/bin")] biaxe [fold (configure v h <$> configurePath <*> pure procEnv), cmake v h cmakeLists, make v, install v] lib' p cmake :: Verbosity -> FilePath -> Maybe FilePath -> String -> FilePath -> IO () cmake _ _ Nothing _ _ = mempty cmake v prefixPath (Just cfgLists) _ _ = do let p = takeDirectory cfgLists silentCreateProcess v ((proc "cmake" ["-DCMAKE_INSTALL_PREFIX:PATH=" ++ prefixPath, p]) { cwd = Just p }) configure :: Verbosity -> FilePath -> FilePath -> Maybe [(String, String)] -> String -> FilePath -> IO () configure v prefixPath configurePath procEnv lib' p = putStrLn ("configuring " ++ lib' ++ "...") *> silentCreateProcess v ((proc configurePath ["--prefix", prefixPath, "--host", host]) { cwd = Just p, env = procEnv }) findMakefile :: FilePath -> IO FilePath findMakefile p = do subdirs <- allSubdirs p mp <- findFile (p:subdirs) "Makefile" pure $ maybe p takeDirectory mp make :: Verbosity -> String -> FilePath -> IO () make v lib' p = do putStrLn ("building " ++ lib' ++ "...") p' <- findMakefile p cpus <- getNumCapabilities silentCreateProcess v ((proc makeExe ["-j" ++ show cpus]) { cwd = Just p' }) install :: Verbosity -> String -> FilePath -> IO () install v lib' p = do putStrLn ("installing " ++ lib' ++ "...") p' <- findMakefile p silentCreateProcess v ((proc makeExe ["install"]) { cwd = Just p' })