1 {-# OPTIONS -W -fno-warn-incomplete-patterns #-}
2 -----------------------------------------------------------------------------
3 -- $Id: Main.hs,v 1.3 2000/10/11 14:08:52 simonmar Exp $
7 -- (c) Simon Marlow 2000
9 -----------------------------------------------------------------------------
11 -- with path so that ghc -M can find config.h
12 #include "../includes/config.h"
14 module Main (main) where
16 #include "HsVersions.h"
18 import CmSummarise ( getImports )
19 import CmStaticInfo ( Package(..) )
23 import Util ( global )
27 #ifndef mingw32_TARGET_OS
42 -----------------------------------------------------------------------------
45 -- * -fglasgow-exts NO LONGER IMPLIES -package lang!!! (-fglasgow-exts is a
46 -- dynamic flag whereas -package is a static flag.)
48 -----------------------------------------------------------------------------
51 -- certain options in OPTIONS pragmas are persistent through subsequent compilations.
52 -- new mkdependHS doesn't support all the options that the old one did (-X et al.)
53 -- time commands when run with -v
58 -- Win32 support: proper signal handling
59 -- make sure OPTIONS in .hs file propogate to .hc file if -C or -keep-hc-file-too
60 -- reading the package configuration file is too slow
61 -- -H, -K, -Rghc-timing
64 -----------------------------------------------------------------------------
65 -- Differences vs. old driver:
67 -- No more "Enter your Haskell program, end with ^D (on a line of its own):"
68 -- consistency checking removed (may do this properly later)
70 -- no hi diffs (could be added later)
73 -----------------------------------------------------------------------------
77 Phase of the | Suffix saying | Flag saying | (suffix of)
78 compilation system | ``start here''| ``stop after''| output file
80 literate pre-processor | .lhs | - | -
81 C pre-processor (opt.) | - | -E | -
82 Haskell compiler | .hs | -C, -S | .hc, .s
83 C compiler (opt.) | .hc or .c | -S | .s
84 assembler | .s or .S | -c | .o
85 linker | other | - | a.out
89 = MkDependHS -- haskell dependency generation
94 | HCc -- Haskellised C (as opposed to vanilla C) compilation
95 | Mangle -- assembly mangling, now done by a separate script.
96 | SplitMangle -- after mangler if splitting
102 -----------------------------------------------------------------------------
103 -- Build the Hsc command line
105 build_hsc_opts :: IO [String]
107 opt_C_ <- getOpts opt_C -- misc hsc opts
109 -- take into account -fno-* flags by removing the equivalent -f*
110 -- flag from our list.
111 anti_flags <- getOpts anti_opt_C
112 let basic_opts = opt_C_ ++ warn_opts ++ optimisation_opts ++ stg_opts
113 filtered_opts = filter (`notElem` anti_flags) basic_opts
116 warn_level <- readIORef warning_opt
117 let warn_opts = case warn_level of
118 W_default -> standardWarnings
120 W_all -> minusWallOpts
124 minus_o <- readIORef opt_level
127 0 -> hsc_minusNoO_flags
128 1 -> hsc_minusO_flags
129 2 -> hsc_minusO2_flags
130 _ -> error "unknown opt level"
134 ways_ <- readIORef ways
135 let stg_massage | WayProf `elem` ways_ = "-fmassage-stg-for-profiling"
138 stg_stats <- readIORef opt_StgStats
139 let stg_stats_flag | stg_stats = "-dstg-stats"
142 let stg_opts = [ stg_massage, stg_stats_flag, "-flet-no-escape" ]
143 -- let-no-escape always on for now
146 let hi_vers = "-fhi-version="++cProjectVersionInt
148 static <- (do s <- readIORef static; if s then return "-static" else return "")
150 l <- readIORef hsc_lang
153 HscAsm -> "-olang=asm"
154 HscJava -> "-olang=java"
156 -- get hi-file suffix
157 hisuf <- readIORef hi_suf
159 -- hi-suffix for packages depends on the build tag.
161 do tag <- readIORef build_tag
164 else return (tag ++ "_hi")
166 import_dirs <- readIORef import_paths
167 package_import_dirs <- getPackageImportPath
169 let hi_map = "-himap=" ++
170 makeHiMap import_dirs hisuf
171 package_import_dirs package_hisuf
174 hi_map_sep = "-himap-sep=" ++ [split_marker]
176 scale <- readIORef scale_sizes_by
177 heap <- readState specific_heap_size
178 stack <- readState specific_stack_size
183 -- ToDo: C stub files
184 ++ [ hi_vers, static, verb, lang, hi_map, hi_map_sep ]
188 (import_dirs :: [String])
189 (hi_suffix :: String)
190 (package_import_dirs :: [String])
191 (package_hi_suffix :: String)
192 (split_marker :: Char)
193 = foldr (add_dir hi_suffix)
194 (foldr (add_dir package_hi_suffix) "" package_import_dirs)
197 add_dir hisuf dir str = dir ++ "%." ++ hisuf ++ split_marker : str
199 -----------------------------------------------------------------------------
203 -- all error messages are propagated as exceptions
204 my_catchDyn (\dyn -> case dyn of
205 PhaseFailed _phase code -> exitWith code
206 Interrupted -> exitWith (ExitFailure 1)
207 _ -> do hPutStrLn stderr (show (dyn :: BarfKind))
208 exitWith (ExitFailure 1)
211 -- make sure we clean up after ourselves
212 later (do forget_it <- readIORef keep_tmp_files
213 unless forget_it $ do
214 verb <- readIORef verbose
217 -- exceptions will be blocked while we clean the temporary files,
218 -- so there shouldn't be any difficulty if we receive further
221 -- install signal handlers
222 main_thread <- myThreadId
224 #ifndef mingw32_TARGET_OS
225 let sig_handler = Catch (raiseInThread main_thread
226 (DynException (toDyn Interrupted)))
227 installHandler sigQUIT sig_handler Nothing
228 installHandler sigINT sig_handler Nothing
232 writeIORef prog_name pgm
236 -- grab any -B options from the command line first
237 argv' <- setTopDir argv
238 top_dir <- readIORef topDir
240 let installed s = top_dir ++ s
241 inplace s = top_dir ++ '/':cCURRENT_DIR ++ '/':s
243 installed_pkgconfig = installed ("package.conf")
244 inplace_pkgconfig = inplace (cGHC_DRIVER_DIR ++ "/package.conf.inplace")
246 -- discover whether we're running in a build tree or in an installation,
247 -- by looking for the package configuration file.
248 am_installed <- doesFileExist installed_pkgconfig
251 then writeIORef path_pkgconfig installed_pkgconfig
252 else do am_inplace <- doesFileExist inplace_pkgconfig
254 then writeIORef path_pkgconfig inplace_pkgconfig
255 else throw (OtherError "can't find package.conf")
257 -- set the location of our various files
259 then do writeIORef path_usage (installed "ghc-usage.txt")
260 writeIORef pgm_L (installed "unlit")
261 writeIORef pgm_C (installed "hsc")
262 writeIORef pgm_m (installed "ghc-asm")
263 writeIORef pgm_s (installed "ghc-split")
265 else do writeIORef path_usage (inplace (cGHC_DRIVER_DIR ++ '/':usage_file))
266 writeIORef pgm_L (inplace cGHC_UNLIT)
267 writeIORef pgm_C (inplace cGHC_HSC)
268 writeIORef pgm_m (inplace cGHC_MANGLER)
269 writeIORef pgm_s (inplace cGHC_SPLIT)
271 -- read the package configuration
272 conf_file <- readIORef path_pkgconfig
273 contents <- readFile conf_file
274 writeIORef package_details (read contents)
276 -- find the phase to stop after (i.e. -E, -C, -c, -S flags)
277 (flags2, todo, stop_flag) <- getToDo argv'
278 writeIORef v_todo todo
280 -- process all the other arguments, and get the source files
281 non_static <- processArgs static_flags flags2 []
283 -- find the build tag, and re-process the build-specific options
284 more_opts <- findBuildTag
285 _ <- processArgs static_opts more_opts []
287 -- give the static flags to hsc
290 -- the rest of the arguments are "dynamic"
291 srcs <- processArgs dynamic_flags non_static []
293 -- complain about any unknown flags
294 let unknown_flags = [ f | ('-':f) <- srcs ]
295 mapM unknownFlagErr unknown_flags
298 verb <- readIORef verbose
300 when verb (do hPutStr stderr "Glasgow Haskell Compiler, Version "
301 hPutStr stderr version_str
302 hPutStr stderr ", for Haskell 98, compiled by GHC version "
303 hPutStrLn stderr booter_version)
305 when verb (hPutStrLn stderr ("Using package config file: " ++ conf_file))
307 -- mkdependHS is special
308 when (todo == DoMkDependHS) beginMkDependHS
311 when (todo == DoMake) beginMake
313 -- for each source file, find which phases to run
314 pipelines <- mapM (genPipeline todo stop_flag) srcs
315 let src_pipelines = zip srcs pipelines
317 o_file <- readIORef output_file
318 if isJust o_file && todo /= DoLink && length srcs > 1
319 then throwDyn (UsageError "can't apply -o option to multiple source files")
322 if null srcs then throwDyn (UsageError "no input files") else do
324 -- save the flag state, because this could be modified by OPTIONS pragmas
325 -- during the compilation, and we'll need to restore it before starting
326 -- the next compilation.
327 saved_driver_state <- readIORef driver_state
329 let compileFile (src, phases) = do
330 r <- run_pipeline phases src (todo==DoLink) True orig_base orig_suff
331 writeIORef driver_state saved_driver_state
333 where (orig_base, orig_suff) = splitFilename src
335 o_files <- mapM compileFile src_pipelines
337 when (todo == DoMkDependHS) endMkDependHS
339 when (todo == DoLink) (do_link o_files)
341 -- grab the last -B option on the command line, and
342 -- set topDir to its value.
343 setTopDir :: [String] -> IO [String]
345 let (minusbs, others) = partition (prefixMatch "-B") args
347 [] -> writeIORef topDir clibdir
348 some -> writeIORef topDir (drop 2 (last some)))
351 -----------------------------------------------------------------------------
352 -- Which phase to stop at
354 data ToDo = DoMkDependHS | DoMkDLL | StopBefore Phase | DoLink | DoInteractive
357 GLOBAL_VAR(v_todo, error "todo", ToDo)
359 todoFlag :: String -> Maybe ToDo
360 todoFlag "-M" = Just $ DoMkDependHS
361 todoFlag "-E" = Just $ StopBefore Hsc
362 todoFlag "-C" = Just $ StopBefore HCc
363 todoFlag "-S" = Just $ StopBefore As
364 todoFlag "-c" = Just $ StopBefore Ln
365 todoFlag "--make" = Just $ DoMake
366 todoFlag "--interactive" = Just $ DoInteractive
370 -> IO ( [String] -- rest of command line
372 , String -- "ToDo" flag
375 = case my_partition todoFlag flags of
376 ([] , rest) -> return (rest, DoLink, "") -- default is to do linking
377 ([(flag,one)], rest) -> return (rest, one, flag)
380 "only one of the flags -M, -E, -C, -S, -c, --make is allowed")
382 -----------------------------------------------------------------------------
385 -- Herein is all the magic about which phases to run in which order, whether
386 -- the intermediate files should be in /tmp or in the current directory,
387 -- what the suffix of the intermediate files should be, etc.
389 -- The following compilation pipeline algorithm is fairly hacky. A
390 -- better way to do this would be to express the whole comilation as a
391 -- data flow DAG, where the nodes are the intermediate files and the
392 -- edges are the compilation phases. This framework would also work
393 -- nicely if a haskell dependency generator was included in the
396 -- It would also deal much more cleanly with compilation phases that
397 -- generate multiple intermediates, (eg. hsc generates .hc, .hi, and
398 -- possibly stub files), where some of the output files need to be
399 -- processed further (eg. the stub files need to be compiled by the C
402 -- A cool thing to do would then be to execute the data flow graph
403 -- concurrently, automatically taking advantage of extra processors on
404 -- the host machine. For example, when compiling two Haskell files
405 -- where one depends on the other, the data flow graph would determine
406 -- that the C compiler from the first comilation can be overlapped
407 -- with the hsc comilation for the second file.
409 data IntermediateFileType
414 -- the first compilation phase for a given file is determined
416 startPhase "lhs" = Unlit
417 startPhase "hs" = Cpp
418 startPhase "hc" = HCc
420 startPhase "raw_s" = Mangle
424 startPhase _ = Ln -- all unknown file types
427 :: ToDo -- when to stop
428 -> String -- "stop after" flag (for error messages)
429 -> String -- original filename
430 -> IO [ -- list of phases to run for this file
432 IntermediateFileType, -- keep the output from this phase?
433 String) -- output file suffix
436 genPipeline todo stop_flag filename
438 split <- readIORef split_object_files
439 mangle <- readIORef do_asm_mangling
440 lang <- readIORef hsc_lang
441 keep_hc <- readIORef keep_hc_files
442 keep_raw_s <- readIORef keep_raw_s_files
443 keep_s <- readIORef keep_s_files
446 ----------- ----- ---- --- -- -- - - -
447 (_basename, suffix) = splitFilename filename
449 start_phase = startPhase suffix
451 haskell_ish_file = suffix `elem` [ "hs", "lhs", "hc" ]
452 c_ish_file = suffix `elem` [ "c", "s", "S" ] -- maybe .cc et al.??
454 -- for a .hc file, or if the -C flag is given, we need to force lang to HscC
456 | suffix == "hc" = HscC
457 | todo == StopBefore HCc && lang /= HscC && haskell_ish_file = HscC
461 ----------- ----- ---- --- -- -- - - -
463 | todo == DoMkDependHS = [ Unlit, Cpp, MkDependHS ]
467 HscC | split && mangle -> [ Unlit, Cpp, Hsc, HCc, Mangle,
468 SplitMangle, SplitAs ]
469 | mangle -> [ Unlit, Cpp, Hsc, HCc, Mangle, As ]
471 | otherwise -> [ Unlit, Cpp, Hsc, HCc, As ]
473 HscAsm | split -> [ Unlit, Cpp, Hsc, SplitMangle, SplitAs ]
474 | otherwise -> [ Unlit, Cpp, Hsc, As ]
476 HscJava | split -> not_valid
477 | otherwise -> error "not implemented: compiling via Java"
479 | c_ish_file = [ Cc, As ]
481 | otherwise = [ ] -- just pass this file through to the linker
483 -- ToDo: this is somewhat cryptic
484 not_valid = throwDyn (OtherError ("invalid option combination"))
485 ----------- ----- ---- --- -- -- - - -
487 -- this shouldn't happen.
488 if start_phase /= Ln && start_phase `notElem` pipeline
489 then throwDyn (OtherError ("can't find starting phase for "
493 -- if we can't find the phase we're supposed to stop before,
494 -- something has gone wrong.
498 && phase `notElem` pipeline
499 && not (phase == As && SplitAs `elem` pipeline)) $
501 ("flag " ++ stop_flag
502 ++ " is incompatible with source file `" ++ filename ++ "'"))
506 ----------- ----- ---- --- -- -- - - -
508 :: [Phase] -- raw pipeline
509 -> Phase -- phase to stop before
510 -> [(Phase, IntermediateFileType, String{-file extension-})]
511 annotatePipeline [] _ = []
512 annotatePipeline (Ln:_) _ = []
513 annotatePipeline (phase:next_phase:ps) stop =
514 (phase, keep_this_output, phase_input_ext next_phase)
515 : annotatePipeline (next_phase:ps) stop
518 | next_phase == stop = Persistent
522 Mangle | keep_raw_s -> Persistent
523 As | keep_s -> Persistent
524 HCc | keep_hc -> Persistent
527 -- add information about output files to the pipeline
528 -- the suffix on an output file is determined by the next phase
529 -- in the pipeline, so we add linking to the end of the pipeline
530 -- to force the output from the final phase to be a .o file.
531 stop_phase = case todo of StopBefore phase -> phase
534 annotated_pipeline = annotatePipeline (pipeline ++ [ Ln ]) stop_phase
536 phase_ne p (p1,_,_) = (p1 /= p)
537 ----------- ----- ---- --- -- -- - - -
540 dropWhile (phase_ne start_phase) .
541 foldr (\p ps -> if phase_ne stop_phase p then p:ps else []) []
547 :: [ (Phase, IntermediateFileType, String) ] -- phases to run
548 -> String -- input file
549 -> Bool -- doing linking afterward?
550 -> Bool -- take into account -o when generating output?
551 -> String -- original basename (eg. Main)
552 -> String -- original suffix (eg. hs)
553 -> IO String -- return final filename
555 run_pipeline [] input_fn _ _ _ _ = return input_fn
556 run_pipeline ((phase, keep, o_suffix):phases)
557 input_fn do_linking use_ofile orig_basename orig_suffix
560 output_fn <- outputFileName (null phases) keep o_suffix
562 carry_on <- run_phase phase orig_basename orig_suffix input_fn output_fn
563 -- sometimes we bail out early, eg. when the compiler's recompilation
564 -- checker has determined that recompilation isn't necessary.
566 then do let (_,keep,final_suffix) = last phases
567 ofile <- outputFileName True keep final_suffix
569 else do -- carry on ...
571 -- sadly, ghc -E is supposed to write the file to stdout. We
572 -- generate <file>.cpp, so we also have to cat the file here.
573 when (null phases && phase == Cpp) $
574 run_something "Dump pre-processed file to stdout"
575 ("cat " ++ output_fn)
577 run_pipeline phases output_fn do_linking use_ofile orig_basename orig_suffix
580 outputFileName last_phase keep suffix
581 = do o_file <- readIORef output_file
582 if last_phase && not do_linking && use_ofile && isJust o_file
585 Nothing -> error "outputFileName"
586 else if keep == Persistent
587 then do f <- odir_ify (orig_basename ++ '.':suffix)
589 else newTempName suffix
591 -------------------------------------------------------------------------------
595 GLOBAL_VAR(dep_makefile, "Makefile", String);
596 GLOBAL_VAR(dep_include_prelude, False, Bool);
597 GLOBAL_VAR(dep_ignore_dirs, [], [String]);
598 GLOBAL_VAR(dep_suffixes, [], [String]);
599 GLOBAL_VAR(dep_warnings, True, Bool);
602 GLOBAL_VAR(dep_makefile_hdl, error "dep_makefile_hdl", Maybe Handle);
603 GLOBAL_VAR(dep_tmp_file, error "dep_tmp_file", String);
604 GLOBAL_VAR(dep_tmp_hdl, error "dep_tmp_hdl", Handle);
605 GLOBAL_VAR(dep_dir_contents, error "dep_dir_contents", [(String,[String])]);
607 depStartMarker = "# DO NOT DELETE: Beginning of Haskell dependencies"
608 depEndMarker = "# DO NOT DELETE: End of Haskell dependencies"
610 -- for compatibility with the old mkDependHS, we accept options of the form
611 -- -optdep-f -optdep.depend, etc.
613 ( "s", SepArg (add dep_suffixes) ),
614 ( "f", SepArg (writeIORef dep_makefile) ),
615 ( "w", NoArg (writeIORef dep_warnings False) ),
616 ( "-include-prelude", NoArg (writeIORef dep_include_prelude True) ),
617 ( "X", Prefix (addToDirList dep_ignore_dirs) ),
618 ( "-exclude-directory=", Prefix (addToDirList dep_ignore_dirs) )
621 beginMkDependHS :: IO ()
624 -- slurp in the mkdependHS-style options
625 flags <- getOpts opt_dep
626 _ <- processArgs dep_opts flags []
628 -- open a new temp file in which to stuff the dependency info
630 dep_file <- newTempName "dep"
631 writeIORef dep_tmp_file dep_file
632 tmp_hdl <- openFile dep_file WriteMode
633 writeIORef dep_tmp_hdl tmp_hdl
636 makefile <- readIORef dep_makefile
637 exists <- doesFileExist makefile
640 writeIORef dep_makefile_hdl Nothing
644 makefile_hdl <- openFile makefile ReadMode
645 writeIORef dep_makefile_hdl (Just makefile_hdl)
647 -- slurp through until we get the magic start string,
648 -- copying the contents into dep_makefile
650 l <- hGetLine makefile_hdl
651 if (l == depStartMarker)
653 else do hPutStrLn tmp_hdl l; slurp
655 -- slurp through until we get the magic end marker,
656 -- throwing away the contents
658 l <- hGetLine makefile_hdl
659 if (l == depEndMarker)
663 catchJust ioErrors slurp
664 (\e -> if isEOFError e then return () else ioError e)
665 catchJust ioErrors chuck
666 (\e -> if isEOFError e then return () else ioError e)
669 -- write the magic marker into the tmp file
670 hPutStrLn tmp_hdl depStartMarker
672 -- cache the contents of all the import directories, for future
674 import_dirs <- readIORef import_paths
675 pkg_import_dirs <- getPackageImportPath
676 import_dir_contents <- mapM getDirectoryContents import_dirs
677 pkg_import_dir_contents <- mapM getDirectoryContents pkg_import_dirs
678 writeIORef dep_dir_contents
679 (zip import_dirs import_dir_contents ++
680 zip pkg_import_dirs pkg_import_dir_contents)
682 -- ignore packages unless --include-prelude is on
683 include_prelude <- readIORef dep_include_prelude
684 when (not include_prelude) $
685 mapM_ (add dep_ignore_dirs) pkg_import_dirs
690 endMkDependHS :: IO ()
692 makefile <- readIORef dep_makefile
693 makefile_hdl <- readIORef dep_makefile_hdl
694 tmp_file <- readIORef dep_tmp_file
695 tmp_hdl <- readIORef dep_tmp_hdl
697 -- write the magic marker into the tmp file
698 hPutStrLn tmp_hdl depEndMarker
704 -- slurp the rest of the orignal makefile and copy it into the output
710 catchJust ioErrors slurp
711 (\e -> if isEOFError e then return () else ioError e)
715 hClose tmp_hdl -- make sure it's flushed
717 -- create a backup of the original makefile
718 when (isJust makefile_hdl) $
719 run_something ("Backing up " ++ makefile)
720 (unwords [ "cp", makefile, makefile++".bak" ])
722 -- copy the new makefile in place
723 run_something "Installing new makefile"
724 (unwords [ "cp", tmp_file, makefile ])
727 findDependency :: String -> Import -> IO (Maybe (String, Bool))
728 findDependency mod imp = do
729 dir_contents <- readIORef dep_dir_contents
730 ignore_dirs <- readIORef dep_ignore_dirs
731 hisuf <- readIORef hi_suf
734 (imp_mod, is_source) =
736 Normal str -> (str, False)
737 Source str -> (str, True )
739 imp_hi = imp_mod ++ '.':hisuf
740 imp_hiboot = imp_mod ++ ".hi-boot"
741 imp_hiboot_v = imp_mod ++ ".hi-boot-" ++ cHscIfaceFileVersion
742 imp_hs = imp_mod ++ ".hs"
743 imp_lhs = imp_mod ++ ".lhs"
745 deps | is_source = [ imp_hiboot_v, imp_hiboot, imp_hs, imp_lhs ]
746 | otherwise = [ imp_hi, imp_hs, imp_lhs ]
748 search [] = throwDyn (OtherError ("can't find one of the following: " ++
749 unwords (map (\d -> '`': d ++ "'") deps) ++
750 " (imported from `" ++ mod ++ "')"))
751 search ((dir, contents) : dirs)
752 | null present = search dirs
754 if dir `elem` ignore_dirs
757 then if dep /= imp_hiboot_v
758 then return (Just (dir++'/':imp_hiboot, False))
759 else return (Just (dir++'/':dep, False))
760 else return (Just (dir++'/':imp_hi, not is_source))
762 present = filter (`elem` contents) deps
769 -----------------------------------------------------------------------------
772 run_phase MkDependHS basename suff input_fn _output_fn = do
773 src <- readFile input_fn
774 let imports = getImports src
776 deps <- mapM (findDependency basename) imports
778 osuf_opt <- readIORef output_suf
779 let osuf = case osuf_opt of
783 extra_suffixes <- readIORef dep_suffixes
784 let suffixes = osuf : map (++ ('_':osuf)) extra_suffixes
785 ofiles = map (\suf -> basename ++ '.':suf) suffixes
787 objs <- mapM odir_ify ofiles
789 hdl <- readIORef dep_tmp_hdl
791 -- std dependeny of the object(s) on the source file
792 hPutStrLn hdl (unwords objs ++ " : " ++ basename ++ '.':suff)
794 let genDep (dep, False {- not an hi file -}) =
795 hPutStrLn hdl (unwords objs ++ " : " ++ dep)
796 genDep (dep, True {- is an hi file -}) = do
797 hisuf <- readIORef hi_suf
798 let dep_base = remove_suffix '.' dep
799 deps = (dep_base ++ hisuf)
800 : map (\suf -> dep_base ++ suf ++ '_':hisuf) extra_suffixes
801 -- length objs should be == length deps
802 sequence_ (zipWith (\o d -> hPutStrLn hdl (o ++ " : " ++ d)) objs deps)
804 mapM genDep [ d | Just d <- deps ]
808 -- add the lines to dep_makefile:
812 -- if the dependency is on something other than a .hi file:
813 -- this.o this.p_o ... : dep
815 -- if the import is {-# SOURCE #-}
816 -- this.o this.p_o ... : dep.hi-boot[-$vers]
819 -- this.o ... : dep.hi
820 -- this.p_o ... : dep.p_hi
823 -- (where .o is $osuf, and the other suffixes come from
824 -- the cmdline -s options).
826 -----------------------------------------------------------------------------
829 run_phase Hsc basename suff input_fn output_fn
830 = do hsc <- readIORef pgm_C
832 -- we add the current directory (i.e. the directory in which
833 -- the .hs files resides) to the import path, since this is
834 -- what gcc does, and it's probably what you want.
835 let current_dir = getdir basename
837 paths <- readIORef include_paths
838 writeIORef include_paths (current_dir : paths)
840 -- build the hsc command line
841 hsc_opts <- build_hsc_opts
843 doing_hi <- readIORef produceHi
844 tmp_hi_file <- if doing_hi
845 then newTempName "hi"
848 -- tmp files for foreign export stub code
849 tmp_stub_h <- newTempName "stub_h"
850 tmp_stub_c <- newTempName "stub_c"
852 -- figure out where to put the .hi file
853 ohi <- readIORef output_hi
854 hisuf <- readIORef hi_suf
855 let hi_flags = case ohi of
856 Nothing -> [ "-hidir="++current_dir, "-hisuf="++hisuf ]
857 Just fn -> [ "-hifile="++fn ]
859 -- figure out if the source has changed, for recompilation avoidance.
860 -- only do this if we're eventually going to generate a .o file.
861 -- (ToDo: do when generating .hc files too?)
863 -- Setting source_unchanged to "-fsource_unchanged" means that M.o seems
864 -- to be up to date wrt M.hs; so no need to recompile unless imports have
865 -- changed (which the compiler itself figures out).
866 -- Setting source_unchanged to "" tells the compiler that M.o is out of
867 -- date wrt M.hs (or M.o doesn't exist) so we must recompile regardless.
868 do_recomp <- readIORef recomp
869 todo <- readIORef v_todo
870 o_file <- odir_ify (basename ++ '.':phase_input_ext Ln)
872 if not (do_recomp && ( todo == DoLink || todo == StopBefore Ln ))
874 else do t1 <- getModificationTime (basename ++ '.':suff)
875 o_file_exists <- doesFileExist o_file
877 then return "" -- Need to recompile
878 else do t2 <- getModificationTime o_file
880 then return "-fsource-unchanged"
884 run_something "Haskell Compiler"
885 (unwords (hsc : input_fn : (
890 "-ofile="++output_fn,
897 -- check whether compilation was performed, bail out if not
898 b <- doesFileExist output_fn
899 if not b && not (null source_unchanged) -- sanity
900 then do run_something "Touching object file"
903 else do -- carry on...
906 let stub_h = basename ++ "_stub.h"
907 let stub_c = basename ++ "_stub.c"
909 -- copy .h_stub file into current dir if present
910 b <- doesFileExist tmp_stub_h
912 run_something "Copy stub .h file"
913 ("cp " ++ tmp_stub_h ++ ' ':stub_h)
915 -- #include <..._stub.h> in .hc file
916 addCmdlineHCInclude tmp_stub_h -- hack
918 -- copy the _stub.c file into the current dir
919 run_something "Copy stub .c file"
921 "rm -f", stub_c, "&&",
922 "echo \'#include \""++stub_h++"\"\' >"++stub_c, " &&",
923 "cat", tmp_stub_c, ">> ", stub_c
926 -- compile the _stub.c file w/ gcc
927 pipeline <- genPipeline (StopBefore Ln) "" stub_c
928 run_pipeline pipeline stub_c False{-no linking-}
929 False{-no -o option-}
930 (basename++"_stub") "c"
932 add ld_inputs (basename++"_stub.o")
936 -----------------------------------------------------------------------------
939 -- we don't support preprocessing .c files (with -E) now. Doing so introduces
940 -- way too many hacks, and I can't say I've ever used it anyway.
942 run_phase cc_phase _basename _suff input_fn output_fn
943 | cc_phase == Cc || cc_phase == HCc
944 = do cc <- readIORef pgm_c
945 cc_opts <- (getOpts opt_c)
946 cmdline_include_dirs <- readIORef include_paths
948 let hcc = cc_phase == HCc
950 -- add package include paths even if we're just compiling
951 -- .c files; this is the Value Add(TM) that using
952 -- ghc instead of gcc gives you :)
953 pkg_include_dirs <- getPackageIncludePath
954 let include_paths = map (\p -> "-I"++p) (cmdline_include_dirs
957 c_includes <- getPackageCIncludes
958 cmdline_includes <- readState cmdline_hc_includes -- -#include options
960 let cc_injects | hcc = unlines (map mk_include
961 (c_includes ++ reverse cmdline_includes))
965 '"':_{-"-} -> "#include "++h_file
966 '<':_ -> "#include "++h_file
967 _ -> "#include \""++h_file++"\""
969 cc_help <- newTempName "c"
970 h <- openFile cc_help WriteMode
972 hPutStrLn h ("#include \"" ++ input_fn ++ "\"\n")
975 ccout <- newTempName "ccout"
977 mangle <- readIORef do_asm_mangling
978 (md_c_flags, md_regd_c_flags) <- machdepCCOpts
982 o2 <- readIORef opt_minus_o2_for_C
983 let opt_flag | o2 = "-O2"
986 pkg_extra_cc_opts <- getPackageExtraCcOpts
988 excessPrecision <- readState excess_precision
990 run_something "C Compiler"
991 (unwords ([ cc, "-x", "c", cc_help, "-o", output_fn ]
993 ++ (if cc_phase == HCc && mangle
996 ++ [ verb, "-S", "-Wimplicit", opt_flag ]
997 ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
999 #ifdef mingw32_TARGET_OS
1002 ++ (if excessPrecision then [] else [ "-ffloat-store" ])
1004 ++ pkg_extra_cc_opts
1009 -- ToDo: postprocess the output from gcc
1011 -----------------------------------------------------------------------------
1014 run_phase Mangle _basename _suff input_fn output_fn
1015 = do mangler <- readIORef pgm_m
1016 mangler_opts <- getOpts opt_m
1018 if (prefixMatch "i386" cTARGETPLATFORM)
1019 then do n_regs <- readState stolen_x86_regs
1020 return [ show n_regs ]
1022 run_something "Assembly Mangler"
1025 ++ [ input_fn, output_fn ]
1030 -----------------------------------------------------------------------------
1033 run_phase SplitMangle _basename _suff input_fn _output_fn
1034 = do splitter <- readIORef pgm_s
1036 -- this is the prefix used for the split .s files
1037 tmp_pfx <- readIORef tmpdir
1039 let split_s_prefix = tmp_pfx ++ "/ghc" ++ show x
1040 writeIORef split_prefix split_s_prefix
1041 addFilesToClean (split_s_prefix ++ "__*") -- d:-)
1043 -- allocate a tmp file to put the no. of split .s files in (sigh)
1044 n_files <- newTempName "n_files"
1046 run_something "Split Assembly File"
1053 -- save the number of split files for future references
1054 s <- readFile n_files
1055 let n = read s :: Int
1056 writeIORef n_split_files n
1059 -----------------------------------------------------------------------------
1062 run_phase As _basename _suff input_fn output_fn
1063 = do as <- readIORef pgm_a
1064 as_opts <- getOpts opt_a
1066 cmdline_include_paths <- readIORef include_paths
1067 let cmdline_include_flags = map (\p -> "-I"++p) cmdline_include_paths
1068 run_something "Assembler"
1069 (unwords (as : as_opts
1070 ++ cmdline_include_flags
1071 ++ [ "-c", input_fn, "-o", output_fn ]
1075 run_phase SplitAs basename _suff _input_fn _output_fn
1076 = do as <- readIORef pgm_a
1077 as_opts <- getOpts opt_a
1079 split_s_prefix <- readIORef split_prefix
1080 n <- readIORef n_split_files
1082 odir <- readIORef output_dir
1083 let real_odir = case odir of
1087 let assemble_file n = do
1088 let input_s = split_s_prefix ++ "__" ++ show n ++ ".s"
1089 let output_o = newdir real_odir
1090 (basename ++ "__" ++ show n ++ ".o")
1091 real_o <- osuf_ify output_o
1092 run_something "Assembler"
1093 (unwords (as : as_opts
1094 ++ [ "-c", "-o", real_o, input_s ]
1097 mapM_ assemble_file [1..n]
1100 -----------------------------------------------------------------------------
1103 do_link :: [String] -> IO ()
1104 do_link o_files = do
1105 ln <- readIORef pgm_l
1107 o_file <- readIORef output_file
1108 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1110 pkg_lib_paths <- getPackageLibraryPath
1111 let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
1113 lib_paths <- readIORef library_paths
1114 let lib_path_opts = map ("-L"++) lib_paths
1116 pkg_libs <- getPackageLibraries
1117 let pkg_lib_opts = map (\lib -> "-l"++lib) pkg_libs
1119 libs <- readIORef cmdline_libraries
1120 let lib_opts = map ("-l"++) (reverse libs)
1121 -- reverse because they're added in reverse order from the cmd line
1123 pkg_extra_ld_opts <- getPackageExtraLdOpts
1125 -- probably _stub.o files
1126 extra_ld_inputs <- readIORef ld_inputs
1128 -- opts from -optl-<blah>
1129 extra_ld_opts <- getOpts opt_l
1131 run_something "Linker"
1133 ([ ln, verb, "-o", output_fn ]
1138 ++ pkg_lib_path_opts
1140 ++ pkg_extra_ld_opts
1145 -----------------------------------------------------------------------------
1146 -- compatibility code
1148 #if __GLASGOW_HASKELL__ <= 408
1150 ioErrors = justIoErrors
1153 #ifdef mingw32_TARGET_OS
1154 foreign import "_getpid" getProcessID :: IO Int