git.iko.soy/typeable/cabal2nix
on master help sign in
Merge pull request #344 from obsidiansystems/parse-platform
17e0b6cPeter Simons
src/Cabal2nix.hs+51−16
@@ -1,5 +1,6 @@
1−{-# LANGUAGE RecordWildCards #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
3
4
4module Cabal2nix
5module Cabal2nix
5 ( main, cabal2nix, cabal2nix', cabal2nixWithDB
6 ( main, cabal2nix, cabal2nix', cabal2nixWithDB
@@ -9,7 +10,9 @@ module Cabal2nix
9import Control.Exception ( bracket )
10import Control.Exception ( bracket )
10import Control.Lens
11import Control.Lens
11import Control.Monad ( when )
12import Control.Monad ( when )
13+import Data.List
14+import Data.List.Split
12−import Data.Maybe ( fromMaybe, isJust )
15+import Data.Maybe ( fromMaybe, isJust, listToMaybe )
13import Data.Monoid ( (<>) )
16import Data.Monoid ( (<>) )
14import qualified Data.Set as Set
17import qualified Data.Set as Set
15import Data.String
18import Data.String
@@ -81,7 +84,7 @@ options = Options
81 <*> switch (long "shell" <> help "generate output suitable for nix-shell")
84 <*> switch (long "shell" <> help "generate output suitable for nix-shell")
82 <*> many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)")
85 <*> many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)")
83 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
86 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
84− <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
87+ <*> option (maybeReader parsePlatform) (long "system" <> help "host system (in either short Nix format or full LLVM style) to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
85 <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")
88 <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")
86 <*> optional (option utcTimeReader (long "hackage-snapshot" <> help "hackage snapshot time, ISO format"))
89 <*> optional (option utcTimeReader (long "hackage-snapshot" <> help "hackage snapshot time, ISO format"))
87 <*> strArgument (metavar "URI")
90 <*> strArgument (metavar "URI")
@@ -99,19 +102,51 @@ readP p = eitherReader $ \s -> case [ r' | (r',"") <- P.readP_to_S p s ] of
99 (r:_) -> Right r
102 (r:_) -> Right r
100 _ -> Left ("invalid value " ++ show s)
103 _ -> Left ("invalid value " ++ show s)
101
104
102−parsePlatform :: P.ReadP r Platform
105+-- | Replicate the normalization performed by GHC_CONVERT_CPU in GHC's aclocal.m4
103−parsePlatform = do arch <- P.choice [ P.string "i686" >> return I386
106+-- since the output of that is what Cabal parses.
104− , P.string "x86_64" >> return X86_64
107+ghcConvertArch :: String -> String
105− , P.string "armv7l" >> return Arm
108+ghcConvertArch arch = case arch of
106− , P.string "armv6l" >> return Arm
109+ "i486" -> "i386"
107− -- Not yet supported yet, see Cabal #5221
110+ "i586" -> "i386"
108− --, P.string "aarch64" >> return AArch64
111+ "i686" -> "i386"
109− , P.string "mipsel" >> return Mips
112+ "amd64" -> "x86_64"
113+ _ -> fromMaybe arch $ listToMaybe
114+ [prefix | prefix <- archPrefixes, prefix `isPrefixOf` arch]
115+ where archPrefixes =
116+ [ "aarch64", "alpha", "arm", "hppa1_1", "hppa", "m68k", "mipseb"
117+ , "mipsel", "mips", "powerpc64le", "powerpc64", "powerpc", "s390x"
118+ , "sparc64", "sparc"
110− ]
119+ ]
111− _ <- P.char '-'
120+
112− os <- P.choice [ P.string "linux" >> return Linux, P.string "darwin" >> return OSX
121+-- | Replicate the normalization performed by GHC_CONVERT_OS in GHC's aclocal.m4
113− , P.string "windows" >> return Windows]
122+-- since the output of that is what Cabal parses.
123+ghcConvertOS :: String -> String
124+ghcConvertOS os = case os of
125+ "watchos" -> "ios"
126+ "tvos" -> "ios"
127+ "linux-android" -> "linux-android"
128+ _ | "linux-" `isPrefixOf` os -> "linux"
129+ _ -> fromMaybe os $ listToMaybe
130+ [prefix | prefix <- osPrefixes, prefix `isPrefixOf` os]
131+ where osPrefixes =
132+ [ "gnu", "openbsd", "aix", "darwin", "solaris2", "freebsd", "nto-qnx"]
133+
134+parseArch :: String -> Arch
135+parseArch = classifyArch Permissive . ghcConvertArch
136+
137+parseOS :: String -> OS
138+parseOS = classifyOS Permissive . ghcConvertOS
139+
140+parsePlatform :: String -> Maybe Platform
141+parsePlatform = parsePlatformParts . splitOn "-"
142+
143+parsePlatformParts :: [String] -> Maybe Platform
144+parsePlatformParts = \case
145+ [arch, os] ->
114− return (Platform arch os)
146+ Just $ Platform (parseArch arch) (parseOS os)
147+ (arch : _ : osParts) ->
148+ Just $ Platform (parseArch arch) $ parseOS $ intercalate "-" osParts
149+ _ -> Nothing
115
150
116pinfo :: ParserInfo Options
151pinfo :: ParserInfo Options
117pinfo = info
152pinfo = info