aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/src/Build.hs
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap/src/Build.hs')
-rw-r--r--bootstrap/src/Build.hs239
1 files changed, 0 insertions, 239 deletions
diff --git a/bootstrap/src/Build.hs b/bootstrap/src/Build.hs
deleted file mode 100644
index 724a1c6..0000000
--- a/bootstrap/src/Build.hs
+++ /dev/null
@@ -1,239 +0,0 @@
-{-# LANGUAGE MultiWayIf #-}
-module Build
- ( CompilerSettings(..)
- , buildLibrary
- , buildProgram
- , buildWithScript
- )
-where
-
-import BuildModel ( AvailableModule(..)
- , CompileTimeInfo(..)
- , RawSource(..)
- , Source(..)
- , constructCompileTimeInfo
- , getAllObjectFiles
- , getAvailableModules
- , getSourceFileName
- , processRawSource
- )
-import Data.List ( intercalate
- , isSuffixOf
- )
-import Data.List.Utils ( replace )
-import Development.Shake ( FilePattern
- , Change(ChangeModtimeAndDigest)
- , cmd
- , getDirectoryFilesIO
- , liftIO
- , need
- , progressSimple
- , shake
- , shakeChange
- , shakeColor
- , shakeFiles
- , shakeOptions
- , shakeProgress
- , shakeThreads
- , want
- , (<//>)
- , (%>)
- , (&?>)
- )
-import Development.Shake.FilePath ( exe
- , splitDirectories
- , (</>)
- , (<.>)
- )
-import System.Environment ( setEnv )
-import System.FilePath ( takeBaseName )
-import System.Process ( system )
-import System.Directory ( createDirectoryIfMissing
- , makeAbsolute
- , withCurrentDirectory
- )
-
-data CompilerSettings = CompilerSettings {
- compilerSettingsCompiler :: FilePath
- , compilerSettingsFlags :: [String]
- , compilerSettingsModuleFlag :: String
- , compilerSettingsIncludeFlag :: String
-}
-
-buildProgram
- :: FilePath
- -> [FilePath]
- -> [FilePattern]
- -> FilePath
- -> CompilerSettings
- -> String
- -> FilePath
- -> [FilePath]
- -> IO ()
-buildProgram programDirectory' libraryDirectories sourceExtensions buildDirectory' (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) programName programSource archives
- = do
- libraryModules <- findAvailableModules libraryDirectories
- let programDirectory = foldl1 (</>) (splitDirectories programDirectory')
- let buildDirectory = foldl1 (</>) (splitDirectories buildDirectory')
- let includeFlags = (includeFlag ++ buildDirectory) : map (includeFlag ++) libraryDirectories
- sourceFiles <- getDirectoriesFiles [programDirectory] sourceExtensions
- rawSources <- mapM sourceFileToRawSource sourceFiles
- let sources' = map processRawSource rawSources
- let isThisProgramOrNotProgram p@(Program{}) =
- programSourceFileName p == programDirectory </> programSource
- isThisProgramOrNotProgram _ = True
- let sources = filter isThisProgramOrNotProgram sources'
- let availableModules = (getAvailableModules sources buildDirectory) ++ libraryModules
- let compileTimeInfo = map
- (\s -> constructCompileTimeInfo s availableModules buildDirectory)
- sources
- let objectFiles = getAllObjectFiles buildDirectory sources
- shake shakeOptions { shakeFiles = buildDirectory
- , shakeChange = ChangeModtimeAndDigest
- , shakeColor = True
- , shakeThreads = 0
- , shakeProgress = progressSimple
- }
- $ do
- let infoToRule cti =
- let obj = compileTimeInfoObjectFileProduced cti
- other = compileTimeInfoOtherFilesProduced cti
- directDependencies = compileTimeInfoDirectDependencies cti
- sourceFile = compileTimeInfoSourceFileName cti
- fileMatcher f =
- let realf = foldl1 (</>) (splitDirectories f)
- in if realf == obj || realf `elem` other
- then Just (obj : other)
- else Nothing
- in fileMatcher &?> \(objectFile : _) -> do
- need (sourceFile : directDependencies)
- cmd compiler
- ["-c", moduleFlag, buildDirectory]
- includeFlags
- flags
- ["-o", objectFile, sourceFile]
- want [buildDirectory </> programName <.> exe]
- buildDirectory </> programName <.> exe %> \executable -> do
- need objectFiles
- need archives
- cmd compiler objectFiles archives ["-o", executable] flags
- mapM_ infoToRule compileTimeInfo
-
-buildLibrary
- :: FilePath
- -> [FilePattern]
- -> FilePath
- -> CompilerSettings
- -> String
- -> [FilePath]
- -> IO (FilePath)
-buildLibrary libraryDirectory sourceExtensions buildDirectory (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) libraryName otherLibraryDirectories
- = do
- otherModules <- findAvailableModules otherLibraryDirectories
- let includeFlags = (includeFlag ++ buildDirectory) : map (includeFlag ++) otherLibraryDirectories
- sourceFiles <- getDirectoriesFiles [libraryDirectory] sourceExtensions
- rawSources <- mapM sourceFileToRawSource sourceFiles
- let sources = map processRawSource rawSources
- let availableModules = (getAvailableModules sources buildDirectory) ++ otherModules
- let compileTimeInfo = map
- (\s -> constructCompileTimeInfo s availableModules buildDirectory)
- sources
- let objectFiles = getAllObjectFiles buildDirectory sources
- let archiveFile = buildDirectory </> "lib" ++ libraryName <.> "a"
- shake shakeOptions { shakeFiles = buildDirectory
- , shakeChange = ChangeModtimeAndDigest
- , shakeColor = True
- , shakeThreads = 0
- , shakeProgress = progressSimple
- }
- $ do
- let infoToRule cti =
- let obj = compileTimeInfoObjectFileProduced cti
- other = compileTimeInfoOtherFilesProduced cti
- directDependencies = compileTimeInfoDirectDependencies cti
- sourceFile = compileTimeInfoSourceFileName cti
- fileMatcher f =
- let realf = foldl1 (</>) (splitDirectories f)
- in if realf == obj || realf `elem` other
- then Just (obj : other)
- else Nothing
- in fileMatcher &?> \(objectFile : _) -> do
- need (sourceFile : directDependencies)
- cmd compiler
- ["-c", moduleFlag, buildDirectory]
- includeFlags
- flags
- ["-o", objectFile, sourceFile]
- want [archiveFile]
- archiveFile %> \a -> do
- need objectFiles
- cmd "ar" ["rs"] a objectFiles
- mapM_ infoToRule compileTimeInfo
- return archiveFile
-
-buildWithScript
- :: String
- -> FilePath
- -> FilePath
- -> CompilerSettings
- -> String
- -> [FilePath]
- -> IO (FilePath)
-buildWithScript script projectDirectory buildDirectory (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) libraryName otherLibraryDirectories
- = do
- absoluteBuildDirectory <- makeAbsolute buildDirectory
- createDirectoryIfMissing True absoluteBuildDirectory
- absoluteLibraryDirectories <- mapM makeAbsolute otherLibraryDirectories
- setEnv "FC" compiler
- setEnv "FFLAGS" (intercalate " " flags)
- setEnv "FINCLUDEFLAG" includeFlag
- setEnv "FMODUELFLAG" moduleFlag
- setEnv "BUILD_DIR" $ unWindowsPath absoluteBuildDirectory
- setEnv "INCLUDE_DIRS"
- (intercalate " " (map unWindowsPath absoluteLibraryDirectories))
- let archiveFile =
- (unWindowsPath absoluteBuildDirectory)
- ++ "/lib"
- ++ libraryName
- <.> "a"
- withCurrentDirectory
- projectDirectory
- if
- | isMakefile script -> system
- ("make -f " ++ script ++ " " ++ archiveFile)
- | otherwise -> system (script ++ " " ++ archiveFile)
- return archiveFile
-
--- A little wrapper around getDirectoryFiles so we can get files from multiple directories
-getDirectoriesFiles :: [FilePath] -> [FilePattern] -> IO [FilePath]
-getDirectoriesFiles dirs exts = getDirectoryFilesIO "" newPatterns
- where
- newPatterns = concatMap appendExts dirs
- appendExts dir = map ((dir <//> "*") ++) exts
-
-sourceFileToRawSource :: FilePath -> IO RawSource
-sourceFileToRawSource sourceFile = do
- contents <- readFile sourceFile
- return $ RawSource sourceFile contents
-
-isMakefile :: String -> Bool
-isMakefile script | script == "Makefile" = True
- | script == "makefile" = True
- | ".mk" `isSuffixOf` script = True
- | otherwise = False
-
-unWindowsPath :: String -> String
-unWindowsPath = changeSeparators . removeDriveLetter
-
-removeDriveLetter :: String -> String
-removeDriveLetter path | ':' `elem` path = (tail . dropWhile (/= ':')) path
- | otherwise = path
-
-changeSeparators :: String -> String
-changeSeparators = replace "\\" "/"
-
-findAvailableModules :: [FilePath] -> IO [AvailableModule]
-findAvailableModules directories = do
- moduleFiles <- getDirectoriesFiles directories ["*.mod"]
- let availableModules = map (\mf -> AvailableModule { availableModuleName = takeBaseName mf, availableModuleFile = mf }) moduleFiles
- return availableModules