[project @ 2002-06-12 22:04:25 by wolfgang]
authorwolfgang <unknown>
Wed, 12 Jun 2002 22:04:27 +0000 (22:04 +0000)
committerwolfgang <unknown>
Wed, 12 Jun 2002 22:04:27 +0000 (22:04 +0000)
Added support for Frameworks on MacOS X.
*) On MacOS X, two additional command-line options are supported:
-framework <FRAMEWORK>    link with framework, gets passed on to ld
-framework-path <PATH>    gets passed on to ld as "-F<PATH>". (-F is already taken for GHC).
*) Two corresponding additional options for package.conf files:
framework_dirs
extra_frameworks
These options are allowed on any platform. They are ignored everywhere except on MacOS X.
*) ghc-pkg no longer uses Read. Instead, it uses a Happy parser. ghc/utils/ghc-pkg/ParsePkgConfLite.y is basically a copy of ghc/compiler/main/ParsePkgConf.y. "Light" refers to the fact that it doesn't depend on other GHC modules and has less sophisticated error reporting.
*) Frameworks will need some additional work for GHCi.

ghc/compiler/ghci/InteractiveUI.hs
ghc/compiler/main/DriverFlags.hs
ghc/compiler/main/DriverPipeline.hs
ghc/compiler/main/DriverState.hs
ghc/compiler/main/Packages.lhs
ghc/compiler/main/ParsePkgConf.y
ghc/utils/ghc-pkg/Main.hs
ghc/utils/ghc-pkg/Package.hs
ghc/utils/ghc-pkg/ParsePkgConfLite.y [new file with mode: 0644]

