From 643a2f7089ce22012df23c161702f9e6b6da6792 Mon Sep 17 00:00:00 2001 From: wolfgang Date: Wed, 12 Jun 2002 22:04:27 +0000 Subject: [PATCH] [project @ 2002-06-12 22:04:25 by wolfgang] Added support for Frameworks on MacOS X. *) On MacOS X, two additional command-line options are supported: -framework link with framework, gets passed on to ld -framework-path gets passed on to ld as "-F". (-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 | 8 ++- ghc/compiler/main/DriverFlags.hs | 8 ++- ghc/compiler/main/DriverPipeline.hs | 23 +++++++ ghc/compiler/main/DriverState.hs | 19 +++++- ghc/compiler/main/Packages.lhs | 3 +- ghc/compiler/main/ParsePkgConf.y | 2 + ghc/utils/ghc-pkg/Main.hs | 14 +++- ghc/utils/ghc-pkg/Package.hs | 17 +++-- ghc/utils/ghc-pkg/ParsePkgConfLite.y | 118 ++++++++++++++++++++++++++++++++++ 9 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 ghc/utils/ghc-pkg/ParsePkgConfLite.y diff --git a/ghc/compiler/ghci/InteractiveUI.hs b/ghc/compiler/ghci/InteractiveUI.hs index 162dfc2..8ec1362 100644 --- a/ghc/compiler/ghci/InteractiveUI.hs +++ b/ghc/compiler/ghci/InteractiveUI.hs @@ -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 diff --git a/ghc/compiler/main/DriverFlags.hs b/ghc/compiler/main/DriverFlags.hs index e480c8a..e0196f2 100644 --- a/ghc/compiler/main/DriverFlags.hs +++ b/ghc/compiler/main/DriverFlags.hs @@ -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)) ) diff --git a/ghc/compiler/main/DriverPipeline.hs b/ghc/compiler/main/DriverPipeline.hs index b567817..8f70de4 100644 --- a/ghc/compiler/main/DriverPipeline.hs +++ b/ghc/compiler/main/DriverPipeline.hs @@ -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 diff --git a/ghc/compiler/main/DriverState.hs b/ghc/compiler/main/DriverState.hs index 4045c9e..1b4a06b 100644 --- a/ghc/compiler/main/DriverState.hs +++ b/ghc/compiler/main/DriverState.hs @@ -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 diff --git a/ghc/compiler/main/Packages.lhs b/ghc/compiler/main/Packages.lhs index 7c18904..43b96ec 100644 --- a/ghc/compiler/main/Packages.lhs +++ b/ghc/compiler/main/Packages.lhs @@ -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 diff --git a/ghc/compiler/main/ParsePkgConf.y b/ghc/compiler/main/ParsePkgConf.y index 44611e7..fa83513 100644 --- a/ghc/compiler/main/ParsePkgConf.y +++ b/ghc/compiler/main/ParsePkgConf.y @@ -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 } diff --git a/ghc/utils/ghc-pkg/Main.hs b/ghc/utils/ghc-pkg/Main.hs index 4583110..80a6c27 100644 --- a/ghc/utils/ghc-pkg/Main.hs +++ b/ghc/utils/ghc-pkg/Main.hs @@ -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 diff --git a/ghc/utils/ghc-pkg/Package.hs b/ghc/utils/ghc-pkg/Package.hs index ae330ab..b4df186 100644 --- a/ghc/utils/ghc-pkg/Package.hs +++ b/ghc/utils/ghc-pkg/Package.hs @@ -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 index 0000000..17998cd --- /dev/null +++ b/ghc/utils/ghc-pkg/ParsePkgConfLite.y @@ -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 +} -- 1.7.10.4