From 7828bf3ea2ea34e7a3a8662f5f621ef706ffee5c Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 27 Apr 2010 12:28:51 +0000 Subject: [PATCH] --make is now the default (#3515), and -fno-code works with --make (#3783) If the command line contains any Haskell source files, then we behave as if --make had been given. The meaning of the -c flag has changed (back): -c now selects one-shot compilation, but stops before linking. However, to retain backwards compatibility, -c is still allowed with --make, and means the same as --make -no-link. The -no-link flag has been un-deprecated. -fno-code is now allowed with --make (#3783); the fact that it was disabled before was largely accidental, it seems. We also had some regressions in this area: it seems that -fno-code was causing a .hc file to be emitted in certain cases. I've tidied up the code, there was no need for -fno-code to be a "mode" flag, as far as I can tell. -fno-code does not emit interface files, nor does it do recompilation checking, as suggested in #3783. This would make Haddock emit interface files, for example, and I'm fairly sure we don't want to do that. Compiling with -fno-code is pretty quick anyway, perhaps we can get away without recompilation checking. --- compiler/main/DriverPipeline.hs | 2 +- compiler/main/DynFlags.hs | 8 +-- compiler/main/HscMain.lhs | 15 +++-- docs/users_guide/using.xml | 124 ++++++++++++++++++++++++++++++++++----- ghc/Main.hs | 35 ++++++++--- 5 files changed, 148 insertions(+), 36 deletions(-) diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index d54bb0f..387d5a1 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -826,6 +826,7 @@ runPhase (Hsc src_flavour) stop hsc_env basename suff input_fn get_output_fn _ma src_timestamp <- liftIO $ getModificationTime (basename <.> suff) let force_recomp = dopt Opt_ForceRecomp dflags + hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags) source_unchanged <- if force_recomp || not (isStopLn stop) -- Set source_unchanged to False unconditionally if @@ -842,7 +843,6 @@ runPhase (Hsc src_flavour) stop hsc_env basename suff input_fn get_output_fn _ma else return False -- get the DynFlags - let hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags) let next_phase = hscNextPhase dflags src_flavour hsc_lang output_fn <- liftIO $ get_output_fn dflags next_phase (Just location4) diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 8a8b052..5705bb3 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -1063,10 +1063,8 @@ dynamic_flags = [ (Deprecated "Use -exclude-module instead") -------- Linking ---------------------------------------------------- - , Flag "c" (NoArg (upd $ \d -> d{ ghcLink=NoLink } )) - Supported , Flag "no-link" (NoArg (upd $ \d -> d{ ghcLink=NoLink } )) - (Deprecated "Use -c instead") + Supported , Flag "shared" (NoArg (upd $ \d -> d{ ghcLink=LinkDynLib } )) Supported , Flag "dynload" (HasArg (upd . parseDynLibLoaderMode)) @@ -1387,7 +1385,9 @@ dynamic_flags = [ , Flag "fvia-c" (NoArg (setObjTarget HscC)) Supported , Flag "fvia-C" (NoArg (setObjTarget HscC)) Supported - , Flag "fno-code" (NoArg (setTarget HscNothing)) Supported + , Flag "fno-code" (NoArg (do upd $ \d -> d{ ghcLink=NoLink } + setTarget HscNothing)) + Supported , Flag "fbyte-code" (NoArg (setTarget HscInterpreted)) Supported , Flag "fobject-code" (NoArg (setTarget defaultHscTarget)) Supported diff --git a/compiler/main/HscMain.lhs b/compiler/main/HscMain.lhs index 5590744..b183250 100644 --- a/compiler/main/HscMain.lhs +++ b/compiler/main/HscMain.lhs @@ -435,7 +435,12 @@ hscOneShotCompiler = , hscRecompile = genericHscRecompile hscOneShotCompiler - , hscBackend = genericHscBackend hscOneShotCompiler + , hscBackend = \ tc_result mod_summary mb_old_hash -> do + hsc_env <- getSession + case hscTarget (hsc_dflags hsc_env) of + HscNothing -> return (HscRecomp False ()) + _otherw -> genericHscBackend hscOneShotCompiler + tc_result mod_summary mb_old_hash , hscGenBootOutput = \tc_result mod_summary mb_old_iface -> do (iface, changed, _) <- hscSimpleIface tc_result mb_old_iface @@ -536,13 +541,7 @@ hscNothingCompiler = details <- genModDetails iface return (HscNoRecomp, iface, details) - , hscRecompile = \mod_summary mb_old_hash -> - case ms_hsc_src mod_summary of - ExtCoreFile -> - panic "hscCompileNothing: cannot do external core" - _otherwise -> do - tc_result <- hscFileFrontEnd mod_summary - hscBackend hscNothingCompiler tc_result mod_summary mb_old_hash + , hscRecompile = genericHscRecompile hscNothingCompiler , hscBackend = \tc_result _mod_summary mb_old_iface -> do (iface, _changed, details) <- hscSimpleIface tc_result mb_old_iface diff --git a/docs/users_guide/using.xml b/docs/users_guide/using.xml index 6ffdf2a..95f5b94 100644 --- a/docs/users_guide/using.xml +++ b/docs/users_guide/using.xml @@ -6,6 +6,77 @@ using GHC + Getting started: compiling programs + + + In this chapter you'll find a complete reference to the GHC + command-line syntax, including all 400+ flags. It's a large and + complex system, and there are lots of details, so it can be + quite hard to figure out how to get started. With that in mind, + this introductory section provides a quick introduction to the + basic usage of GHC for compiling a Haskell program, before the + following sections dive into the full syntax. + + + + Let's create a Hello World program, and compile and run it. + First, create a file hello.hs containing + the Haskell code: + + + +main = putStrLn "Hello, World!" + + + To compile the program, use GHC like this: + + +$ ghc hello.hs + + (where $ represents the prompt: don't + type it). GHC will compile the source + file hello.hs, producing + an object + file hello.o and + an interface + file hello.hi, and then it + will link the object file to the libraries that come with GHC + to produce an executable called hello on + Unix/Linux/Mac, or hello.exe on + Windows. + + + By default GHC will be very quiet about what it is doing, only + printing error messages. If you want to see in more detail + what's going on behind the scenes, add to + the command line. + + + + Then we can run the program like this: + + + +$ ./hello +Hello World! + + + If your program contains multiple modules, then you only need to + tell GHC the name of the source file containing + the Main module, and GHC will examine + the import declarations to find the other + modules that make up the program and find their source files. + This means that, with the exception of + the Main module, every source file should be + named after the module name that it contains (with dots replaced + by directory separators). For example, the + module Data.Person would be in the + file Data/Person.hs on Unix/Linux/Mac, + or Data\Person.hs on Windows. + + + + Options overview GHC's behaviour is controlled by @@ -110,7 +181,7 @@ module X where Mode flags - For example, or . + For example, or . There may only be a single mode flag on the command line. The available modes are listed in . @@ -220,10 +291,20 @@ module X where Modes of operation - GHC's behaviour is firstly controlled by a mode flag. Only - one of these flags may be given, but it does not necessarily need - to be the first option on the command-line. The available modes - are: + + GHC's behaviour is firstly controlled by a mode flag. Only one + of these flags may be given, but it does not necessarily need to + be the first option on the command-line. + + + + If no mode flag is present, then GHC will enter make mode + () if there are any Haskell source + files given on the command line, or else it will link the + objects named on the command line to produce an executable. + + + The available mode flags are: @@ -242,7 +323,7 @@ module X where - ghc --make + ghc ––make make mode @@ -254,6 +335,12 @@ module X where likely to be much easier, and faster, than using make. Make mode is described in . + + + This mode is the default if there are any Haskell + source files mentioned on the command line, and in this case + the option can be omitted. + @@ -428,8 +515,7 @@ module X where separate compilation - When given the option, - GHC will build a multi-module Haskell program by following + In this mode, GHC will build a multi-module Haskell program by following dependencies from one or more root modules (usually just Main). For example, if your Main module is in a file called @@ -440,12 +526,22 @@ module X where ghc ––make Main.hs - The command line may contain any number of source file - names or module names; GHC will figure out all the modules in - the program by following the imports from these initial modules. - It will then attempt to compile each module which is out of - date, and finally, if there is a Main module, - the program will also be linked into an executable. + + In fact, GHC enters make mode automatically if there are any + Haskell source files on the command line and no other mode is + specified, so in this case we could just type + + + +ghc Main.hs + + + Any number of source file names or module names may be + specified; GHC will figure out all the modules in the program by + following the imports from these initial modules. It will then + attempt to compile each module which is out of date, and + finally, if there is a Main module, the + program will also be linked into an executable. The main advantages to using ghc ––make over traditional diff --git a/ghc/Main.hs b/ghc/Main.hs index 8348897..519d9cd 100644 --- a/ghc/Main.hs +++ b/ghc/Main.hs @@ -429,6 +429,14 @@ isDoInteractiveMode :: Mode -> Bool isDoInteractiveMode (Right (Right DoInteractive)) = True isDoInteractiveMode _ = False +isStopLnMode :: Mode -> Bool +isStopLnMode (Right (Right (StopBefore StopLn))) = True +isStopLnMode _ = False + +isDoMakeMode :: Mode -> Bool +isDoMakeMode (Right (Right DoMake)) = True +isDoMakeMode _ = False + #ifdef GHCI isInteractiveMode :: PostLoadMode -> Bool isInteractiveMode DoInteractive = True @@ -462,7 +470,6 @@ isCompManagerMode DoInteractive = True isCompManagerMode (DoEval _) = True isCompManagerMode _ = False - -- ----------------------------------------------------------------------------- -- Parsing the mode flag @@ -475,7 +482,7 @@ parseModeFlags args = do runCmdLine (processArgs mode_flags args) (Nothing, [], []) mode = case mModeFlag of - Nothing -> stopBeforeMode StopLn + Nothing -> doMakeMode Just (m, _) -> m errs = errs1 ++ map (mkGeneralLocated "on the commandline") errs2 when (not (null errs)) $ ghcError $ errorsToGhcException errs @@ -519,6 +526,9 @@ mode_flags = Supported ------- primary modes ------------------------------------------------ + , Flag "c" (PassFlag (\f -> do setMode (stopBeforeMode StopLn) f + addFlag "-no-link" f)) + Supported , Flag "M" (PassFlag (setMode doMkDependHSMode)) Supported , Flag "E" (PassFlag (setMode (stopBeforeMode anyHsc))) @@ -536,12 +546,6 @@ mode_flags = Supported , Flag "e" (SepArg (\s -> setMode (doEvalMode s) "-e")) Supported - - -- -fno-code says to stop after Hsc but don't generate any code. - , Flag "fno-code" (PassFlag (\f -> do setMode (stopBeforeMode HCc) f - addFlag "-fno-code" f - addFlag "-fforce-recomp" f)) - Supported ] setMode :: Mode -> String -> ModeM () @@ -552,6 +556,11 @@ setMode newMode newFlag = do Nothing -> ((newMode, newFlag), errs) Just (oldMode, oldFlag) -> case (oldMode, newMode) of + -- -c/--make are allowed together, and mean --make -no-link + _ | isStopLnMode oldMode && isDoMakeMode newMode + || isStopLnMode newMode && isDoMakeMode oldMode -> + ((doMakeMode, "--make"), []) + -- If we have both --help and --interactive then we -- want showGhciUsage _ | isShowGhcUsageMode oldMode && @@ -593,7 +602,6 @@ addFlag s flag = do -- Run --make mode doMake :: [(String,Maybe Phase)] -> Ghc () -doMake [] = ghcError (UsageError "no input files") doMake srcs = do let (hs_srcs, non_hs_srcs) = partition haskellish srcs @@ -603,6 +611,15 @@ doMake srcs = do phase `notElem` [As, Cc, CmmCpp, Cmm, StopLn] hsc_env <- GHC.getSession + + -- if we have no haskell sources from which to do a dependency + -- analysis, then just do one-shot compilation and/or linking. + -- This means that "ghc Foo.o Bar.o -o baz" links the program as + -- we expect. + if (null hs_srcs) + then oneShot hsc_env StopLn srcs >> GHC.printWarnings + else do + o_files <- mapM (\x -> do f <- compileFile hsc_env StopLn x GHC.printWarnings -- 1.7.10.4