index 162dfc2..8ec1362 100644 (file)
@@ -1,6 +1,6 @@
 {-# OPTIONS -#include "Linker.h" -#include "SchedAPI.h" #-}
 -----------------------------------------------------------------------------
--- $Id: InteractiveUI.hs,v 1.125 2002/06/04 18:09:00 sof Exp $
+-- $Id: InteractiveUI.hs,v 1.126 2002/06/12 22:04:25 wolfgang Exp $
 --
 -- GHC Interactive User Interface
 --
@@ -998,6 +998,9 @@ ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
 -- directories specified in v_Library_Paths before giving up.
 
 data LibrarySpec = Object FilePath | DLL String
+#ifdef darwin_TARGET_OS
+                   | Framework String
+#endif
 
 -- Packages that don't need loading, because the compiler shares them with
 -- the interpreted program.
@@ -1015,6 +1018,9 @@ loaded_in_ghci
 
 showLS (Object nm)  = "(static) " ++ nm
 showLS (DLL nm) = "(dynamic) " ++ nm
+#ifdef darwin_TARGET_OS
+showLS (Framework nm) = "(framework) " ++ nm
+#endif
 
 linkPackages :: DynFlags -> [LibrarySpec] -> [PackageConfig] -> IO ()
 linkPackages dflags cmdline_lib_specs pkgs
index e480c8a..e0196f2 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverFlags.hs,v 1.96 2002/06/03 23:36:40 sof Exp $
+-- $Id: DriverFlags.hs,v 1.97 2002/06/12 22:04:26 wolfgang Exp $
 --
 -- Driver flags
 --
@@ -263,6 +263,12 @@ static_flags =
   ,  ( "L"             , Prefix (addToDirList v_Library_paths) )
   ,  ( "l"             , Prefix (add v_Cmdline_libraries) )
 
+#ifdef darwin_TARGET_OS
+       ------- Frameworks --------------------------------------------------
+        -- -framework-path should really be -F ...
+  ,  ( "framework-path" , HasArg (addToDirList v_Framework_paths) )
+  ,  ( "framework"     , HasArg (add v_Cmdline_frameworks) )
+#endif
         ------- Packages ----------------------------------------------------
   ,  ( "package-name"   , HasArg (\s -> add v_Opt_C ("-inpackage="++s)) )
 
index b567817..8f70de4 100644 (file)
@@ -903,6 +903,21 @@ doLink o_files = do
     let lib_opts = map ("-l"++) (reverse libs)
         -- reverse because they're added in reverse order from the cmd line
 
+#ifdef darwin_TARGET_OS
+    pkg_framework_paths <- getPackageFrameworkPath
+    let pkg_framework_path_opts = map ("-F"++) pkg_framework_paths
+
+    framework_paths <- readIORef v_Framework_paths
+    let framework_path_opts = map ("-F"++) framework_paths
+
+    pkg_frameworks <- getPackageFrameworks
+    let pkg_framework_opts = map ("-framework " ++) pkg_frameworks
+
+    frameworks <- readIORef v_Cmdline_frameworks
+    let framework_opts = map ("-framework "++) (reverse frameworks)
+        -- reverse because they're added in reverse order from the cmd line
+#endif
+
     pkg_extra_ld_opts <- getPackageExtraLdOpts
 
        -- probably _stub.o files
@@ -930,8 +945,16 @@ doLink o_files = do
                      ++ extra_ld_inputs
                      ++ lib_path_opts
                      ++ lib_opts
+#ifdef darwin_TARGET_OS
+                     ++ framework_path_opts
+                     ++ framework_opts
+#endif
                      ++ pkg_lib_path_opts
                      ++ pkg_lib_opts
+#ifdef darwin_TARGET_OS
+                     ++ pkg_framework_path_opts
+                     ++ pkg_framework_opts
+#endif
                      ++ pkg_extra_ld_opts
                      ++ extra_ld_opts
                      ++ if static && not no_hs_main then
index 4045c9e..1b4a06b 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverState.hs,v 1.79 2002/06/04 19:17:57 sof Exp $
+-- $Id: DriverState.hs,v 1.80 2002/06/12 22:04:26 wolfgang Exp $
 --
 -- Settings for the driver
 --
@@ -379,6 +379,11 @@ GLOBAL_VAR(v_Library_paths, [],     [String])
 
 GLOBAL_VAR(v_Cmdline_libraries,   [], [String])
 
+#ifdef darwin_TARGET_OS
+GLOBAL_VAR(v_Framework_paths, [], [String])
+GLOBAL_VAR(v_Cmdline_frameworks, [], [String])
+#endif
+
 addToDirList :: IORef [String] -> String -> IO ()
 addToDirList ref path
   = do paths           <- readIORef ref
@@ -554,6 +559,18 @@ getPackageExtraLdOpts = do
   ps <- getPackageInfo
   return (concatMap extra_ld_opts ps)
 
+#ifdef darwin_TARGET_OS
+getPackageFrameworkPath  :: IO [String]
+getPackageFrameworkPath = do
+  ps <- getPackageInfo
+  return (nub (filter notNull (concatMap framework_dirs ps)))
+
+getPackageFrameworks  :: IO [String]
+getPackageFrameworks = do
+  ps <- getPackageInfo
+  return (concatMap extra_frameworks ps)
+#endif
+
 getPackageInfo :: IO [PackageConfig]
 getPackageInfo = do
   ps <- readIORef v_Packages
index 7c18904..43b96ec 100644 (file)
@@ -43,7 +43,8 @@ mungePackagePaths top_dir ps = map munge_pkg ps
  where 
   munge_pkg p = p{ import_dirs  = munge_paths (import_dirs p),
                   include_dirs = munge_paths (include_dirs p),
-                  library_dirs = munge_paths (library_dirs p) }
+                  library_dirs = munge_paths (library_dirs p),
+                  framework_dirs = munge_paths (framework_dirs p) }
 
   munge_paths = map munge_path
 
index 44611e7..fa83513 100644 (file)
@@ -63,6 +63,8 @@ field :: { PackageConfig -> PackageConfig }
                        "extra_ghc_opts"  -> p{extra_ghc_opts  = $3}
                        "extra_cc_opts"   -> p{extra_cc_opts   = $3}
                        "extra_ld_opts"   -> p{extra_ld_opts   = $3}
+                       "framework_dirs"  -> p{framework_dirs  = $3}
+                       "extra_frameworks"-> p{extra_frameworks= $3}
                        _other            -> p
                }
 
index 4583110..80a6c27 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: Main.hs,v 1.24 2002/06/03 10:27:11 simonmar Exp $
+-- $Id: Main.hs,v 1.25 2002/06/12 22:04:27 wolfgang Exp $
 --
 -- Package management tool
 -----------------------------------------------------------------------------
