------------------------------------------------------------------------------- |-- Module : Distribution.System-- Copyright : Duncan Coutts 2007-2008---- Maintainer : cabal-devel@haskell.org-- Portability : portable---- Cabal often needs to do slightly different things on specific platforms. You-- probably know about the 'System.Info.os' however using that is very-- inconvenient because it is a string and different Haskell implementations-- do not agree on using the same strings for the same platforms! (In-- particular see the controversy over \"windows\" vs \"ming32\"). So to make it-- more consistent and easy to use we have an 'OS' enumeration.--moduleDistribution.System(-- * Operating SystemOS(..),buildOS,-- * Machine ArchitectureArch(..),buildArch,-- * Platform is a pair of arch and OSPlatform(..),buildPlatform,)whereimportqualifiedSystem.Info(os,arch)importqualifiedData.CharasChar(toLower,isAlphaNum)importDistribution.Text(Text(..),display)importqualifiedDistribution.Compat.ReadPasParseimportqualifiedText.PrettyPrintasDispimportText.PrettyPrint((<>))-- | How strict to be when classifying strings into the 'OS' and 'Arch' enums.---- The reason we have multiple ways to do the classification is because there-- are two situations where we need to do it.---- For parsing os and arch names in .cabal files we really want everyone to be-- referring to the same or or arch by the same name. Variety is not a virtue-- in this case. We don't mind about case though.---- For the System.Info.os\/arch different Haskell implementations use different-- names for the same or\/arch. Also they tend to distinguish versions of an-- os\/arch which we just don't care about.---- The 'Compat' classification allows us to recognise aliases that are already-- in common use but it allows us to distinguish them from the canonical name-- which enables us to warn about such deprecated aliases.--dataClassificationStrictness=Permissive|Compat|Strict-- -------------------------------------------------------------- * Operating System-- ------------------------------------------------------------dataOS=Linux|Windows|OSX-- teir 1 desktop OSs|FreeBSD|OpenBSD|NetBSD-- other free unix OSs|Solaris|AIX|HPUX|IRIX-- ageing Unix OSs|HaLVM-- bare metal / VMs / hypervisors|OtherOSStringderiving(Eq,Ord,Show,Read)--TODO: decide how to handle Android and iOS.-- They are like Linux and OSX but with some differences.-- Should they be separate from linux/osx, or a subtype?-- e.g. should we have os(linux) && os(android) true simultaneously?knownOSs::[OS]knownOSs=[Linux,Windows,OSX,FreeBSD,OpenBSD,NetBSD,Solaris,AIX,HPUX,IRIX,HaLVM]osAliases::ClassificationStrictness->OS->[String]osAliasesPermissiveWindows=["mingw32","cygwin32"]osAliasesCompatWindows=["mingw32","win32"]osAliases_OSX=["darwin"]osAliasesPermissiveFreeBSD=["kfreebsdgnu"]osAliasesPermissiveSolaris=["solaris2"]osAliases__=[]instanceTextOSwheredisp(OtherOSname)=Disp.textnamedispother=Disp.text(lowercase(showother))parse=fmap(classifyOSCompat)identclassifyOS::ClassificationStrictness->String->OSclassifyOSstrictnesss=caselookup(lowercases)osMapofJustos->osNothing->OtherOSswhereosMap=[(name,os)|os<-knownOSs,name<-displayos:osAliasesstrictnessos]buildOS::OSbuildOS=classifyOSPermissiveSystem.Info.os-- -------------------------------------------------------------- * Machine Architecture-- ------------------------------------------------------------dataArch=I386|X86_64|PPC|PPC64|Sparc|Arm|Mips|SH|IA64|S390|Alpha|Hppa|Rs6000|M68k|Vax|OtherArchStringderiving(Eq,Ord,Show,Read)knownArches::[Arch]knownArches=[I386,X86_64,PPC,PPC64,Sparc,Arm,Mips,SH,IA64,S390,Alpha,Hppa,Rs6000,M68k,Vax]archAliases::ClassificationStrictness->Arch->[String]archAliasesStrict_=[]archAliasesCompat_=[]archAliases_PPC=["powerpc"]archAliases_PPC64=["powerpc64"]archAliases_Sparc=["sparc64","sun4"]archAliases_Mips=["mipsel","mipseb"]archAliases_Arm=["armeb","armel"]archAliases__=[]instanceTextArchwheredisp(OtherArchname)=Disp.textnamedispother=Disp.text(lowercase(showother))parse=fmap(classifyArchStrict)identclassifyArch::ClassificationStrictness->String->ArchclassifyArchstrictnesss=caselookup(lowercases)archMapofJustarch->archNothing->OtherArchswherearchMap=[(name,arch)|arch<-knownArches,name<-displayarch:archAliasesstrictnessarch]buildArch::ArchbuildArch=classifyArchPermissiveSystem.Info.arch-- -------------------------------------------------------------- * Platform-- ------------------------------------------------------------dataPlatform=PlatformArchOSderiving(Eq,Ord,Show,Read)instanceTextPlatformwheredisp(Platformarchos)=disparch<>Disp.char'-'<>disposparse=doarch<-parse_<-Parse.char'-'os<-parsereturn(Platformarchos)buildPlatform::PlatformbuildPlatform=PlatformbuildArchbuildOS-- Utils:ident::Parse.ReadPrStringident=Parse.munch1(\c->Char.isAlphaNumc||c=='_'||c=='-')--TODO: probably should disallow starting with a numberlowercase::String->Stringlowercase=mapChar.toLower