[add support for targets.ini to options, use options specified in ini file when possible
John Meacham <john@repetae.net>**20090622230925
 Ignore-this: 5c3751c1499d4ca24aa152fef7c68a85
] hunk ./C/Arch.hs 124
-    let specs = maybe [] (split (== '-')) (optArch options)
+    let specs = maybe [] (split (== '-')) (Just "") -- (optArch options)
hunk ./FlagDump.flags 10
+ini all ini configuration options
hunk ./Grin/Show.hs 20
-import Data.Graph.Inductive.Graph(mkGraph,nmap)
+import Data.Graph.Inductive.Graph(mkGraph)
hunk ./Main.hs 530
-    prog <- if (fopts FO.TypeAnalysis) then do 
+    prog <- if (fopts FO.TypeAnalysis) then do
hunk ./Main.hs 785
+    let lup k = maybe "" id $ Map.lookup k (optInis options)
hunk ./Main.hs 789
-        boehmOpts | fopts FO.Boehm = ["-D_JHC_GC=2", "-lgc"]
+        boehmOpts | fopts FO.Boehm || lup "gc" == "boehm"  = ["-D_JHC_GC=2", "-lgc"]
hunk ./Main.hs 791
-        profileOpts | fopts FO.Profile = ["-D_JHC_PROFILE=1"]
-                  | otherwise = []
-        comm = shellQuote $ [optCC options, "-std=gnu99", "-D_GNU_SOURCE", "-falign-functions=4", "-ffast-math"
-                            , "-Wshadow", "-Wextra", "-Wall", "-Wno-unused-parameter", "-o", fn, cf ] ++
+        profileOpts | fopts FO.Profile || lup "profile" == "true" = ["-D_JHC_PROFILE=1"]
+                    | otherwise = []
+        comm = shellQuote $ [lup "cc"] ++ words (lup "cflags") ++ ["-o", fn, cf] ++
hunk ./Main.hs 795
-        debug = if fopts FO.Debug then ["-g"] else ["-DNDEBUG", "-O3", "-fomit-frame-pointer"]
+        debug = if fopts FO.Debug then words (lup "cflags_debug") else words (lup "cflags_nodebug")
hunk ./Options.hs 30
+import qualified Data.Map as M
hunk ./Options.hs 36
+import Support.IniParse
hunk ./Options.hs 43
+
+{-@Cross Compilation
+
+# Basics
+
+Unlike many other compilers, jhc is a native cross compiler. What this means is
+that every compile of jhc is able to create code for all possible target
+systems. This leads to many simplifications when it comes to cross compiling
+with jhc. Basically in order to cross compile, you need only pass the flag
+'--cross' to jhc, and pass an appropriate '-m' option to tell jhc what machine
+you are targetting. The targets list is extensible at run-time via the
+targets.ini file explained below.
+
+# targets.ini
+
+This file determines what targets are available. The format consists of entries as follows.
+
+  [targetname]
+  key1=value
+  key2=value
+  key3+=value
+  merge=targetname2
+
+merge is a special key meaning to merge the contents of another target into the
+current one. The configuration file is read in order, and the final value set
+for a given key is the one that is used.
+
+An example describing how to cross compile for windows is as follows:
+
+  [win32]
+  gcc=i386-mingw32-gcc
+  cflags+=-mwindows -mno-cygwin
+  executable_extension=.exe
+  merge=i686
+
+This sets the compiler to use as well as a few other options then jumps to the
+generic i686 routine. The special target [default] is always read before all
+other targets. If '--cross' is specified on the command line then this is the
+only implicitly included configuration, otherwise jhc will assume you are
+compiling for the current architecture and choose an appropriate target to
+include in addition to default.
+
+jhc will attempt to read several targets.ini files in order. they are 
+
+<installprefix>/etc/jhc-<version>/targets.ini 
+: this is the targets.ini that is included with jhc and contains the default options.
+
+<installprefix>/etc/jhc-<version>/targets-local.ini 
+: jhc will read this if it exists, it is used to specify custom system wide configuration options, such as the name of local compilers.
+
+$HOME/.jhc/targets.ini
+: this is where a users local configuration information goes.
+
+$HOME/etc/jhc/targets.ini
+: this is simply for people that prefer to not use hidden directories for configuration
+
+The last value specified for an option is the one used, so a users local
+configuration overrides the system local version which overrides the built in
+options.
+
+# Options available
+
+cc
+: what c compiler to use. generally this will be gcc for local builds and <arch>-<os>-gcc for cross compiles
+
+byteorder
+: one of le or be for little or big endian
+
+gc
+: what garbage collector to use. It should be one of 'static' or 'boehm'.
+
+cflags
+: options to pass to the c compiler
+
+cflags_debug
+: options to pass to the c compiler only when debugging is enabled
+
+cflags_nodebug
+: options to pass to the c compiler only when debugging is disabled
+
+profile
+: whether to include profiling code in the generated executable
+
+autoload
+: what haskell libraries to autoload, seperated by commas.
+
+executable_extension
+: specifies an extension that should be appended to executable files, (i.e. .EXE on windows)
+
+merge
+: a special option that merges the contents of another configuration target into the currrent one.
+
+bits:
+: the number of bits a pointer contains on this architecture
+
+bits_max
+: the number of bits in the largest integral type. should be the number of bits in the 'intmax_t' C type.
+
+arch
+: what to pass to gcc as the architecture
+
+-}
+
hunk ./Options.hs 184
-    optArch        ::  Maybe String,           -- ^ target architecture
+    optArch        ::  [String],           -- ^ target architecture
+    optCross       ::  Bool,
hunk ./Options.hs 194
+    optInis        ::  M.Map String String,    -- ^ options read from ini files
hunk ./Options.hs 204
+    optCross       = False,
hunk ./Options.hs 224
-    optArch        = Nothing,
+    optArch        = ["default"],
hunk ./Options.hs 253
-    , Option []    ["progc"]     (ReqArg (\d -> optCC_s d) "gcc")      "c compiler to use"
-    , Option []    ["arg"]       (ReqArg (\d -> optProgArgs_u (++ [d])) "arg") "arguments to pass interpreted program"
+--    , Option []    ["progc"]     (ReqArg (\d -> optCC_s d) "gcc")      "c compiler to use"
+--    , Option []    ["arg"]       (ReqArg (\d -> optProgArgs_u (++ [d])) "arg") "arguments to pass interpreted program"
hunk ./Options.hs 258
-    , Option []    ["interpret"] (NoArg  (optMode_s Interpret))        "interpret"
+ --   , Option []    ["interpret"] (NoArg  (optMode_s Interpret))        "interpret"
hunk ./Options.hs 260
+    , Option []    ["cross"]     (NoArg  (optCross_s True))            "enable cross-compilation, choose target with the -m flag"
hunk ./Options.hs 263
-    , Option ['m'] ["arch"]      (ReqArg (optArch_s . Just ) "arch")            "target architecture"
+    , Option ['m'] ["arch"]      (ReqArg (optArch_u . idu ) "arch")      "target architecture options"
hunk ./Options.hs 343
+    Just home <- fmap (`mplus` Just "/") $ lookupEnv "HOME" 
+    inis <- parseIniFiles (optVerbose o2 > 0) ["data/targets.ini", confDir ++ "/targets.ini", confDir ++ "/targets-local.ini", home ++ "/etc/jhc/targets.ini", home ++ "/.jhc/targets.ini"] (optArch o2)
+    when (FlagDump.Ini `S.member` optDumpSet o2) $ flip mapM_ (M.toList inis) $ \(a,b) -> putStrLn (a ++ "=" ++ b)
+    let autoloads = maybe [] (tokens (',' ==)) (M.lookup "autoload" inis)
+        o3 = o2 { optArgs = ns, optInis = inis }
hunk ./Options.hs 349
-      True -> return (o2 { optArgs = ns })
-      False-> return (o2 { optArgs = ns, optHls  = ("base":"haskell98":optHls o2) })
+      True -> return o3
+      False-> return o3 {  optHls  = (autoloads ++ optHls o2) }
hunk ./Options.hs 412
+