import HscTypes
import Outputable
import Module
-import LazyUniqFM ( eltsUFM )
+import UniqFM ( eltsUFM )
import ErrUtils
import DynFlags
import StaticFlags ( v_Ld_inputs, opt_Static, WayName(..) )
runPhase (Cpp sf) _stop hsc_env _basename _suff input_fn get_output_fn maybe_loc
= do let dflags0 = hsc_dflags hsc_env
src_opts <- liftIO $ getOptionsFromFile dflags0 input_fn
- (dflags, unhandled_flags, warns)
+ (dflags1, unhandled_flags, warns)
<- liftIO $ parseDynamicNoPackageFlags dflags0 src_opts
- handleFlagWarnings dflags warns
checkProcessArgsResult unhandled_flags
- if not (dopt Opt_Cpp dflags) then
+ if not (dopt Opt_Cpp dflags1) then do
+ -- we have to be careful to emit warnings only once.
+ unless (dopt Opt_Pp dflags1) $ handleFlagWarnings dflags1 warns
+
-- no need to preprocess CPP, just pass input file along
-- to the next phase of the pipeline.
- return (HsPp sf, dflags, maybe_loc, input_fn)
+ return (HsPp sf, dflags1, maybe_loc, input_fn)
else do
- output_fn <- liftIO $ get_output_fn dflags (HsPp sf) maybe_loc
- liftIO $ doCpp dflags True{-raw-} False{-no CC opts-} input_fn output_fn
- return (HsPp sf, dflags, maybe_loc, output_fn)
+ output_fn <- liftIO $ get_output_fn dflags1 (HsPp sf) maybe_loc
+ liftIO $ doCpp dflags1 True{-raw-} False{-no CC opts-} input_fn output_fn
+ -- re-read the pragmas now that we've preprocessed the file
+ -- See #2464,#3457
+ src_opts <- liftIO $ getOptionsFromFile dflags0 output_fn
+ (dflags2, unhandled_flags, warns)
+ <- liftIO $ parseDynamicNoPackageFlags dflags0 src_opts
+ unless (dopt Opt_Pp dflags2) $ handleFlagWarnings dflags2 warns
+ -- the HsPp pass below will emit warnings
+ checkProcessArgsResult unhandled_flags
+
+ return (HsPp sf, dflags2, maybe_loc, output_fn)
-------------------------------------------------------------------------------
-- HsPp phase
] ++
map SysTools.Option hspp_opts
)
- return (Hsc sf, dflags, maybe_loc, output_fn)
+
+ -- re-read pragmas now that we've parsed the file (see #3674)
+ src_opts <- liftIO $ getOptionsFromFile dflags output_fn
+ (dflags1, unhandled_flags, warns)
+ <- liftIO $ parseDynamicNoPackageFlags dflags src_opts
+ handleFlagWarnings dflags1 warns
+ checkProcessArgsResult unhandled_flags
+
+ return (Hsc sf, dflags1, maybe_loc, output_fn)
-----------------------------------------------------------------------------
-- Hsc phase
src_timestamp <- liftIO $ getModificationTime (basename <.> suff)
let force_recomp = dopt Opt_ForceRecomp dflags
+ hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
source_unchanged <-
if force_recomp || not (isStopLn stop)
-- Set source_unchanged to False unconditionally if
else return False
-- get the DynFlags
- let hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
let next_phase = hscNextPhase dflags src_flavour hsc_lang
output_fn <- liftIO $ get_output_fn dflags next_phase (Just location4)
then []
else [ "-ffloat-store" ]) ++
#endif
+
-- gcc's -fstrict-aliasing allows two accesses to memory
-- to be considered non-aliasing if they have different types.
-- This interacts badly with the C code we generate, which is
-- very weakly typed, being derived from C--.
["-fno-strict-aliasing"]
-
-
liftIO $ SysTools.runCc dflags (
-- force the C compiler to interpret this file as C when
-- compiling .hc files, by adding the -x c option.
++ map SysTools.Option (
md_c_flags
++ pic_c_flags
+
+#if defined(mingw32_TARGET_OS)
+ -- Stub files generated for foreign exports references the runIO_closure
+ -- and runNonIO_closure symbols, which are defined in the base package.
+ -- These symbols are imported into the stub.c file via RtsAPI.h, and the
+ -- way we do the import depends on whether we're currently compiling
+ -- the base package or not.
+ ++ (if thisPackage dflags == basePackageId
+ then [ "-DCOMPILING_BASE_PACKAGE" ]
+ else [])
+#endif
+
#ifdef sparc_TARGET_ARCH
-- We only support SparcV9 and better because V8 lacks an atomic CAS
-- instruction. Note that the user can still override this
putStrLn (unwords (map (packageIdString . packageConfigId) allpkg))
return $ 'F':s ++ ';':(seperateBySemiColon (map (packageIdString . packageConfigId) allpkg))
+mkExtraCObj :: DynFlags -> [String] -> IO FilePath
+mkExtraCObj dflags xs
+ = do cFile <- newTempName dflags "c"
+ oFile <- newTempName dflags "o"
+ writeFile cFile $ unlines xs
+ let rtsDetails = getPackageDetails (pkgState dflags) rtsPackageId
+ (md_c_flags, _) = machdepCCOpts dflags
+ SysTools.runCc dflags
+ ([Option "-c",
+ FileOption "" cFile,
+ Option "-o",
+ FileOption "" oFile] ++
+ map (FileOption "-I") (includeDirs rtsDetails) ++
+ map Option md_c_flags)
+ return oFile
+
-- generates a Perl skript starting a parallel prg under PVM
mk_pvm_wrapper_script :: String -> String -> String -> String
mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan = unlines $
pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
let pkg_lib_path_opts = concat (map get_pkg_lib_path_opts pkg_lib_paths)
-#ifdef linux_TARGET_OS
+#ifdef elf_OBJ_FORMAT
get_pkg_lib_path_opts l | (dynLibLoader dflags)==SystemDependent && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
| otherwise = ["-L" ++ l]
#else
let no_hs_main = dopt Opt_NoHsMain dflags
let main_lib | no_hs_main = []
| otherwise = [ "-lHSrtsmain" ]
+ rtsEnabledObj <- if dopt Opt_RtsOptsEnabled dflags
+ then do fn <- mkExtraCObj dflags
+ ["#include \"Rts.h\"",
+ "const rtsBool rtsOptsEnabled = rtsTrue;"]
+ return [fn]
+ else return []
+ rtsOptsObj <- case rtsOpts dflags of
+ Just opts ->
+ do fn <- mkExtraCObj dflags
+ -- We assume that the Haskell "show" does
+ -- the right thing here
+ ["char *ghc_rts_opts = " ++ show opts ++ ";"]
+ return [fn]
+ Nothing -> return []
pkg_link_opts <- getPackageLinkOpts dflags dep_packages
let
thread_opts | WayThreaded `elem` ways = [
-#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS)
+#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS) && !defined(haiku_TARGET_OS)
"-lpthread"
#endif
#if defined(osf3_TARGET_OS)
]
++ map SysTools.Option (
md_c_flags
+
+#ifdef mingw32_TARGET_OS
+ -- Permit the linker to auto link _symbol to _imp_symbol.
+ -- This lets us link against DLLs without needing an "import library".
+ ++ ["-Wl,--enable-auto-import"]
+#endif
++ o_files
++ extra_ld_inputs
++ lib_path_opts
#endif
++ pkg_lib_path_opts
++ main_lib
+ ++ rtsEnabledObj
+ ++ rtsOptsObj
++ pkg_link_opts
#ifdef darwin_TARGET_OS
++ pkg_framework_path_opts
#endif
let pkg_lib_paths = collectLibraryPaths pkgs_no_rts
let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
-#ifdef linux_TARGET_OS
+#ifdef elf_OBJ_FORMAT
get_pkg_lib_path_opts l | (dynLibLoader dflags)==SystemDependent && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
| otherwise = ["-L" ++ l]
#else
++ map (SysTools.FileOption "") o_files
++ map SysTools.Option (
md_c_flags
+
+ -- Permit the linker to auto link _symbol to _imp_symbol
+ -- This lets us link against DLLs without needing an "import library"
+ ++ ["-Wl,--enable-auto-import"]
+
++ extra_ld_inputs
++ lib_path_opts
++ extra_ld_opts
-- later, so that it will not complain about the use of the option
-- -undefined dynamic_lookup above.
-- -install_name
- -- Causes the dynamic linker to ignore the DYLD_LIBRARY_PATH when loading
- -- this lib and instead look for it at its absolute path.
- -- When installing the .dylibs (see target.mk), we'll change that path to
- -- point to the place they are installed. Therefore, we won't have to set
- -- up DYLD_LIBRARY_PATH specifically for ghc.
+ -- Mac OS/X stores the path where a dynamic library is (to be) installed
+ -- in the library itself. It's called the "install name" of the library.
+ -- Then any library or executable that links against it before it's
+ -- installed will search for it in its ultimate install location. By
+ -- default we set the install name to the absolute path at build time, but
+ -- it can be overridden by the -dylib-install-name option passed to ghc.
+ -- Cabal does this.
-----------------------------------------------------------------------------
let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
- pwd <- getCurrentDirectory
+ instName <- case dylibInstallName dflags of
+ Just n -> return n
+ Nothing -> do
+ pwd <- getCurrentDirectory
+ return $ pwd `combine` output_fn
SysTools.runLink dflags
([ SysTools.Option verb
, SysTools.Option "-dynamiclib"
++ map SysTools.Option (
md_c_flags
++ o_files
- ++ [ "-undefined", "dynamic_lookup", "-single_module", "-Wl,-macosx_version_min","-Wl,10.3", "-install_name " ++ (pwd </> output_fn) ]
+ ++ [ "-undefined", "dynamic_lookup", "-single_module", "-Wl,-macosx_version_min","-Wl,10.5",
+ "-Wl,-read_only_relocs,suppress", "-install_name", instName ]
++ extra_ld_inputs
++ lib_path_opts
++ extra_ld_opts
-----------------------------------------------------------------------------
let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
+ let buildingRts = thisPackage dflags == rtsPackageId
+ let bsymbolicFlag = if buildingRts
+ then -- -Bsymbolic breaks the way we implement
+ -- hooks in the RTS
+ []
+ else -- we need symbolic linking to resolve
+ -- non-PIC intra-package-relocations
+ ["-Wl,-Bsymbolic"]
SysTools.runLink dflags
([ SysTools.Option verb
++ map SysTools.Option (
md_c_flags
++ o_files
- ++ [ "-shared", "-Wl,-Bsymbolic" ] -- we need symbolic linking to resolve non-PIC intra-package-relocations
+ ++ [ "-shared" ]
+ ++ bsymbolicFlag
++ [ "-Wl,-soname," ++ takeFileName output_fn ] -- set the library soname
++ extra_ld_inputs
++ lib_path_opts