1 -----------------------------------------------------------------------------
4 -- (c) Simon Marlow 2000
6 -----------------------------------------------------------------------------
8 -- with path so that ghc -M can find config.h
9 #include "../includes/config.h"
11 module Main (main) where
18 #ifndef mingw32_TARGET_OS
34 #ifdef mingw32_TARGET_OS
35 foreign import "_getpid" getProcessID :: IO Int
38 #define GLOBAL_VAR(name,value,ty) \
39 name = global (value) :: IORef (ty); \
42 -----------------------------------------------------------------------------
45 -- time commands when run with -v
50 -- Win32 support: proper signal handling
51 -- make sure OPTIONS in .hs file propogate to .hc file if -C or -keep-hc-file-too
52 -- reading the package configuration file is too slow
54 -----------------------------------------------------------------------------
55 -- Differences vs. old driver:
57 -- No more "Enter your Haskell program, end with ^D (on a line of its own):"
58 -- consistency checking removed (may do this properly later)
60 -- no hi diffs (could be added later)
63 -----------------------------------------------------------------------------
64 -- non-configured things
66 cHaskell1Version = "5" -- i.e., Haskell 98
68 -----------------------------------------------------------------------------
72 hPutStr stderr "\nUsage: For basic information, try the `-help' option.\n"
76 let usage_file = "ghc-usage.txt"
77 usage_path = findFile usage_file (cGHC_DRIVER_DIR ++ '/':usage_file)
78 usage <- readFile usage_path
83 dump ('$':'$':s) = hPutStr stderr get_prog_name >> dump s
84 dump (c:s) = hPutChar stderr c >> dump s
86 version_str = cProjectVersion ++
87 ( if cProjectPatchLevel /= "0" && cProjectPatchLevel /= ""
88 then '.':cProjectPatchLevel
91 -----------------------------------------------------------------------------
95 Phase of the | Suffix saying | Flag saying | (suffix of)
96 compilation system | ``start here''| ``stop after''| output file
98 literate pre-processor | .lhs | - | -
99 C pre-processor (opt.) | - | -E | -
100 Haskell compiler | .hs | -C, -S | .hc, .s
101 C compiler (opt.) | .hc or .c | -S | .s
102 assembler | .s or .S | -c | .o
103 linker | other | - | a.out
107 = MkDependHS -- haskell dependency generation
112 | HCc -- Haskellised C (as opposed to vanilla C) compilation
113 | Mangle -- assembly mangling, now done by a separate script.
114 | SplitMangle -- after mangler if splitting
118 deriving (Eq,Ord,Enum,Ix,Show,Bounded)
120 initial_phase = Unlit
122 -----------------------------------------------------------------------------
126 = UnknownFileType String
129 | MultipleSrcsOneOutput
130 | UnknownPackage String
131 | WayCombinationNotSupported [WayName]
132 | PhaseFailed String ExitCode
138 GLOBAL_VAR(prog_name, "ghc", String)
140 get_prog_name = unsafePerformIO (readIORef prog_name) -- urk!
142 instance Show BarfKind where
144 = showString get_prog_name . showString ": " . showBarf e
146 showBarf AmbiguousPhase
147 = showString "only one of the flags -M, -E, -C, -S, -c is allowed"
148 showBarf (UnknownFileType s)
149 = showString "unknown file type, and linking not done: " . showString s
150 showBarf (UnknownFlag s)
151 = showString "unrecognised flag: " . showString s
152 showBarf MultipleSrcsOneOutput
153 = showString "can't apply -o option to multiple source files"
154 showBarf (UnknownPackage s)
155 = showString "unknown package name: " . showString s
156 showBarf (WayCombinationNotSupported ws)
157 = showString "combination not supported: "
158 . foldr1 (\a b -> a . showChar '/' . b)
159 (map (showString . wayName . lkupWay) ws)
160 showBarf (NoInputFiles)
161 = showString "no input files"
162 showBarf (OtherError str)
165 barfKindTc = mkTyCon "BarfKind"
167 instance Typeable BarfKind where
168 typeOf _ = mkAppTy barfKindTc []
170 -----------------------------------------------------------------------------
173 GLOBAL_VAR(files_to_clean, [], [String])
174 GLOBAL_VAR(keep_tmp_files, False, Bool)
176 cleanTempFiles :: IO ()
178 forget_it <- readIORef keep_tmp_files
179 unless forget_it $ do
181 fs <- readIORef files_to_clean
182 verb <- readIORef verbose
185 (do on verb (hPutStrLn stderr ("removing: " ++ f))
186 if '*' `elem` f then system ("rm -f " ++ f) >> return ()
189 (\e -> on verb (hPutStrLn stderr
190 ("warning: can't remove tmp file" ++ f)))
193 -----------------------------------------------------------------------------
194 -- Which phase to stop at
196 GLOBAL_VAR(stop_after, Ln, Phase)
198 end_phase_flag :: String -> Maybe Phase
199 end_phase_flag "-M" = Just MkDependHS
200 end_phase_flag "-E" = Just Cpp
201 end_phase_flag "-C" = Just Hsc
202 end_phase_flag "-S" = Just Mangle
203 end_phase_flag "-c" = Just As
204 end_phase_flag _ = Nothing
206 getStopAfter :: [String]
207 -> IO ( [String] -- rest of command line
208 , Phase -- stop after phase
209 , Bool -- do linking?
212 = case my_partition end_phase_flag flags of
213 ([] , rest) -> return (rest, As, True)
214 ([one], rest) -> return (rest, one, False)
215 (_ , rest) -> throwDyn AmbiguousPhase
217 -----------------------------------------------------------------------------
218 -- Global compilation flags
221 GLOBAL_VAR(cpp_flag, False, Bool)
222 hs_source_cpp_opts = global
223 [ "-D__HASKELL1__="++cHaskell1Version
224 , "-D__GLASGOW_HASKELL__="++cProjectVersionInt
226 , "-D__CONCURRENT_HASKELL__"
229 -- Keep output from intermediate phases
230 GLOBAL_VAR(keep_hi_diffs, False, Bool)
231 GLOBAL_VAR(keep_hc_files, False, Bool)
232 GLOBAL_VAR(keep_s_files, False, Bool)
233 GLOBAL_VAR(keep_raw_s_files, False, Bool)
235 -- Compiler RTS options
236 GLOBAL_VAR(specific_heap_size, 6 * 1000 * 1000, Integer)
237 GLOBAL_VAR(specific_stack_size, 1000 * 1000, Integer)
238 GLOBAL_VAR(scale_sizes_by, 1.0, Double)
241 GLOBAL_VAR(verbose, False, Bool)
242 is_verbose = do v <- readIORef verbose; if v then return "-v" else return ""
245 GLOBAL_VAR(dry_run, False, Bool)
246 GLOBAL_VAR(recomp, True, Bool)
247 GLOBAL_VAR(tmp_prefix, cTMPDIR, String)
248 GLOBAL_VAR(stolen_x86_regs, 4, Int)
249 #if !defined(HAVE_WIN32_DLL_SUPPORT) || defined(DONT_WANT_WIN32_DLL_SUPPORT)
250 GLOBAL_VAR(static, True, Bool)
252 GLOBAL_VAR(static, False, Bool)
254 GLOBAL_VAR(collect_ghc_timing, False, Bool)
255 GLOBAL_VAR(do_asm_mangling, True, Bool)
256 GLOBAL_VAR(excess_precision, False, Bool)
258 -----------------------------------------------------------------------------
259 -- Splitting object files (for libraries)
261 GLOBAL_VAR(split_object_files, False, Bool)
262 GLOBAL_VAR(split_prefix, "", String)
263 GLOBAL_VAR(n_split_files, 0, Int)
266 can_split = prefixMatch "i386" cTARGETPLATFORM
267 || prefixMatch "alpha" cTARGETPLATFORM
268 || prefixMatch "hppa" cTARGETPLATFORM
269 || prefixMatch "m68k" cTARGETPLATFORM
270 || prefixMatch "mips" cTARGETPLATFORM
271 || prefixMatch "powerpc" cTARGETPLATFORM
272 || prefixMatch "rs6000" cTARGETPLATFORM
273 || prefixMatch "sparc" cTARGETPLATFORM
275 -----------------------------------------------------------------------------
276 -- Compiler output options
283 GLOBAL_VAR(hsc_lang, if cGhcWithNativeCodeGen == "YES" &&
284 (prefixMatch "i386" cTARGETPLATFORM ||
285 prefixMatch "sparc" cTARGETPLATFORM)
290 GLOBAL_VAR(output_dir, Nothing, Maybe String)
291 GLOBAL_VAR(output_suf, Nothing, Maybe String)
292 GLOBAL_VAR(output_file, Nothing, Maybe String)
293 GLOBAL_VAR(output_hi, Nothing, Maybe String)
295 GLOBAL_VAR(ld_inputs, [], [String])
297 odir_ify :: String -> IO String
299 odir_opt <- readIORef output_dir
302 Just d -> return (newdir d f)
304 osuf_ify :: String -> IO String
306 osuf_opt <- readIORef output_suf
309 Just s -> return (newsuf s f)
311 -----------------------------------------------------------------------------
314 GLOBAL_VAR(produceHi, True, Bool)
315 GLOBAL_VAR(hi_on_stdout, False, Bool)
316 GLOBAL_VAR(hi_with, "", String)
317 GLOBAL_VAR(hi_suf, "hi", String)
319 data HiDiffFlag = NormalHiDiffs | UsageHiDiffs | NoHiDiffs
320 GLOBAL_VAR(hi_diffs, NoHiDiffs, HiDiffFlag)
322 -----------------------------------------------------------------------------
323 -- Warnings & sanity checking
325 -- Warning packages that are controlled by -W and -Wall. The 'standard'
326 -- warnings that you get all the time are
328 -- -fwarn-overlapping-patterns
329 -- -fwarn-missing-methods
330 -- -fwarn-missing-fields
331 -- -fwarn-deprecations
332 -- -fwarn-duplicate-exports
334 -- these are turned off by -Wnot.
336 standardWarnings = [ "-fwarn-overlapping-patterns"
337 , "-fwarn-missing-methods"
338 , "-fwarn-missing-fields"
339 , "-fwarn-deprecations"
340 , "-fwarn-duplicate-exports"
342 minusWOpts = standardWarnings ++
343 [ "-fwarn-unused-binds"
344 , "-fwarn-unused-matches"
345 , "-fwarn-incomplete-patterns"
346 , "-fwarn-unused-imports"
348 minusWallOpts = minusWOpts ++
349 [ "-fwarn-type-defaults"
350 , "-fwarn-name-shadowing"
351 , "-fwarn-missing-signatures"
354 data WarningState = W_default | W_ | W_all | W_not
356 GLOBAL_VAR(warning_opt, W_default, WarningState)
358 -----------------------------------------------------------------------------
359 -- Compiler optimisation options
361 GLOBAL_VAR(opt_level, 0, Int)
363 setOptLevel :: String -> IO ()
364 setOptLevel "" = do { writeIORef opt_level 1; go_via_C }
365 setOptLevel "not" = writeIORef opt_level 0
366 setOptLevel [c] | isDigit c = do
367 let level = ord c - ord '0'
368 writeIORef opt_level level
369 on (level >= 1) go_via_C
370 setOptLevel s = throwDyn (UnknownFlag ("-O"++s))
373 l <- readIORef hsc_lang
374 case l of { HscAsm -> writeIORef hsc_lang HscC;
375 _other -> return () }
377 GLOBAL_VAR(opt_minus_o2_for_C, False, Bool)
379 GLOBAL_VAR(opt_MaxSimplifierIterations, 4, Int)
380 GLOBAL_VAR(opt_StgStats, False, Bool)
381 GLOBAL_VAR(opt_UsageSPInf, False, Bool) -- Off by default
383 hsc_minusO2_flags = hsc_minusO_flags -- for now
385 hsc_minusNoO_flags = do
386 iter <- readIORef opt_MaxSimplifierIterations
388 "-fignore-interface-pragmas",
389 "-fomit-interface-pragmas",
392 "-fmax-simplifier-iterations" ++ show iter,
396 hsc_minusO_flags = do
397 iter <- readIORef opt_MaxSimplifierIterations
398 usageSP <- readIORef opt_UsageSPInf
399 stgstats <- readIORef opt_StgStats
404 "-fdo-eta-reduction",
405 "-fdo-lambda-eta-expansion",
410 -- initial simplify: mk specialiser happy: minimum effort please
415 -- Don't inline anything till full laziness has bitten
416 -- In particular, inlining wrappers inhibits floating
417 -- e.g. ...(case f x of ...)...
418 -- ==> ...(case (case x of I# x# -> fw x#) of ...)...
419 -- ==> ...(case x of I# x# -> case fw x# of ...)...
420 -- and now the redex (f x) isn't floatable any more
423 -- Similarly, don't apply any rules until after full
424 -- laziness. Notably, list fusion can prevent floating.
427 -- Don't do case-of-case transformations.
428 -- This makes full laziness work better
430 "-fmax-simplifier-iterations2",
433 -- Specialisation is best done before full laziness
434 -- so that overloaded functions have all their dictionary lambdas manifest
443 -- Want to run with inline phase 1 after the specialiser to give
444 -- maximum chance for fusion to work before we inline build/augment
445 -- in phase 2. This made a difference in 'ansi' where an
446 -- overloaded function wasn't inlined till too late.
447 "-fmax-simplifier-iterations" ++ show iter,
450 -- infer usage information here in case we need it later.
451 -- (add more of these where you need them --KSW 1999-04)
452 if usageSP then "-fusagesp" else "",
456 -- Need inline-phase2 here so that build/augment get
457 -- inlined. I found that spectral/hartel/genfft lost some useful
458 -- strictness in the function sumcode' if augment is not inlined
459 -- before strictness analysis runs
462 "-fmax-simplifier-iterations2",
468 "-fmax-simplifier-iterations2",
469 -- No -finline-phase: allow all Ids to be inlined now
470 -- This gets foldr inlined before strictness analysis
479 "-fmax-simplifier-iterations" ++ show iter,
480 -- No -finline-phase: allow all Ids to be inlined now
484 -- nofib/spectral/hartel/wang doubles in speed if you
485 -- do full laziness late in the day. It only happens
486 -- after fusion and other stuff, so the early pass doesn't
487 -- catch it. For the record, the redex is
488 -- f_el22 (f_el21 r_midblock)
490 -- Leave out lambda lifting for now
491 -- "-fsimplify", -- Tidy up results of full laziness
493 -- "-fmax-simplifier-iterations2",
495 -- "-ffloat-outwards-full",
497 -- We want CSE to follow the final full-laziness pass, because it may
498 -- succeed in commoning up things floated out by full laziness.
500 -- CSE must immediately follow a simplification pass, because it relies
501 -- on the no-shadowing invariant. See comments at the top of CSE.lhs
502 -- So it must NOT follow float-inwards, which can give rise to shadowing,
503 -- even if its input doesn't have shadows. Hence putting it between
510 -- Case-liberation for -O2. This should be after
511 -- strictness analysis and the simplification which follows it.
513 -- ( ($OptLevel != 2)
515 -- : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
517 -- "-fliberate-case",
519 -- Final clean-up simplification:
522 "-fmax-simplifier-iterations" ++ show iter,
523 -- No -finline-phase: allow all Ids to be inlined now
528 -----------------------------------------------------------------------------
531 split_marker = ':' -- not configurable
533 import_paths, include_paths, library_paths :: IORef [String]
534 GLOBAL_VAR(import_paths, ["."], [String])
535 GLOBAL_VAR(include_paths, ["."], [String])
536 GLOBAL_VAR(library_paths, [], [String])
538 GLOBAL_VAR(cmdline_libraries, [], [String])
539 GLOBAL_VAR(cmdline_hc_includes, [], [String])
541 augment_import_paths :: String -> IO ()
542 augment_import_paths "" = writeIORef import_paths []
543 augment_import_paths path
544 = do paths <- readIORef import_paths
545 writeIORef import_paths (paths ++ dirs)
546 where dirs = split split_marker path
548 augment_include_paths :: String -> IO ()
549 augment_include_paths path
550 = do paths <- readIORef include_paths
551 writeIORef include_paths (paths ++ split split_marker path)
553 augment_library_paths :: String -> IO ()
554 augment_library_paths path
555 = do paths <- readIORef library_paths
556 writeIORef library_paths (paths ++ split split_marker path)
558 -----------------------------------------------------------------------------
561 GLOBAL_VAR(package_config, (findFile "package.conf" (cGHC_DRIVER_DIR++"/package.conf.inplace")), String)
563 listPackages :: IO ()
565 details <- readIORef package_details
566 hPutStr stdout (listPkgs details)
573 details <- readIORef package_details
574 hPutStr stdout "Reading package info from stdin... "
576 let new_pkg = read stuff :: (String,Package)
578 (\e -> throwDyn (OtherError "parse error in package info"))
579 hPutStrLn stdout "done."
580 if (fst new_pkg `elem` map fst details)
581 then throwDyn (OtherError ("package `" ++ fst new_pkg ++
582 "' already installed"))
584 conf_file <- readIORef package_config
585 savePackageConfig conf_file
586 maybeRestoreOldConfig conf_file $ do
587 writeNewConfig conf_file ( ++ [new_pkg])
590 deletePackage :: String -> IO ()
591 deletePackage pkg = do
593 details <- readIORef package_details
594 if (pkg `notElem` map fst details)
595 then throwDyn (OtherError ("package `" ++ pkg ++ "' not installed"))
597 conf_file <- readIORef package_config
598 savePackageConfig conf_file
599 maybeRestoreOldConfig conf_file $ do
600 writeNewConfig conf_file (filter ((/= pkg) . fst))
603 checkConfigAccess :: IO ()
604 checkConfigAccess = do
605 conf_file <- readIORef package_config
606 access <- getPermissions conf_file
607 unless (writable access)
608 (throwDyn (OtherError "you don't have permission to modify the package configuration file"))
610 maybeRestoreOldConfig :: String -> IO () -> IO ()
611 maybeRestoreOldConfig conf_file io
612 = catchAllIO io (\e -> do
613 hPutStr stdout "\nWARNING: an error was encountered while the new \n\
614 \configuration was being written. Attempting to \n\
615 \restore the old configuration... "
616 system ("cp " ++ conf_file ++ ".old " ++ conf_file)
617 hPutStrLn stdout "done."
621 writeNewConfig :: String -> ([(String,Package)] -> [(String,Package)]) -> IO ()
622 writeNewConfig conf_file fn = do
623 hPutStr stdout "Writing new package config file... "
624 old_details <- readIORef package_details
625 h <- openFile conf_file WriteMode
626 hPutStr h (dumpPackages (fn old_details))
628 hPutStrLn stdout "done."
630 savePackageConfig :: String -> IO ()
631 savePackageConfig conf_file = do
632 hPutStr stdout "Saving old package config file... "
633 -- mv rather than cp because we've already done an hGetContents
634 -- on this file so we won't be able to open it for writing
635 -- unless we move the old one out of the way...
636 system ("mv " ++ conf_file ++ " " ++ conf_file ++ ".old")
637 hPutStrLn stdout "done."
639 -- package list is maintained in dependency order
640 packages = global ["std", "rts", "gmp"] :: IORef [String]
641 -- comma in value, so can't use macro, grrr
642 {-# NOINLINE packages #-}
644 addPackage :: String -> IO ()
646 = do pkg_details <- readIORef package_details
647 case lookup package pkg_details of
648 Nothing -> throwDyn (UnknownPackage package)
650 ps <- readIORef packages
651 unless (package `elem` ps) $ do
652 mapM_ addPackage (package_deps details)
653 ps <- readIORef packages
654 writeIORef packages (package:ps)
656 getPackageImportPath :: IO [String]
657 getPackageImportPath = do
658 ps <- readIORef packages
659 ps' <- getPackageDetails ps
660 return (nub (concat (map import_dirs ps')))
662 getPackageIncludePath :: IO [String]
663 getPackageIncludePath = do
664 ps <- readIORef packages
665 ps' <- getPackageDetails ps
666 return (nub (filter (not.null) (concatMap include_dirs ps')))
668 -- includes are in reverse dependency order (i.e. rts first)
669 getPackageCIncludes :: IO [String]
670 getPackageCIncludes = do
671 ps <- readIORef packages
672 ps' <- getPackageDetails ps
673 return (reverse (nub (filter (not.null) (concatMap c_includes ps'))))
675 getPackageLibraryPath :: IO [String]
676 getPackageLibraryPath = do
677 ps <- readIORef packages
678 ps' <- getPackageDetails ps
679 return (nub (concat (map library_dirs ps')))
681 getPackageLibraries :: IO [String]
682 getPackageLibraries = do
683 ps <- readIORef packages
684 ps' <- getPackageDetails ps
685 tag <- readIORef build_tag
686 let suffix = if null tag then "" else '_':tag
688 map (\p -> map (++suffix) (hs_libraries p) ++ extra_libraries p) ps'
691 getPackageExtraGhcOpts :: IO [String]
692 getPackageExtraGhcOpts = do
693 ps <- readIORef packages
694 ps' <- getPackageDetails ps
695 return (concatMap extra_ghc_opts ps')
697 getPackageExtraCcOpts :: IO [String]
698 getPackageExtraCcOpts = do
699 ps <- readIORef packages
700 ps' <- getPackageDetails ps
701 return (concatMap extra_cc_opts ps')
703 getPackageExtraLdOpts :: IO [String]
704 getPackageExtraLdOpts = do
705 ps <- readIORef packages
706 ps' <- getPackageDetails ps
707 return (concatMap extra_ld_opts ps')
709 getPackageDetails :: [String] -> IO [Package]
710 getPackageDetails ps = do
711 pkg_details <- readIORef package_details
712 return [ pkg | p <- ps, Just pkg <- [ lookup p pkg_details ] ]
714 GLOBAL_VAR(package_details, (error "package_details"), [(String,Package)])
716 -----------------------------------------------------------------------------
719 -- The central concept of a "way" is that all objects in a given
720 -- program must be compiled in the same "way". Certain options change
721 -- parameters of the virtual machine, eg. profiling adds an extra word
722 -- to the object header, so profiling objects cannot be linked with
723 -- non-profiling objects.
725 -- After parsing the command-line options, we determine which "way" we
726 -- are building - this might be a combination way, eg. profiling+ticky-ticky.
728 -- We then find the "build-tag" associated with this way, and this
729 -- becomes the suffix used to find .hi files and libraries used in
732 GLOBAL_VAR(build_tag, "", String)
762 GLOBAL_VAR(ways, [] ,[WayName])
764 -- ToDo: allow WayDll with any other allowed combination
766 allowed_combinations =
767 [ [WayProf,WayUnreg],
768 [WayProf,WaySMP] -- works???
771 findBuildTag :: IO [String] -- new options
773 way_names <- readIORef ways
774 case sort way_names of
775 [] -> do writeIORef build_tag ""
778 [w] -> do let details = lkupWay w
779 writeIORef build_tag (wayTag details)
780 return (wayOpts details)
782 ws -> if ws `notElem` allowed_combinations
783 then throwDyn (WayCombinationNotSupported ws)
784 else let stuff = map lkupWay ws
785 tag = concat (map wayTag stuff)
786 flags = map wayOpts stuff
788 writeIORef build_tag tag
789 return (concat flags)
792 case lookup w way_details of
793 Nothing -> error "findBuildTag"
794 Just details -> details
802 way_details :: [ (WayName, Way) ]
804 [ (WayProf, Way "p" "Profiling"
810 (WayTicky, Way "t" "Ticky-ticky Profiling"
813 , "-optc-DTICKY_TICKY"
816 (WayUnreg, Way "u" "Unregisterised"
818 , "-optc-DUSE_MINIINTERPRETER"
819 , "-fno-asm-mangling"
823 (WayDll, Way "dll" "DLLized"
826 (WayPar, Way "mp" "Parallel"
829 , "-D__PARALLEL_HASKELL__"
831 , "-package concurrent"
834 (WayGran, Way "mg" "Gransim"
839 , "-package concurrent"
842 (WaySMP, Way "s" "SMP"
849 (WayUser_a, Way "a" "User way 'a'" ["$WAY_a_REAL_OPTS"]),
850 (WayUser_b, Way "b" "User way 'b'" ["$WAY_b_REAL_OPTS"]),
851 (WayUser_c, Way "c" "User way 'c'" ["$WAY_c_REAL_OPTS"]),
852 (WayUser_d, Way "d" "User way 'd'" ["$WAY_d_REAL_OPTS"]),
853 (WayUser_e, Way "e" "User way 'e'" ["$WAY_e_REAL_OPTS"]),
854 (WayUser_f, Way "f" "User way 'f'" ["$WAY_f_REAL_OPTS"]),
855 (WayUser_g, Way "g" "User way 'g'" ["$WAY_g_REAL_OPTS"]),
856 (WayUser_h, Way "h" "User way 'h'" ["$WAY_h_REAL_OPTS"]),
857 (WayUser_i, Way "i" "User way 'i'" ["$WAY_i_REAL_OPTS"]),
858 (WayUser_j, Way "j" "User way 'j'" ["$WAY_j_REAL_OPTS"]),
859 (WayUser_k, Way "k" "User way 'k'" ["$WAY_k_REAL_OPTS"]),
860 (WayUser_l, Way "l" "User way 'l'" ["$WAY_l_REAL_OPTS"]),
861 (WayUser_m, Way "m" "User way 'm'" ["$WAY_m_REAL_OPTS"]),
862 (WayUser_n, Way "n" "User way 'n'" ["$WAY_n_REAL_OPTS"]),
863 (WayUser_o, Way "o" "User way 'o'" ["$WAY_o_REAL_OPTS"]),
864 (WayUser_A, Way "A" "User way 'A'" ["$WAY_A_REAL_OPTS"]),
865 (WayUser_B, Way "B" "User way 'B'" ["$WAY_B_REAL_OPTS"])
868 -----------------------------------------------------------------------------
869 -- Programs for particular phases
871 GLOBAL_VAR(pgm_dep, findFile "mkdependHS" cGHC_MKDEPENDHS, String)
872 GLOBAL_VAR(pgm_L, findFile "unlit" cGHC_UNLIT, String)
873 GLOBAL_VAR(pgm_P, cRAWCPP, String)
874 GLOBAL_VAR(pgm_C, findFile "hsc" cGHC_HSC, String)
875 GLOBAL_VAR(pgm_c, cGCC, String)
876 GLOBAL_VAR(pgm_m, findFile "ghc-asm" cGHC_MANGLER, String)
877 GLOBAL_VAR(pgm_s, findFile "ghc-split" cGHC_SPLIT, String)
878 GLOBAL_VAR(pgm_a, cGCC, String)
879 GLOBAL_VAR(pgm_l, cGCC, String)
881 -----------------------------------------------------------------------------
882 -- Options for particular phases
884 GLOBAL_VAR(opt_dep, [], [String])
885 GLOBAL_VAR(opt_L, [], [String])
886 GLOBAL_VAR(opt_P, [], [String])
887 GLOBAL_VAR(opt_C, [], [String])
888 GLOBAL_VAR(opt_Crts, [], [String])
889 GLOBAL_VAR(opt_c, [], [String])
890 GLOBAL_VAR(opt_a, [], [String])
891 GLOBAL_VAR(opt_m, [], [String])
892 GLOBAL_VAR(opt_l, [], [String])
893 GLOBAL_VAR(opt_dll, [], [String])
895 -- we add to the options from the front, so we need to reverse the list
896 getOpts :: IORef [String] -> IO [String]
897 getOpts opts = readIORef opts >>= return . reverse
899 GLOBAL_VAR(anti_opt_C, [], [String])
901 -----------------------------------------------------------------------------
902 -- Via-C compilation stuff
904 -- flags returned are: ( all C compilations
905 -- , registerised HC compilations
909 | prefixMatch "alpha" cTARGETPLATFORM
910 = return ( ["-static"], [] )
912 | prefixMatch "hppa" cTARGETPLATFORM
913 -- ___HPUX_SOURCE, not _HPUX_SOURCE, is #defined if -ansi!
914 -- (very nice, but too bad the HP /usr/include files don't agree.)
915 = return ( ["-static", "-D_HPUX_SOURCE"], [] )
917 | prefixMatch "m68k" cTARGETPLATFORM
918 -- -fno-defer-pop : for the .hc files, we want all the pushing/
919 -- popping of args to routines to be explicit; if we let things
920 -- be deferred 'til after an STGJUMP, imminent death is certain!
922 -- -fomit-frame-pointer : *don't*
923 -- It's better to have a6 completely tied up being a frame pointer
924 -- rather than let GCC pick random things to do with it.
925 -- (If we want to steal a6, then we would try to do things
926 -- as on iX86, where we *do* steal the frame pointer [%ebp].)
927 = return ( [], ["-fno-defer-pop", "-fno-omit-frame-pointer"] )
929 | prefixMatch "i386" cTARGETPLATFORM
930 -- -fno-defer-pop : basically the same game as for m68k
932 -- -fomit-frame-pointer : *must* in .hc files; because we're stealing
933 -- the fp (%ebp) for our register maps.
934 = do n_regs <- readIORef stolen_x86_regs
935 sta <- readIORef static
936 return ( [ if sta then "-DDONT_WANT_WIN32_DLL_SUPPORT" else "" ],
937 [ "-fno-defer-pop", "-fomit-frame-pointer",
938 "-DSTOLEN_X86_REGS="++show n_regs ]
941 | prefixMatch "mips" cTARGETPLATFORM
942 = return ( ["static"], [] )
944 | prefixMatch "powerpc" cTARGETPLATFORM || prefixMatch "rs6000" cTARGETPLATFORM
945 = return ( ["static"], ["-finhibit-size-directive"] )
950 -----------------------------------------------------------------------------
951 -- Build the Hsc command line
953 build_hsc_opts :: IO [String]
955 opt_C_ <- getOpts opt_C -- misc hsc opts
958 warn_level <- readIORef warning_opt
959 let warn_opts = case warn_level of
960 W_default -> standardWarnings
962 W_all -> minusWallOpts
966 minus_o <- readIORef opt_level
969 0 -> hsc_minusNoO_flags
970 1 -> hsc_minusO_flags
971 2 -> hsc_minusO2_flags
975 ways_ <- readIORef ways
976 let stg_massage | WayProf `elem` ways_ = "-fmassage-stg-for-profiling"
979 stg_stats <- readIORef opt_StgStats
980 let stg_stats_flag | stg_stats = "-dstg-stats"
983 let stg_opts = [ stg_massage, stg_stats_flag, "-flet-no-escape" ]
984 -- let-no-escape always on for now
987 let hi_vers = "-fhi-version="++cProjectVersionInt
988 static <- (do s <- readIORef static; if s then return "-static" else return "")
990 l <- readIORef hsc_lang
993 HscAsm -> "-olang=asm"
994 HscJava -> "-olang=java"
996 -- get hi-file suffix
997 hisuf <- readIORef hi_suf
999 -- hi-suffix for packages depends on the build tag.
1001 do tag <- readIORef build_tag
1004 else return (tag ++ "_hi")
1006 import_dirs <- readIORef import_paths
1007 package_import_dirs <- getPackageImportPath
1009 let hi_map = "-himap=" ++
1010 makeHiMap import_dirs hisuf
1011 package_import_dirs package_hisuf
1014 hi_map_sep = "-himap-sep=" ++ [split_marker]
1016 scale <- readIORef scale_sizes_by
1017 heap <- readIORef specific_heap_size
1018 stack <- readIORef specific_stack_size
1019 cmdline_rts_opts <- getOpts opt_Crts
1020 let heap' = truncate (fromIntegral heap * scale) :: Integer
1021 stack' = truncate (fromIntegral stack * scale) :: Integer
1022 rts_opts = [ "+RTS", "-H"++show heap', "-K"++show stack' ]
1023 ++ cmdline_rts_opts ++ [ "-RTS" ]
1025 -- take into account -fno-* flags by removing the equivalent -f*
1026 -- flag from our list.
1027 anti_flags <- getOpts anti_opt_C
1028 let basic_opts = opt_C_ ++ warn_opts ++ optimisation_opts ++ stg_opts
1029 filtered_opts = filter (`notElem` anti_flags) basic_opts
1034 -- ToDo: C stub files
1035 ++ [ hi_vers, static, verb, lang, hi_map, hi_map_sep ]
1040 (import_dirs :: [String])
1041 (hi_suffix :: String)
1042 (package_import_dirs :: [String])
1043 (package_hi_suffix :: String)
1044 (split_marker :: Char)
1045 = foldr (add_dir hi_suffix)
1046 (foldr (add_dir package_hi_suffix) "" package_import_dirs)
1049 add_dir hisuf dir str = dir ++ "%." ++ hisuf ++ split_marker : str
1052 getOptionsFromSource
1053 :: String -- input file
1054 -> IO [String] -- options, if any
1055 getOptionsFromSource file
1056 = do h <- openFile file ReadMode
1062 () | null l -> look h
1063 | prefixMatch "#" l -> look h
1064 | prefixMatch "{-# LINE" l -> look h
1065 | Just (opts:_) <- matchRegex optionRegex l
1066 -> return (words opts)
1067 | otherwise -> return []
1069 optionRegex = mkRegex "{-#[ \t]+OPTIONS[ \t]+(.*)#-}"
1071 -----------------------------------------------------------------------------
1074 get_source_files :: [String] -> ([String],[String])
1075 get_source_files = partition (('-' /=) . head)
1077 suffixes :: [(String,Phase)]
1089 phase_input_ext Unlit = "lhs"
1090 phase_input_ext Cpp = "lpp"
1091 phase_input_ext Hsc = "cpp"
1092 phase_input_ext HCc = "hc"
1093 phase_input_ext Cc = "c"
1094 phase_input_ext Mangle = "raw_s"
1095 phase_input_ext SplitMangle = "split_s" -- not really generated
1096 phase_input_ext As = "s"
1097 phase_input_ext SplitAs = "split_s" -- not really generated
1098 phase_input_ext Ln = "o"
1100 find_phase :: String -> ([(Phase,String)], [String])
1101 -> ([(Phase,String)], [String])
1102 find_phase f (phase_srcs, unknown_srcs)
1103 = case lookup ext suffixes of
1104 Just the_phase -> ((the_phase,f):phase_srcs, unknown_srcs)
1105 Nothing -> (phase_srcs, f:unknown_srcs)
1106 where (basename,ext) = split_filename f
1109 find_phases srcs = (phase_srcs, unknown_srcs)
1110 where (phase_srcs, unknown_srcs) = foldr find_phase ([],[]) srcs
1113 -- all error messages are propagated as exceptions
1114 my_catchDyn (\dyn -> case dyn of
1115 PhaseFailed phase code -> exitWith code
1116 Interrupted -> exitWith (ExitFailure 1)
1117 _ -> do hPutStrLn stderr (show (dyn :: BarfKind))
1118 exitWith (ExitFailure 1)) $
1120 later cleanTempFiles $
1121 -- exceptions will be blocked while we clean the temporary files,
1122 -- so there shouldn't be any difficulty if we receive further
1126 -- install signal handlers
1127 main_thread <- myThreadId
1129 #ifndef mingw32_TARGET_OS
1130 let sig_handler = Catch (raiseInThread main_thread
1131 (DynException (toDyn Interrupted)))
1132 installHandler sigQUIT sig_handler Nothing
1133 installHandler sigINT sig_handler Nothing
1137 writeIORef prog_name pgm
1141 -- grab any -B options from the command line first
1142 argv' <- setTopDir argv
1144 -- read the package configuration
1145 conf_file <- readIORef package_config
1146 contents <- readFile conf_file
1147 writeIORef package_details (read contents)
1149 -- find the phase to stop after (i.e. -E, -C, -c, -S flags)
1150 (flags2, stop_phase, do_linking) <- getStopAfter argv'
1152 -- process all the other arguments, and get the source files
1153 srcs <- processArgs flags2 []
1155 -- find the build tag, and re-process the build-specific options
1156 more_opts <- findBuildTag
1157 _ <- processArgs more_opts []
1160 verb <- readIORef verbose
1162 when verb (hPutStrLn stderr ("Using package config file: " ++ conf_file))
1164 if stop_phase == MkDependHS -- mkdependHS is special
1165 then do_mkdependHS flags2 srcs
1168 -- for each source file, find which phase to start at
1169 let (phase_srcs, unknown_srcs) = find_phases srcs
1171 o_file <- readIORef output_file
1172 if isJust o_file && not do_linking && length phase_srcs > 1
1173 then throwDyn MultipleSrcsOneOutput
1176 if null unknown_srcs && null phase_srcs
1177 then throwDyn NoInputFiles
1180 -- if we have unknown files, and we're not doing linking, complain
1181 -- (otherwise pass them through to the linker).
1182 if not (null unknown_srcs) && not do_linking
1183 then throwDyn (UnknownFileType (head unknown_srcs))
1186 let compileFile :: (Phase, String) -> IO String
1187 compileFile (phase, src) = do
1188 let (orig_base, _) = split_filename src
1189 if phase < Ln -- anything to do?
1190 then run_pipeline stop_phase do_linking True orig_base (phase,src)
1193 o_files <- mapM compileFile phase_srcs
1196 do_link o_files unknown_srcs
1199 -- The following compilation pipeline algorithm is fairly hacky. A
1200 -- better way to do this would be to express the whole comilation as a
1201 -- data flow DAG, where the nodes are the intermediate files and the
1202 -- edges are the compilation phases. This framework would also work
1203 -- nicely if a haskell dependency generator was included in the
1206 -- It would also deal much more cleanly with compilation phases that
1207 -- generate multiple intermediates, (eg. hsc generates .hc, .hi, and
1208 -- possibly stub files), where some of the output files need to be
1209 -- processed further (eg. the stub files need to be compiled by the C
1212 -- A cool thing to do would then be to execute the data flow graph
1213 -- concurrently, automatically taking advantage of extra processors on
1214 -- the host machine. For example, when compiling two Haskell files
1215 -- where one depends on the other, the data flow graph would determine
1216 -- that the C compiler from the first comilation can be overlapped
1217 -- with the hsc comilation for the second file.
1220 :: Phase -- phase to end on (never Linker)
1221 -> Bool -- doing linking afterward?
1222 -> Bool -- take into account -o when generating output?
1223 -> String -- original basename (eg. Main)
1224 -> (Phase, String) -- phase to run, input file
1225 -> IO String -- return final filename
1227 run_pipeline last_phase do_linking use_ofile orig_basename (phase, input_fn)
1228 | phase > last_phase = return input_fn
1232 let (basename,ext) = split_filename input_fn
1234 split <- readIORef split_object_files
1235 mangle <- readIORef do_asm_mangling
1236 lang <- readIORef hsc_lang
1238 -- figure out what the next phase is. This is
1239 -- straightforward, apart from the fact that hsc can generate
1240 -- either C or assembler direct, and assembly mangling is
1241 -- optional, and splitting involves one extra phase and an alternate
1247 HscAsm | split -> SplitMangle
1250 HCc | mangle -> Mangle
1255 Mangle | not split -> As
1256 SplitMangle -> SplitAs
1262 -- filename extension for the output, determined by next_phase
1263 let new_ext = phase_input_ext next_phase
1265 -- Figure out what the output from this pass should be called.
1267 -- If we're keeping the output from this phase, then we just save
1268 -- it in the current directory, otherwise we generate a new temp file.
1269 keep_s <- readIORef keep_s_files
1270 keep_raw_s <- readIORef keep_raw_s_files
1271 keep_hc <- readIORef keep_hc_files
1272 let keep_this_output =
1275 Mangle | keep_raw_s -> True -- first enhancement :)
1277 HCc | keep_hc -> True
1281 (if next_phase > last_phase && not do_linking && use_ofile
1282 then do o_file <- readIORef output_file
1286 f <- odir_ify (orig_basename ++ '.':new_ext)
1289 -- .o files are always kept. .s files and .hc file may be kept.
1290 else if keep_this_output
1291 then odir_ify (orig_basename ++ '.':new_ext)
1292 else do filename <- newTempName new_ext
1293 add files_to_clean filename
1297 run_phase phase orig_basename input_fn output_fn
1299 -- sadly, ghc -E is supposed to write the file to stdout. We
1300 -- generate <file>.cpp, so we also have to cat the file here.
1301 when (next_phase > last_phase && last_phase == Cpp) $
1302 run_something "Dump pre-processed file to stdout"
1303 ("cat " ++ output_fn)
1305 run_pipeline last_phase do_linking use_ofile
1306 orig_basename (next_phase, output_fn)
1309 -- find a temporary name that doesn't already exist.
1310 newTempName :: String -> IO String
1311 newTempName extn = do
1313 tmp_dir <- readIORef tmp_prefix
1314 findTempName tmp_dir x
1315 where findTempName tmp_dir x = do
1316 let filename = tmp_dir ++ "/ghc" ++ show x ++ '.':extn
1317 b <- doesFileExist filename
1318 if b then findTempName tmp_dir (x+1)
1319 else return filename
1321 -------------------------------------------------------------------------------
1324 do_mkdependHS :: [String] -> [String] -> IO ()
1325 do_mkdependHS cmd_opts srcs = do
1327 let quote_include_opt o | prefixMatch "-#include" o = "'" ++ o ++ "'"
1330 mkdependHS <- readIORef pgm_dep
1331 mkdependHS_opts <- getOpts opt_dep
1332 hs_src_cpp_opts <- readIORef hs_source_cpp_opts
1334 run_something "Dependency generation"
1335 (unwords (mkdependHS :
1338 ++ ("--" : map quote_include_opt cmd_opts )
1342 -------------------------------------------------------------------------------
1345 run_phase Unlit basename input_fn output_fn
1346 = do unlit <- readIORef pgm_L
1347 unlit_flags <- getOpts opt_L
1348 run_something "Literate pre-processor"
1349 ("echo '# 1 \"" ++input_fn++"\"' > "++output_fn++" && "
1350 ++ unlit ++ ' ':input_fn ++ " - >> " ++ output_fn)
1352 -------------------------------------------------------------------------------
1355 run_phase Cpp basename input_fn output_fn
1356 = do src_opts <- getOptionsFromSource input_fn
1357 processArgs src_opts []
1359 do_cpp <- readIORef cpp_flag
1362 cpp <- readIORef pgm_P
1363 hscpp_opts <- getOpts opt_P
1364 hs_src_cpp_opts <- readIORef hs_source_cpp_opts
1366 cmdline_include_paths <- readIORef include_paths
1367 pkg_include_dirs <- getPackageIncludePath
1368 let include_paths = map (\p -> "-I"++p) (cmdline_include_paths
1369 ++ pkg_include_dirs)
1372 run_something "C pre-processor"
1374 (["echo '{-# LINE 1 \"" ++ input_fn ++ "\" -}'", ">", output_fn, "&&",
1379 ++ [ "-x", "c", input_fn, ">>", output_fn ]
1382 run_something "Inefective C pre-processor"
1383 ("echo '{-# LINE 1 \"" ++ input_fn ++ "\" -}' > "
1384 ++ output_fn ++ " && cat " ++ input_fn
1385 ++ " >> " ++ output_fn)
1387 -----------------------------------------------------------------------------
1390 run_phase Hsc basename input_fn output_fn
1391 = do hsc <- readIORef pgm_C
1393 -- we add the current directory (i.e. the directory in which
1394 -- the .hs files resides) to the import path, since this is
1395 -- what gcc does, and it's probably what you want.
1396 let current_dir = getdir basename
1398 paths <- readIORef include_paths
1399 writeIORef include_paths (current_dir : paths)
1401 -- build the hsc command line
1402 hsc_opts <- build_hsc_opts
1404 doing_hi <- readIORef produceHi
1405 tmp_hi_file <- if doing_hi
1406 then do fn <- newTempName "hi"
1407 add files_to_clean fn
1411 let hi_flag = if doing_hi then "-hifile=" ++ tmp_hi_file
1414 -- deal with -Rghc-timing
1415 timing <- readIORef collect_ghc_timing
1416 stat_file <- newTempName "stat"
1417 add files_to_clean stat_file
1418 let stat_opts | timing = [ "+RTS", "-S"++stat_file, "-RTS" ]
1421 -- tmp files for foreign export stub code
1422 tmp_stub_h <- newTempName "stub_h"
1423 tmp_stub_c <- newTempName "stub_c"
1424 add files_to_clean tmp_stub_h
1425 add files_to_clean tmp_stub_c
1427 -- figure out where to put the .hi file
1428 ohi <- readIORef output_hi
1429 hisuf <- readIORef hi_suf
1430 let hi_flags = case ohi of
1431 Nothing -> [ "-hidir="++current_dir, "-hisuf="++hisuf ]
1432 Just fn -> [ "-hifile="++fn ]
1434 -- run the compiler!
1435 run_something "Haskell Compiler"
1436 (unwords (hsc : input_fn : (
1440 "-ofile="++output_fn,
1447 -- Generate -Rghc-timing info
1449 run_something "Generate timing stats"
1450 (findFile "ghc-stats" cGHC_STATS ++ ' ':stat_file)
1454 let stub_h = basename ++ "_stub.h"
1455 let stub_c = basename ++ "_stub.c"
1457 -- copy .h_stub file into current dir if present
1458 b <- doesFileExist tmp_stub_h
1460 run_something "Copy stub .h file"
1461 ("cp " ++ tmp_stub_h ++ ' ':stub_h)
1463 -- #include <..._stub.h> in .hc file
1464 add cmdline_hc_includes tmp_stub_h -- hack
1466 -- copy the _stub.c file into the current dir
1467 run_something "Copy stub .c file"
1469 "rm -f", stub_c, "&&",
1470 "echo \'#include \""++stub_h++"\"\' >"++stub_c, " &&",
1471 "cat", tmp_stub_c, ">> ", stub_c
1474 -- compile the _stub.c file w/ gcc
1475 run_pipeline As False{-no linking-}
1476 False{-no -o option-}
1480 add ld_inputs (basename++"_stub.o")
1483 -----------------------------------------------------------------------------
1486 -- we don't support preprocessing .c files (with -E) now. Doing so introduces
1487 -- way too many hacks, and I can't say I've ever used it anyway.
1489 run_phase cc_phase basename input_fn output_fn
1490 | cc_phase == Cc || cc_phase == HCc
1491 = do cc <- readIORef pgm_c
1492 cc_opts <- (getOpts opt_c)
1493 cmdline_include_dirs <- readIORef include_paths
1495 let hcc = cc_phase == HCc
1497 -- add package include paths even if we're just compiling
1498 -- .c files; this is the Value Add(TM) that using
1499 -- ghc instead of gcc gives you :)
1500 pkg_include_dirs <- getPackageIncludePath
1501 let include_paths = map (\p -> "-I"++p) (cmdline_include_dirs
1502 ++ pkg_include_dirs)
1504 c_includes <- getPackageCIncludes
1505 cmdline_includes <- readIORef cmdline_hc_includes -- -#include options
1507 let cc_injects | hcc = unlines (map mk_include
1508 (c_includes ++ reverse cmdline_includes))
1512 '"':_{-"-} -> "#include "++h_file
1513 '<':_ -> "#include "++h_file
1514 _ -> "#include \""++h_file++"\""
1516 cc_help <- newTempName "c"
1517 add files_to_clean cc_help
1518 h <- openFile cc_help WriteMode
1519 hPutStr h cc_injects
1520 hPutStrLn h ("#include \"" ++ input_fn ++ "\"\n")
1523 ccout <- newTempName "ccout"
1524 add files_to_clean ccout
1526 mangle <- readIORef do_asm_mangling
1527 (md_c_flags, md_regd_c_flags) <- machdepCCOpts
1531 o2 <- readIORef opt_minus_o2_for_C
1532 let opt_flag | o2 = "-O2"
1535 pkg_extra_cc_opts <- getPackageExtraCcOpts
1537 excessPrecision <- readIORef excess_precision
1539 run_something "C Compiler"
1540 (unwords ([ cc, "-x", "c", cc_help, "-o", output_fn ]
1542 ++ (if cc_phase == HCc && mangle
1543 then md_regd_c_flags
1545 ++ [ verb, "-S", "-Wimplicit", opt_flag ]
1546 ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
1548 #ifdef mingw32_TARGET_OS
1551 ++ (if excessPrecision then [] else [ "-ffloat-store" ])
1553 ++ pkg_extra_cc_opts
1557 -- ToDo: postprocess the output from gcc
1559 -----------------------------------------------------------------------------
1562 run_phase Mangle basename input_fn output_fn
1563 = do mangler <- readIORef pgm_m
1564 mangler_opts <- getOpts opt_m
1566 if (prefixMatch "i386" cTARGETPLATFORM)
1567 then do n_regs <- readIORef stolen_x86_regs
1568 return [ show n_regs ]
1570 run_something "Assembly Mangler"
1573 ++ [ input_fn, output_fn ]
1577 -----------------------------------------------------------------------------
1580 run_phase SplitMangle basename input_fn outputfn
1581 = do splitter <- readIORef pgm_s
1583 -- this is the prefix used for the split .s files
1584 tmp_pfx <- readIORef tmp_prefix
1586 let split_s_prefix = tmp_pfx ++ "/ghc" ++ show x
1587 writeIORef split_prefix split_s_prefix
1588 add files_to_clean (split_s_prefix ++ "__*") -- d:-)
1590 -- allocate a tmp file to put the no. of split .s files in (sigh)
1591 n_files <- newTempName "n_files"
1592 add files_to_clean n_files
1594 run_something "Split Assembly File"
1601 -- save the number of split files for future references
1602 s <- readFile n_files
1603 let n = read s :: Int
1604 writeIORef n_split_files n
1606 -----------------------------------------------------------------------------
1609 run_phase As basename input_fn output_fn
1610 = do as <- readIORef pgm_a
1611 as_opts <- getOpts opt_a
1613 cmdline_include_paths <- readIORef include_paths
1614 let cmdline_include_flags = map (\p -> "-I"++p) cmdline_include_paths
1615 run_something "Assembler"
1616 (unwords (as : as_opts
1617 ++ cmdline_include_flags
1618 ++ [ "-c", input_fn, "-o", output_fn ]
1621 run_phase SplitAs basename input_fn output_fn
1622 = do as <- readIORef pgm_a
1623 as_opts <- getOpts opt_a
1625 odir_opt <- readIORef output_dir
1626 let odir | Just s <- odir_opt = s
1627 | otherwise = basename
1629 split_s_prefix <- readIORef split_prefix
1630 n <- readIORef n_split_files
1632 odir <- readIORef output_dir
1633 let real_odir = case odir of
1637 let assemble_file n = do
1638 let input_s = split_s_prefix ++ "__" ++ show n ++ ".s"
1639 let output_o = newdir real_odir
1640 (basename ++ "__" ++ show n ++ ".o")
1641 real_o <- osuf_ify output_o
1642 run_something "Assembler"
1643 (unwords (as : as_opts
1644 ++ [ "-c", "-o", real_o, input_s ]
1647 mapM_ assemble_file [1..n]
1649 -----------------------------------------------------------------------------
1652 do_link :: [String] -> [String] -> IO ()
1653 do_link o_files unknown_srcs = do
1654 ln <- readIORef pgm_l
1656 o_file <- readIORef output_file
1657 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1659 pkg_lib_paths <- getPackageLibraryPath
1660 let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
1662 lib_paths <- readIORef library_paths
1663 let lib_path_opts = map ("-L"++) lib_paths
1665 pkg_libs <- getPackageLibraries
1666 let pkg_lib_opts = map (\lib -> "-l"++lib) pkg_libs
1668 libs <- readIORef cmdline_libraries
1669 let lib_opts = map ("-l"++) (reverse libs)
1670 -- reverse because they're added in reverse order from the cmd line
1672 pkg_extra_ld_opts <- getPackageExtraLdOpts
1674 -- probably _stub.o files
1675 extra_ld_inputs <- readIORef ld_inputs
1677 -- opts from -optl-<blah>
1678 extra_ld_opts <- getOpts opt_l
1680 run_something "Linker"
1682 ([ ln, verb, "-o", output_fn ]
1688 ++ pkg_lib_path_opts
1690 ++ pkg_extra_ld_opts
1695 -----------------------------------------------------------------------------
1696 -- Running an external program
1698 run_something phase_name cmd
1700 verb <- readIORef verbose
1708 n <- readIORef dry_run
1712 #ifndef mingw32_TARGET_OS
1713 exit_code <- system cmd `catchAllIO`
1714 (\e -> throwDyn (PhaseFailed phase_name (ExitFailure 1)))
1716 tmp <- newTempName "sh"
1717 h <- openFile tmp WriteMode
1720 exit_code <- system ("sh - " ++ tmp) `catchAllIO`
1721 (\e -> throwDyn (PhaseFailed phase_name (ExitFailure 1)))
1725 if exit_code /= ExitSuccess
1726 then throwDyn (PhaseFailed phase_name exit_code)
1727 else do on verb (putStr "\n")
1730 -----------------------------------------------------------------------------
1734 = NoArg (IO ()) -- flag with no argument
1735 | HasArg (String -> IO ()) -- flag has an argument (maybe prefix)
1736 | SepArg (String -> IO ()) -- flag has a separate argument
1737 | Prefix (String -> IO ()) -- flag is a prefix only
1738 | OptPrefix (String -> IO ()) -- flag may be a prefix
1739 | AnySuffix (String -> IO ()) -- flag is a prefix, pass whole arg to fn
1740 | PassFlag (String -> IO ()) -- flag with no arg, pass flag to fn
1742 -- note that ordering is important in the following list: any flag which
1743 -- is a prefix flag (i.e. HasArg, Prefix, OptPrefix, AnySuffix) will override
1744 -- flags further down the list with the same prefix.
1747 [ ------- help -------------------------------------------------------
1748 ( "?" , NoArg long_usage)
1749 , ( "-help" , NoArg long_usage)
1752 ------- version ----------------------------------------------------
1753 , ( "-version" , NoArg (do hPutStrLn stderr (cProjectName
1754 ++ ", version " ++ version_str)
1755 exitWith ExitSuccess))
1756 , ( "-numeric-version", NoArg (do hPutStrLn stderr version_str
1757 exitWith ExitSuccess))
1759 ------- verbosity ----------------------------------------------------
1760 , ( "v" , NoArg (writeIORef verbose True) )
1761 , ( "n" , NoArg (writeIORef dry_run True) )
1763 ------- recompilation checker --------------------------------------
1764 , ( "recomp" , NoArg (writeIORef recomp True) )
1765 , ( "no-recomp" , NoArg (writeIORef recomp False) )
1767 ------- ways --------------------------------------------------------
1768 , ( "prof" , NoArg (addNoDups ways WayProf) )
1769 , ( "unreg" , NoArg (addNoDups ways WayUnreg) )
1770 , ( "dll" , NoArg (addNoDups ways WayDll) )
1771 , ( "ticky" , NoArg (addNoDups ways WayTicky) )
1772 , ( "parallel" , NoArg (addNoDups ways WayPar) )
1773 , ( "gransim" , NoArg (addNoDups ways WayGran) )
1774 , ( "smp" , NoArg (addNoDups ways WaySMP) )
1775 , ( "debug" , NoArg (addNoDups ways WayDebug) )
1778 ------- Interface files ---------------------------------------------
1779 , ( "hi" , NoArg (writeIORef produceHi True) )
1780 , ( "nohi" , NoArg (writeIORef produceHi False) )
1781 , ( "hi-diffs" , NoArg (writeIORef hi_diffs NormalHiDiffs) )
1782 , ( "no-hi-diffs" , NoArg (writeIORef hi_diffs NoHiDiffs) )
1783 , ( "hi-diffs-with-usages" , NoArg (writeIORef hi_diffs UsageHiDiffs) )
1784 , ( "keep-hi-diffs" , NoArg (writeIORef keep_hi_diffs True) )
1785 --"hi-with-*" -> hiw <- readIORef hi_with (ToDo)
1787 --------- Profiling --------------------------------------------------
1788 , ( "auto-dicts" , NoArg (add opt_C "-fauto-sccs-on-dicts") )
1789 , ( "auto-all" , NoArg (add opt_C "-fauto-sccs-on-all-toplevs") )
1790 , ( "auto" , NoArg (add opt_C "-fauto-sccs-on-exported-toplevs") )
1791 , ( "caf-all" , NoArg (add opt_C "-fauto-sccs-on-individual-cafs") )
1792 -- "ignore-sccs" doesn't work (ToDo)
1794 ------- Miscellaneous -----------------------------------------------
1795 , ( "cpp" , NoArg (writeIORef cpp_flag True) )
1796 , ( "#include" , HasArg (add cmdline_hc_includes) )
1797 , ( "no-link-chk" , NoArg (return ()) ) -- ignored for backwards compat
1799 ------- Output Redirection ------------------------------------------
1800 , ( "odir" , HasArg (writeIORef output_dir . Just) )
1801 , ( "o" , SepArg (writeIORef output_file . Just) )
1802 , ( "osuf" , HasArg (writeIORef output_suf . Just) )
1803 , ( "hisuf" , HasArg (writeIORef hi_suf) )
1804 , ( "tmpdir" , HasArg (writeIORef tmp_prefix . (++ "/")) )
1805 , ( "ohi" , HasArg (\s -> case s of
1806 "-" -> writeIORef hi_on_stdout True
1807 _ -> writeIORef output_hi (Just s)) )
1810 , ( "keep-hc-file" , AnySuffix (\_ -> writeIORef keep_hc_files True) )
1811 , ( "keep-s-file" , AnySuffix (\_ -> writeIORef keep_s_files True) )
1812 , ( "keep-raw-s-file", AnySuffix (\_ -> writeIORef keep_raw_s_files True) )
1813 , ( "keep-tmp-files" , AnySuffix (\_ -> writeIORef keep_tmp_files True) )
1815 , ( "split-objs" , NoArg (if can_split
1816 then do writeIORef split_object_files True
1817 add opt_C "-fglobalise-toplev-names"
1818 add opt_c "-DUSE_SPLIT_MARKERS"
1819 else hPutStrLn stderr
1820 "warning: don't know how to split \
1821 \object files on this architecture"
1824 ------- Include/Import Paths ----------------------------------------
1825 , ( "i" , OptPrefix augment_import_paths )
1826 , ( "I" , Prefix augment_include_paths )
1828 ------- Libraries ---------------------------------------------------
1829 , ( "L" , Prefix augment_library_paths )
1830 , ( "l" , Prefix (add cmdline_libraries) )
1832 ------- Packages ----------------------------------------------------
1833 , ( "package-name" , HasArg (\s -> add opt_C ("-inpackage="++s)) )
1835 , ( "package" , HasArg (addPackage) )
1836 , ( "syslib" , HasArg (addPackage) ) -- for compatibility w/ old vsns
1838 , ( "-list-packages" , NoArg (listPackages) )
1839 , ( "-add-package" , NoArg (newPackage) )
1840 , ( "-delete-package" , SepArg (deletePackage) )
1842 ------- Specific phases --------------------------------------------
1843 , ( "pgmdep" , HasArg (writeIORef pgm_dep) )
1844 , ( "pgmL" , HasArg (writeIORef pgm_L) )
1845 , ( "pgmP" , HasArg (writeIORef pgm_P) )
1846 , ( "pgmC" , HasArg (writeIORef pgm_C) )
1847 , ( "pgmc" , HasArg (writeIORef pgm_c) )
1848 , ( "pgmm" , HasArg (writeIORef pgm_m) )
1849 , ( "pgms" , HasArg (writeIORef pgm_s) )
1850 , ( "pgma" , HasArg (writeIORef pgm_a) )
1851 , ( "pgml" , HasArg (writeIORef pgm_l) )
1853 , ( "optdep" , HasArg (add opt_dep) )
1854 , ( "optL" , HasArg (add opt_L) )
1855 , ( "optP" , HasArg (add opt_P) )
1856 , ( "optCrts" , HasArg (add opt_Crts) )
1857 , ( "optC" , HasArg (add opt_C) )
1858 , ( "optc" , HasArg (add opt_c) )
1859 , ( "optm" , HasArg (add opt_m) )
1860 , ( "opta" , HasArg (add opt_a) )
1861 , ( "optl" , HasArg (add opt_l) )
1862 , ( "optdll" , HasArg (add opt_dll) )
1864 ------ HsCpp opts ---------------------------------------------------
1865 , ( "D" , Prefix (\s -> add opt_P ("-D'"++s++"'") ) )
1866 , ( "U" , Prefix (\s -> add opt_P ("-U'"++s++"'") ) )
1868 ------ Warning opts -------------------------------------------------
1869 , ( "W" , NoArg (writeIORef warning_opt W_))
1870 , ( "Wall" , NoArg (writeIORef warning_opt W_all))
1871 , ( "Wnot" , NoArg (writeIORef warning_opt W_not))
1872 , ( "w" , NoArg (writeIORef warning_opt W_not))
1874 ----- Linker --------------------------------------------------------
1875 , ( "static" , NoArg (writeIORef static True) )
1877 ------ Compiler RTS options -----------------------------------------
1878 , ( "H" , HasArg (sizeOpt specific_heap_size) )
1879 , ( "K" , HasArg (sizeOpt specific_stack_size) )
1880 , ( "Rscale-sizes" , HasArg (floatOpt scale_sizes_by) )
1881 , ( "Rghc-timing" , NoArg (writeIORef collect_ghc_timing True) )
1883 ------ Debugging ----------------------------------------------------
1884 , ( "dstg-stats" , NoArg (writeIORef opt_StgStats True) )
1886 , ( "dno-" , Prefix (\s -> add anti_opt_C ("-d"++s)) )
1887 , ( "d" , AnySuffix (add opt_C) )
1889 ------ Machine dependant (-m<blah>) stuff ---------------------------
1891 , ( "monly-2-regs", NoArg (writeIORef stolen_x86_regs 2) )
1892 , ( "monly-3-regs", NoArg (writeIORef stolen_x86_regs 3) )
1893 , ( "monly-4-regs", NoArg (writeIORef stolen_x86_regs 4) )
1895 ------ Compiler flags -----------------------------------------------
1896 , ( "O2-for-C" , NoArg (writeIORef opt_minus_o2_for_C True) )
1897 , ( "O" , OptPrefix (setOptLevel) )
1899 , ( "fglasgow-exts-no-lang", NoArg ( do add opt_C "-fglasgow-exts") )
1901 , ( "fglasgow-exts" , NoArg (do add opt_C "-fglasgow-exts"
1904 , ( "fasm" , OptPrefix (\_ -> writeIORef hsc_lang HscAsm) )
1906 , ( "fvia-c" , NoArg (writeIORef hsc_lang HscC) )
1907 , ( "fvia-C" , NoArg (writeIORef hsc_lang HscC) )
1909 , ( "fno-asm-mangling" , NoArg (writeIORef do_asm_mangling False) )
1911 , ( "fmax-simplifier-iterations",
1912 Prefix (writeIORef opt_MaxSimplifierIterations . read) )
1914 , ( "fusagesp" , NoArg (do writeIORef opt_UsageSPInf True
1915 add opt_C "-fusagesp-on") )
1917 , ( "fexcess-precision" , NoArg (do writeIORef excess_precision True
1918 add opt_C "-fexcess-precision"))
1920 -- flags that are "active negatives"
1921 , ( "fno-implicit-prelude" , PassFlag (add opt_C) )
1922 , ( "fno-prune-tydecls" , PassFlag (add opt_C) )
1923 , ( "fno-prune-instdecls" , PassFlag (add opt_C) )
1924 , ( "fno-pre-inlining" , PassFlag (add opt_C) )
1926 -- All other "-fno-<blah>" options cancel out "-f<blah>" on the hsc cmdline
1927 , ( "fno-", Prefix (\s -> add anti_opt_C ("-f"++s)) )
1929 -- Pass all remaining "-f<blah>" options to hsc
1930 , ( "f", AnySuffix (add opt_C) )
1933 -----------------------------------------------------------------------------
1934 -- Process command-line
1936 processArgs :: [String] -> [String] -> IO [String] -- returns spare args
1937 processArgs [] spare = return (reverse spare)
1938 processArgs args@(('-':_):_) spare = do
1939 args' <- processOneArg args
1940 processArgs args' spare
1941 processArgs (arg:args) spare =
1942 processArgs args (arg:spare)
1944 processOneArg :: [String] -> IO [String]
1945 processOneArg (('-':arg):args) = do
1946 let (rest,action) = findArg arg
1952 then io >> return args
1953 else throwDyn (UnknownFlag dash_arg)
1957 then fio rest >> return args
1959 [] -> throwDyn (UnknownFlag dash_arg)
1960 (arg1:args1) -> fio arg1 >> return args1
1964 [] -> throwDyn (UnknownFlag dash_arg)
1965 (arg1:args1) -> fio arg1 >> return args1
1969 then fio rest >> return args
1970 else throwDyn (UnknownFlag dash_arg)
1972 OptPrefix fio -> fio rest >> return args
1974 AnySuffix fio -> fio ('-':arg) >> return args
1978 then throwDyn (UnknownFlag dash_arg)
1979 else fio ('-':arg) >> return args
1981 findArg :: String -> (String,OptKind)
1983 = case [ (remove_spaces rest, k) | (pat,k) <- opts,
1984 Just rest <- [my_prefix_match pat arg],
1985 is_prefix k || null rest ] of
1986 [] -> throwDyn (UnknownFlag ('-':arg))
1989 is_prefix (NoArg _) = False
1990 is_prefix (SepArg _) = False
1991 is_prefix (PassFlag _) = False
1994 -----------------------------------------------------------------------------
1995 -- convert sizes like "3.5M" into integers
1997 sizeOpt :: IORef Integer -> String -> IO ()
1999 | c == "" = writeSizeOpt ref (truncate n)
2000 | c == "K" || c == "k" = writeSizeOpt ref (truncate (n * 1000))
2001 | c == "M" || c == "m" = writeSizeOpt ref (truncate (n * 1000 * 1000))
2002 | c == "G" || c == "g" = writeSizeOpt ref (truncate (n * 1000 * 1000 * 1000))
2003 | otherwise = throwDyn (UnknownFlag str)
2004 where (m, c) = span pred str
2005 n = read m :: Double
2006 pred c = isDigit c || c == '.'
2008 writeSizeOpt :: IORef Integer -> Integer -> IO ()
2009 writeSizeOpt ref new = do
2010 current <- readIORef ref
2011 when (new > current) $
2014 floatOpt :: IORef Double -> String -> IO ()
2016 = writeIORef ref (read str :: Double)
2018 -----------------------------------------------------------------------------
2019 -- Finding files in the installation
2021 GLOBAL_VAR(topDir, clibdir, String)
2023 -- grab the last -B option on the command line, and
2024 -- set topDir to its value.
2025 setTopDir :: [String] -> IO [String]
2027 let (minusbs, others) = partition (prefixMatch "-B") args
2029 [] -> writeIORef topDir clibdir
2030 some -> writeIORef topDir (drop 2 (last some)))
2033 findFile name alt_path = unsafePerformIO (do
2034 top_dir <- readIORef topDir
2035 let installed_file = top_dir ++ '/':name
2036 let inplace_file = top_dir ++ '/':cCURRENT_DIR ++ '/':alt_path
2037 b <- doesFileExist inplace_file
2038 if b then return inplace_file
2039 else return installed_file
2042 -----------------------------------------------------------------------------
2045 my_partition :: (a -> Maybe b) -> [a] -> ([b],[a])
2046 my_partition p [] = ([],[])
2047 my_partition p (a:as)
2048 = let (bs,cs) = my_partition p as in
2050 Nothing -> (bs,a:cs)
2053 my_prefix_match :: String -> String -> Maybe String
2054 my_prefix_match [] rest = Just rest
2055 my_prefix_match (p:pat) [] = Nothing
2056 my_prefix_match (p:pat) (r:rest)
2057 | p == r = my_prefix_match pat rest
2058 | otherwise = Nothing
2060 prefixMatch :: Eq a => [a] -> [a] -> Bool
2061 prefixMatch [] str = True
2062 prefixMatch pat [] = False
2063 prefixMatch (p:ps) (s:ss) | p == s = prefixMatch ps ss
2066 postfixMatch :: String -> String -> Bool
2067 postfixMatch pat str = prefixMatch (reverse pat) (reverse str)
2069 later = flip finally
2071 on b io = if b then io >> return (error "on") else return (error "on")
2073 my_catch = flip catchAllIO
2074 my_catchDyn = flip catchDyn
2076 global :: a -> IORef a
2077 global a = unsafePerformIO (newIORef a)
2079 split_filename :: String -> (String,String)
2080 split_filename f = (reverse (stripDot rev_basename), reverse rev_ext)
2081 where (rev_ext, rev_basename) = span ('.' /=) (reverse f)
2082 stripDot ('.':xs) = xs
2085 split :: Char -> String -> [String]
2086 split c s = case rest of
2088 _:rest -> chunk : split c rest
2089 where (chunk, rest) = break (==c) s
2091 add :: IORef [a] -> a -> IO ()
2094 writeIORef var (x:xs)
2096 addNoDups :: Eq a => IORef [a] -> a -> IO ()
2097 addNoDups var x = do
2099 unless (x `elem` xs) $ writeIORef var (x:xs)
2101 remove_suffix :: String -> Char -> String
2103 | null pre = reverse suf
2104 | otherwise = reverse pre
2105 where (suf,pre) = break (==c) (reverse s)
2107 drop_longest_prefix :: String -> Char -> String
2108 drop_longest_prefix s c = reverse suf
2109 where (suf,pre) = break (==c) (reverse s)
2111 take_longest_prefix :: String -> Char -> String
2112 take_longest_prefix s c = reverse pre
2113 where (suf,pre) = break (==c) (reverse s)
2115 newsuf :: String -> String -> String
2116 newsuf suf s = remove_suffix s '.' ++ suf
2118 -- getdir strips the filename off the input string, returning the directory.
2119 getdir :: String -> String
2120 getdir s = if null dir then "." else init dir
2121 where dir = take_longest_prefix s '/'
2123 newdir :: String -> String -> String
2124 newdir dir s = dir ++ '/':drop_longest_prefix s '/'
2126 remove_spaces :: String -> String
2127 remove_spaces = reverse . dropWhile isSpace . reverse . dropWhile isSpace