import EXCEPTION
import DATA_IOREF ( readIORef, writeIORef )
-#ifdef GHCI
-import Time ( getClockTime )
-#endif
+import Time ( ClockTime )
import Directory
import System
import IO
preprocess :: FilePath -> IO FilePath
preprocess filename =
- ASSERT(haskellish_src_file filename)
+ ASSERT(isHaskellSrcFilename filename)
do restoreDynFlags -- Restore to state of last save
runPipeline (StopBefore Hsc) ("preprocess")
False{-temporary output file-}
compile :: HscEnv
-> Module
-> ModLocation
+ -> ClockTime -- timestamp of original source file
-> Bool -- True <=> source unchanged
-> Bool -- True <=> have object
-> Maybe ModIface -- old interface, if available
| CompErrs
-compile hsc_env this_mod location
+compile hsc_env this_mod location src_timestamp
source_unchanged have_object
old_iface = do
hsc_env' = hsc_env { hsc_dflags = dyn_flags' }
-- run the compiler
- hsc_result <- hscMain hsc_env' this_mod location
+ hsc_result <- hscMain hsc_env' printErrorsAndWarnings this_mod location
source_unchanged' have_object old_iface
case hsc_result of
HscInterpreted ->
case maybe_interpreted_code of
#ifdef GHCI
- Just comp_bc -> do tm <- getClockTime
- return ([BCOs comp_bc], tm)
+ Just comp_bc -> return ([BCOs comp_bc], src_timestamp)
+ -- Why do we use the timestamp of the source file here,
+ -- rather than the current time? This works better in
+ -- the case where the local clock is out of sync
+ -- with the filesystem's clock. It's just as accurate:
+ -- if the source is modified, then the linkable will
+ -- be out of date.
#endif
Nothing -> panic "compile: no interpreted code"
genOutputFilenameFunc :: Bool -> Maybe FilePath -> Phase -> String
-> IO (Phase{-next phase-} -> Maybe ModLocation -> IO FilePath)
-genOutputFilenameFunc keep_output maybe_output_filename stop_phase basename
+genOutputFilenameFunc keep_final_output maybe_output_filename
+ stop_phase basename
= do
hcsuf <- readIORef v_HC_suf
odir <- readIORef v_Output_dir
myPhaseInputExt other = phaseInputExt other
func next_phase maybe_location
- | next_phase == stop_phase
- = case maybe_output_filename of
- Just file -> return file
- Nothing
- | Ln <- next_phase -> return odir_persistent
- | keep_output -> return persistent
- | otherwise -> newTempName suffix
- -- sometimes, we keep output from intermediate stages
- | otherwise
- = case next_phase of
- Ln -> return odir_persistent
- Mangle | keep_raw_s -> return persistent
- As | keep_s -> return persistent
- HCc | keep_hc -> return persistent
- _other -> newTempName suffix
+ | is_last_phase, Just f <- maybe_output_filename = return f
+ | is_last_phase && keep_final_output = persistent_fn
+ | keep_this_output = persistent_fn
+ | otherwise = newTempName suffix
+
where
+ is_last_phase = next_phase == stop_phase
+
+ -- sometimes, we keep output from intermediate stages
+ keep_this_output =
+ case next_phase of
+ Ln -> True
+ Mangle | keep_raw_s -> True
+ As | keep_s -> True
+ HCc | keep_hc -> True
+ _other -> False
+
suffix = myPhaseInputExt next_phase
+
+ -- persistent object files get put in odir
+ persistent_fn
+ | Ln <- next_phase = return odir_persistent
+ | otherwise = return persistent
+
persistent = basename ++ '.':suffix
odir_persistent
-- gather the imports and module name
(_,_,mod_name) <-
- if extcoreish_suffix suff
+ if isExtCoreFilename ('.':suff)
then do
-- no explicit imports in ExtCore input.
m <- getCoreModuleName input_fn
hsc_env <- newHscEnv OneShot dyn_flags'
-- run the compiler!
- result <- hscMain hsc_env mod
+ result <- hscMain hsc_env printErrorsAndWarnings mod
location{ ml_hspp_file=Just input_fn }
source_unchanged
False
[rts_pkg, std_pkg] <- getPackageDetails [rtsPackage, basePackage]
+ ways <- readIORef v_Ways
+
+ -- Here are some libs that need to be linked at the *end* of
+ -- the command line, because they contain symbols that are referred to
+ -- by the RTS. We can't therefore use the ordinary way opts for these.
+ let
+ debug_opts | WayDebug `elem` ways = [
+#if defined(HAVE_LIBBFD)
+ "-lbfd", "-liberty"
+#endif
+ ]
+ | otherwise = []
+
+ let
+ thread_opts | WayThreaded `elem` ways = [
+#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS)
+ "-lpthread"
+#endif
+#if defined(osf3_TARGET_OS)
+ , "-lexc"
+#endif
+ ]
+ | otherwise = []
+
let extra_os = if static || no_hs_main
then []
else [ head (library_dirs rts_pkg) ++ "/Main.dll_o",
++ pkg_framework_path_opts
++ pkg_framework_opts
#endif
+ ++ debug_opts
+ ++ thread_opts
))
-- parallel only: move binary to another dir -- HWL