aboutsummaryrefslogtreecommitdiff
path: root/app/Main.hs
diff options
context:
space:
mode:
Diffstat (limited to 'app/Main.hs')
-rw-r--r--app/Main.hs294
1 files changed, 3 insertions, 291 deletions
diff --git a/app/Main.hs b/app/Main.hs
index 38ba8f1..4897901 100644
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,296 +1,8 @@
-{-# LANGUAGE OverloadedStrings #-}
-
module Main where
-import Build ( buildLibrary
- , buildProgram
- )
-import qualified Data.Text.IO as TIO
-import Development.Shake ( FilePattern
- , (<//>)
- , getDirectoryFilesIO
- )
-import Development.Shake.FilePath ( (</>) )
-import Options.Applicative ( Parser
- , (<**>)
- , command
- , execParser
- , fullDesc
- , header
- , help
- , helper
- , info
- , long
- , progDesc
- , subparser
- , switch
- )
-import System.Directory ( doesDirectoryExist
- , doesFileExist
+import Fpm ( getArguments
+ , start
)
-import System.Process ( runCommand )
-import Toml ( TomlCodec
- , (.=)
- )
-import qualified Toml
-
-data Arguments = Arguments { command' :: Command, release :: Bool }
-
-data TomlSettings = TomlSettings {
- tomlSettingsCompiler :: String
- , tomlSettingsProjectName :: String
- , tomlSettingsLibrary :: (Maybe Library)
- , tomlSettingsExecutables :: [Executable]
- , tomlSettingsTests :: [Executable]
-}
-
-data AppSettings = AppSettings {
- appSettingsCompiler :: String
- , appSettingsProjectName :: String
- , appSettingsBuildPrefix :: String
- , appSettingsFlags :: [String]
- , appSettingsLibrary :: (Maybe Library)
- , appSettingsExecutables :: [Executable]
- , appSettingsTests :: [Executable]
-}
-
-data Library = Library { librarySourceDir :: String }
-
-data Executable = Executable {
- executableSourceDir :: String
- , executableMainFile :: String
- , executableName :: String
-}
-
-data Command = Run | Test | Build
main :: IO ()
-main = do
- args <- getArguments
- fpmContents <- TIO.readFile "fpm.toml"
- let tomlSettings = Toml.decode settingsCodec fpmContents
- case tomlSettings of
- Left err -> print err
- Right tomlSettings' -> do
- appSettings <- toml2AppSettings tomlSettings' (release args)
- app args appSettings
-
-app :: Arguments -> AppSettings -> IO ()
-app args settings = case command' args of
- Build -> build settings
- Run -> do
- build settings
- let buildPrefix = appSettingsBuildPrefix settings
- let
- executableNames = map
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- sourceDir </> name
- )
- (appSettingsExecutables settings)
- let executables = map (buildPrefix </>) executableNames
- mapM_ runCommand executables
- Test -> do
- build settings
- let buildPrefix = appSettingsBuildPrefix settings
- let
- executableNames = map
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- sourceDir </> name
- )
- (appSettingsTests settings)
- let executables = map (buildPrefix </>) executableNames
- mapM_ runCommand executables
-
-build :: AppSettings -> IO ()
-build settings = do
- let compiler = appSettingsCompiler settings
- let projectName = appSettingsProjectName settings
- let buildPrefix = appSettingsBuildPrefix settings
- let flags = appSettingsFlags settings
- let executables = appSettingsExecutables settings
- let tests = appSettingsTests settings
- executableDepends <- case appSettingsLibrary settings of
- Just librarySettings -> do
- let librarySourceDir' = librarySourceDir librarySettings
- buildLibrary librarySourceDir'
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> "library")
- compiler
- flags
- projectName
- []
- return [buildPrefix </> "library"]
- Nothing -> do
- return []
- mapM_
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- do
- buildProgram sourceDir
- executableDepends
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> sourceDir)
- compiler
- flags
- name
- mainFile
- )
- executables
- mapM_
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- do
- buildProgram sourceDir
- executableDepends
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> sourceDir)
- compiler
- flags
- name
- mainFile
- )
- tests
-
-getArguments :: IO Arguments
-getArguments = execParser
- (info
- (arguments <**> helper)
- (fullDesc <> progDesc "Work with Fortran projects" <> header
- "fpm - A Fortran package manager and build system"
- )
- )
-
-arguments :: Parser Arguments
-arguments =
- Arguments
- <$> subparser
- ( command "run" (info runArguments (progDesc "Run the executable"))
- <> command "test" (info testArguments (progDesc "Run the tests"))
- <> command "build"
- (info buildArguments (progDesc "Build the executable"))
- )
- <*> switch (long "release" <> help "Build in release mode")
-
-runArguments :: Parser Command
-runArguments = pure Run
-
-testArguments :: Parser Command
-testArguments = pure Test
-
-buildArguments :: Parser Command
-buildArguments = pure Build
-
-getDirectoriesFiles :: [FilePath] -> [FilePattern] -> IO [FilePath]
-getDirectoriesFiles dirs exts = getDirectoryFilesIO "" newPatterns
- where
- newPatterns = concatMap appendExts dirs
- appendExts dir = map ((dir <//> "*") ++) exts
-
-settingsCodec :: TomlCodec TomlSettings
-settingsCodec =
- TomlSettings
- <$> Toml.string "compiler"
- .= tomlSettingsCompiler
- <*> Toml.string "name"
- .= tomlSettingsProjectName
- <*> Toml.dioptional (Toml.table libraryCodec "library")
- .= tomlSettingsLibrary
- <*> Toml.list executableCodec "executable"
- .= tomlSettingsExecutables
- <*> Toml.list executableCodec "test"
- .= tomlSettingsTests
-
-libraryCodec :: TomlCodec Library
-libraryCodec = Library <$> Toml.string "source-dir" .= librarySourceDir
-
-executableCodec :: TomlCodec Executable
-executableCodec =
- Executable
- <$> Toml.string "source-dir"
- .= executableSourceDir
- <*> Toml.string "main"
- .= executableMainFile
- <*> Toml.string "name"
- .= executableName
-
-toml2AppSettings :: TomlSettings -> Bool -> IO AppSettings
-toml2AppSettings tomlSettings release = do
- let projectName = tomlSettingsProjectName tomlSettings
- librarySettings <- getLibrarySettings $ tomlSettingsLibrary tomlSettings
- executableSettings <- getExecutableSettings
- (tomlSettingsExecutables tomlSettings)
- projectName
- testSettings <- getTestSettings $ tomlSettingsTests tomlSettings
- return AppSettings
- { appSettingsCompiler = tomlSettingsCompiler tomlSettings
- , appSettingsProjectName = projectName
- , appSettingsBuildPrefix = "build"
- </> if release then "release" else "debug"
- , appSettingsFlags = if release
- then
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-O3"
- , "-march=native"
- , "-ffast-math"
- , "-funroll-loops"
- ]
- else
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-g"
- , "-fbounds-check"
- , "-fcheck-array-temporaries"
- , "-fbacktrace"
- ]
- , appSettingsLibrary = librarySettings
- , appSettingsExecutables = executableSettings
- , appSettingsTests = testSettings
- }
-
-getLibrarySettings :: Maybe Library -> IO (Maybe Library)
-getLibrarySettings maybeSettings = case maybeSettings of
- Just settings -> return maybeSettings
- Nothing -> do
- defaultExists <- doesDirectoryExist "src"
- if defaultExists
- then return (Just (Library { librarySourceDir = "src" }))
- else return Nothing
-
-getExecutableSettings :: [Executable] -> String -> IO [Executable]
-getExecutableSettings [] projectName = do
- defaultDirectoryExists <- doesDirectoryExist "app"
- if defaultDirectoryExists
- then do
- defaultMainExists <- doesFileExist ("app" </> "main.f90")
- if defaultMainExists
- then return
- [ Executable { executableSourceDir = "app"
- , executableMainFile = "main.f90"
- , executableName = projectName
- }
- ]
- else return []
- else return []
-getExecutableSettings executables _ = return executables
-
-getTestSettings :: [Executable] -> IO [Executable]
-getTestSettings [] = do
- defaultDirectoryExists <- doesDirectoryExist "test"
- if defaultDirectoryExists
- then do
- defaultMainExists <- doesFileExist ("test" </> "main.f90")
- if defaultMainExists
- then return
- [ Executable { executableSourceDir = "test"
- , executableMainFile = "main.f90"
- , executableName = "runTests"
- }
- ]
- else return []
- else return []
-getTestSettings tests = return tests
+main = getArguments >>= start