@@ -22,6 +22,8 @@ import System ( getEnv, getArgs,
 import IO
 import List ( isPrefixOf )
 
+import ParsePkgConfLite
+
 #include "../../includes/config.h"
 
 #ifdef mingw32_HOST_OS
@@ -105,12 +107,14 @@ runit clis = do
       toField "extra_ghc_opts"  = return extra_ghc_opts
       toField "extra_cc_opts"   = return extra_cc_opts
       toField "extra_ld_opts"   = return extra_ld_opts  
+      toField "framework_dirs"  = return framework_dirs  
+      toField "extra_frameworks"= return extra_frameworks  
       toField s                        = die ("unknown field: `" ++ s ++ "'")
 
   fields <- mapM toField [ f | Field f <- clis ]
 
   s <- readFile conf_file
-  let packages = read s :: [PackageConfig]
+  let packages = parsePackageConfig s
   eval_catch packages (\_ -> die "parse error in package config file")
 
   let auto_ghci_libs = any isAuto clis 
@@ -156,7 +160,7 @@ addPackage packages pkgconf inputFile auto_ghci_libs updatePkg force = do
       f   -> do
         hPutStr stdout ("Reading package info from " ++ show f)
        readFile f
-  let new_pkg = read s :: PackageConfig
+  let new_pkg = parseOnePackageConfig s
   eval_catch new_pkg (\_ -> die "parse error in package info")
   hPutStrLn stdout "done."
   hPutStr stdout "Expanding embedded variables..."
@@ -315,6 +319,8 @@ expandEnvVars pkg force = do
   e_g_opts <- expandStrings (extra_ghc_opts pkg)
   e_c_opts <- expandStrings (extra_cc_opts pkg)
   e_l_opts <- expandStrings (extra_ld_opts pkg)
+  f_dirs   <- expandStrings (framework_dirs pkg)
+  e_frames <- expandStrings (extra_frameworks pkg)
   return (pkg { name            = nm
              , import_dirs     = imp_dirs
              , source_dirs     = src_dirs
@@ -327,6 +333,8 @@ expandEnvVars pkg force = do
              , extra_ghc_opts  = e_g_opts
              , extra_cc_opts   = e_c_opts
              , extra_ld_opts   = e_l_opts
+             , framework_dirs  = f_dirs
+             , extra_frameworks= e_frames
              })
   where
    expandStrings = mapM expandString
index ae330ab..b4df186 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: Package.hs,v 1.2 2001/03/27 14:10:34 simonmar Exp $
+-- $Id: Package.hs,v 1.3 2002/06/12 22:04:27 wolfgang Exp $
 --
 -- Package configuration defn.
 -----------------------------------------------------------------------------
@@ -33,11 +33,10 @@ data PackageConfig
        package_deps    :: [String],
        extra_ghc_opts  :: [String],
        extra_cc_opts   :: [String],
-       extra_ld_opts   :: [String]
+       extra_ld_opts   :: [String],
+       framework_dirs  :: [String], -- ignored everywhere but on Darwin/MacOS X
+       extra_frameworks:: [String]  -- ignored everywhere but on Darwin/MacOS X
      }
-#ifdef PKG_TOOL
-       deriving (Read)
-#endif
 
 defaultPackageConfig
    = Package {
@@ -52,7 +51,9 @@ defaultPackageConfig
        package_deps    = [],
        extra_ghc_opts  = [],
        extra_cc_opts   = [],
-       extra_ld_opts   = []
+       extra_ld_opts   = [],
+       framework_dirs  = [],
+       extra_frameworks= []
     }
 
 -----------------------------------------------------------------------------
@@ -81,7 +82,9 @@ dumpPkgGuts pkg =
          dumpField "package_deps"    (package_deps    pkg),
          dumpField "extra_ghc_opts"  (extra_ghc_opts  pkg),
          dumpField "extra_cc_opts"   (extra_cc_opts   pkg),
-         dumpField "extra_ld_opts"   (extra_ld_opts   pkg)
+         dumpField "extra_ld_opts"   (extra_ld_opts   pkg),
+         dumpField "framework_dirs"  (framework_dirs   pkg),
+         dumpField "extra_frameworks"(extra_frameworks pkg)
       ])))
 
 dumpField :: String -> [String] -> Doc
diff --git a/ghc/utils/ghc-pkg/ParsePkgConfLite.y b/ghc/utils/ghc-pkg/ParsePkgConfLite.y
new file mode 100644 (file)
index 0000000..17998cd
--- /dev/null
@@ -0,0 +1,118 @@
+{
+-- This parser is based on ParsedPkgConf.y in compiler/main/
+-- It's supposed to do the same thing, but without depending on other GHC modules.
+-- The disadvantage is the less sophisticated error reporting, and it's probably
+-- slower because it doesn't use FastStrings.
+
+module ParsePkgConfLite{- ( parsePackageConfig, parseOnePackageConfig ) -}where
+
+import Package  ( PackageConfig(..), defaultPackageConfig )
+import Char(isSpace, isAlpha, isAlphaNum, isUpper)
+import List(break)
+import Debug.Trace
+}
+
+%token
+ '{'           { ITocurly }
+ '}'           { ITccurly }
+ '['           { ITobrack }
+ ']'           { ITcbrack }
+ ','           { ITcomma }
+ '='           { ITequal }
+ VARID         { ITvarid    $$ }
+ CONID         { ITconid    $$ }
+ STRING                { ITstring   $$ }
+
+%name parse pkgconf
+%name parseOne pkg
+%tokentype { Token }
+%%
+
+pkgconf :: { [ PackageConfig ] }
+       : '[' pkgs ']'                  { reverse $2 }
+
+pkgs   :: { [ PackageConfig ] }
+       : pkg                           { [ $1 ] }
+       | pkgs ',' pkg                  { $3 : $1 }
+
+pkg    :: { PackageConfig }
+       : CONID '{' fields '}'          { $3 defaultPackageConfig }
+
+fields  :: { PackageConfig -> PackageConfig }
+       : field                         { \p -> $1 p }
+       | fields ',' field              { \p -> $1 ($3 p) }
+
+field  :: { PackageConfig -> PackageConfig }
+       : VARID '=' STRING              
+                 {\p -> case $1 of
+                  "name" -> p{name = $3}
+                  _      -> error "unkown key in config file" }
+                       
+       | VARID '=' strlist             
+               {\p -> case $1 of
+                       "import_dirs"     -> p{import_dirs     = $3}
+                       "library_dirs"    -> p{library_dirs    = $3}
+                       "hs_libraries"    -> p{hs_libraries    = $3}
+                       "extra_libraries" -> p{extra_libraries = $3}
+                       "include_dirs"    -> p{include_dirs    = $3}
+                       "c_includes"      -> p{c_includes      = $3}
+                       "package_deps"    -> p{package_deps    = $3}
+                       "extra_ghc_opts"  -> p{extra_ghc_opts  = $3}
+                       "extra_cc_opts"   -> p{extra_cc_opts   = $3}
+                       "extra_ld_opts"   -> p{extra_ld_opts   = $3}
+                       "framework_dirs"  -> p{framework_dirs  = $3}
+                       "extra_frameworks"-> p{extra_frameworks= $3}
+                       _other            -> p
+               }
+
+strlist :: { [String] }
+        : '[' ']'                      { [] }
+       | '[' strs ']'                  { reverse $2 }
+
+strs   :: { [String] }
+       : STRING                        { [ $1 ] }
+       | strs ',' STRING               { $3 : $1 }
+
+{
+data Token =
+       ITocurly
+    |  ITccurly
+    |  ITobrack
+    |  ITcbrack
+    |  ITcomma
+    |  ITequal
+    |  ITvarid String
+    |  ITconid String
+    |  ITstring String
+
+lexer :: String -> [Token]
+
+lexer [] = []
+lexer ('{':cs) = ITocurly : lexer cs
+lexer ('}':cs) = ITccurly : lexer cs
+lexer ('[':cs) = ITobrack : lexer cs
+lexer (']':cs) = ITcbrack : lexer cs
+lexer (',':cs) = ITcomma : lexer cs
+lexer ('=':cs) = ITequal : lexer cs
+lexer ('"':cs) = lexString cs ""
+lexer (c:cs)
+    | isSpace c = lexer cs
+    | isAlpha c = lexID (c:cs) where
+lexer _ = error "Unexpected token"
+
+lexID cs = (if isUpper (head cs) then ITconid else ITvarid) id : lexer rest
+    where
+       (id,rest) = break (\c -> c /= '_' && not (isAlphaNum c)) cs
+
+lexString ('"':cs) s = ITstring (reverse s) : lexer cs
+lexString ('\\':c:cs) s = lexString cs (c:s)
+lexString (c:cs) s = lexString cs (c:s)
+
+happyError _ = error "Couldn't parse package configuration."
+
+parsePackageConfig :: String -> [PackageConfig]
+parsePackageConfig = parse . lexer
+
+parseOnePackageConfig :: String -> PackageConfig
+parseOnePackageConfig = parseOne . lexer
+}