Add dump flag for timing output
[ghc.git] / compiler / main / SysTools.hs
1 {-
2 -----------------------------------------------------------------------------
3 --
4 -- (c) The University of Glasgow 2001-2003
5 --
6 -- Access to system tools: gcc, cp, rm etc
7 --
8 -----------------------------------------------------------------------------
9 -}
10
11 {-# LANGUAGE CPP, MultiWayIf, ScopedTypeVariables #-}
12
13 module SysTools (
14 -- Initialisation
15 initSysTools,
16 initLlvmTargets,
17
18 -- Interface to system tools
19 module SysTools.Tasks,
20 module SysTools.Info,
21
22 linkDynLib,
23
24 copy,
25 copyWithHeader,
26
27 Option(..),
28
29 -- platform-specifics
30 libmLinkOpts,
31
32 -- frameworks
33 getPkgFrameworkOpts,
34 getFrameworkOpts
35 ) where
36
37 #include "HsVersions.h"
38
39 import GhcPrelude
40
41 import Module
42 import Packages
43 import Config
44 import Outputable
45 import ErrUtils
46 import Panic
47 import Platform
48 import Util
49 import DynFlags
50
51 import System.FilePath
52 import System.IO
53 import System.Directory
54 import SysTools.ExtraObj
55 import SysTools.Info
56 import SysTools.Tasks
57 import Data.List
58
59 #if defined(mingw32_HOST_OS)
60 #if MIN_VERSION_Win32(2,5,0)
61 import qualified System.Win32.Types as Win32
62 #else
63 import qualified System.Win32.Info as Win32
64 #endif
65 import Data.Char
66 import Exception
67 import Foreign
68 import Foreign.C.String
69 import System.Win32.Types (DWORD, LPTSTR, HANDLE)
70 import System.Win32.Types (failIfNull, failIf, iNVALID_HANDLE_VALUE)
71 import System.Win32.File (createFile,closeHandle, gENERIC_READ, fILE_SHARE_READ, oPEN_EXISTING, fILE_ATTRIBUTE_NORMAL, fILE_FLAG_BACKUP_SEMANTICS )
72 import System.Win32.DLL (loadLibrary, getProcAddress)
73 #endif
74
75 #if defined(mingw32_HOST_OS)
76 # if defined(i386_HOST_ARCH)
77 # define WINDOWS_CCONV stdcall
78 # elif defined(x86_64_HOST_ARCH)
79 # define WINDOWS_CCONV ccall
80 # else
81 # error Unknown mingw32 arch
82 # endif
83 #endif
84
85 {-
86 How GHC finds its files
87 ~~~~~~~~~~~~~~~~~~~~~~~
88
89 [Note topdir]
90
91 GHC needs various support files (library packages, RTS etc), plus
92 various auxiliary programs (cp, gcc, etc). It starts by finding topdir,
93 the root of GHC's support files
94
95 On Unix:
96 - ghc always has a shell wrapper that passes a -B<dir> option
97
98 On Windows:
99 - ghc never has a shell wrapper.
100 - we can find the location of the ghc binary, which is
101 $topdir/<foo>/<something>.exe
102 where <something> may be "ghc", "ghc-stage2", or similar
103 - we strip off the "<foo>/<something>.exe" to leave $topdir.
104
105 from topdir we can find package.conf, ghc-asm, etc.
106
107
108 SysTools.initSysProgs figures out exactly where all the auxiliary programs
109 are, and initialises mutable variables to make it easy to call them.
110 To to this, it makes use of definitions in Config.hs, which is a Haskell
111 file containing variables whose value is figured out by the build system.
112
113 Config.hs contains two sorts of things
114
115 cGCC, The *names* of the programs
116 cCPP e.g. cGCC = gcc
117 cUNLIT cCPP = gcc -E
118 etc They do *not* include paths
119
120
121 cUNLIT_DIR The *path* to the directory containing unlit, split etc
122 cSPLIT_DIR *relative* to the root of the build tree,
123 for use when running *in-place* in a build tree (only)
124
125
126
127 ---------------------------------------------
128 NOTES for an ALTERNATIVE scheme (i.e *not* what is currently implemented):
129
130 Another hair-brained scheme for simplifying the current tool location
131 nightmare in GHC: Simon originally suggested using another
132 configuration file along the lines of GCC's specs file - which is fine
133 except that it means adding code to read yet another configuration
134 file. What I didn't notice is that the current package.conf is
135 general enough to do this:
136
137 Package
138 {name = "tools", import_dirs = [], source_dirs = [],
139 library_dirs = [], hs_libraries = [], extra_libraries = [],
140 include_dirs = [], c_includes = [], package_deps = [],
141 extra_ghc_opts = ["-pgmc/usr/bin/gcc","-pgml${topdir}/bin/unlit", ... etc.],
142 extra_cc_opts = [], extra_ld_opts = []}
143
144 Which would have the advantage that we get to collect together in one
145 place the path-specific package stuff with the path-specific tool
146 stuff.
147 End of NOTES
148 ---------------------------------------------
149
150 ************************************************************************
151 * *
152 \subsection{Initialisation}
153 * *
154 ************************************************************************
155 -}
156
157 initLlvmTargets :: Maybe String
158 -> IO LlvmTargets
159 initLlvmTargets mbMinusB
160 = do top_dir <- findTopDir mbMinusB
161 let llvmTargetsFile = top_dir </> "llvm-targets"
162 llvmTargetsStr <- readFile llvmTargetsFile
163 case maybeReadFuzzy llvmTargetsStr of
164 Just s -> return (fmap mkLlvmTarget <$> s)
165 Nothing -> pgmError ("Can't parse " ++ show llvmTargetsFile)
166 where
167 mkLlvmTarget :: (String, String, String) -> LlvmTarget
168 mkLlvmTarget (dl, cpu, attrs) = LlvmTarget dl cpu (words attrs)
169
170
171 initSysTools :: Maybe String -- Maybe TopDir path (without the '-B' prefix)
172 -> IO Settings -- Set all the mutable variables above, holding
173 -- (a) the system programs
174 -- (b) the package-config file
175 -- (c) the GHC usage message
176 initSysTools mbMinusB
177 = do top_dir <- findTopDir mbMinusB
178 -- see [Note topdir]
179 -- NB: top_dir is assumed to be in standard Unix
180 -- format, '/' separated
181
182 let settingsFile = top_dir </> "settings"
183 platformConstantsFile = top_dir </> "platformConstants"
184 installed :: FilePath -> FilePath
185 installed file = top_dir </> file
186 libexec :: FilePath -> FilePath
187 libexec file = top_dir </> "bin" </> file
188
189 settingsStr <- readFile settingsFile
190 platformConstantsStr <- readFile platformConstantsFile
191 mySettings <- case maybeReadFuzzy settingsStr of
192 Just s ->
193 return s
194 Nothing ->
195 pgmError ("Can't parse " ++ show settingsFile)
196 platformConstants <- case maybeReadFuzzy platformConstantsStr of
197 Just s ->
198 return s
199 Nothing ->
200 pgmError ("Can't parse " ++
201 show platformConstantsFile)
202 let getSetting key = case lookup key mySettings of
203 Just xs ->
204 return $ case stripPrefix "$topdir" xs of
205 Just [] ->
206 top_dir
207 Just xs'@(c:_)
208 | isPathSeparator c ->
209 top_dir ++ xs'
210 _ ->
211 xs
212 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
213 getBooleanSetting key = case lookup key mySettings of
214 Just "YES" -> return True
215 Just "NO" -> return False
216 Just xs -> pgmError ("Bad value for " ++ show key ++ ": " ++ show xs)
217 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
218 readSetting key = case lookup key mySettings of
219 Just xs ->
220 case maybeRead xs of
221 Just v -> return v
222 Nothing -> pgmError ("Failed to read " ++ show key ++ " value " ++ show xs)
223 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
224 crossCompiling <- getBooleanSetting "cross compiling"
225 targetArch <- readSetting "target arch"
226 targetOS <- readSetting "target os"
227 targetWordSize <- readSetting "target word size"
228 targetUnregisterised <- getBooleanSetting "Unregisterised"
229 targetHasGnuNonexecStack <- readSetting "target has GNU nonexec stack"
230 targetHasIdentDirective <- readSetting "target has .ident directive"
231 targetHasSubsectionsViaSymbols <- readSetting "target has subsections via symbols"
232 myExtraGccViaCFlags <- getSetting "GCC extra via C opts"
233 -- On Windows, mingw is distributed with GHC,
234 -- so we look in TopDir/../mingw/bin
235 -- It would perhaps be nice to be able to override this
236 -- with the settings file, but it would be a little fiddly
237 -- to make that possible, so for now you can't.
238 gcc_prog <- getSetting "C compiler command"
239 gcc_args_str <- getSetting "C compiler flags"
240 gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie"
241 cpp_prog <- getSetting "Haskell CPP command"
242 cpp_args_str <- getSetting "Haskell CPP flags"
243 let unreg_gcc_args = if targetUnregisterised
244 then ["-DNO_REGS", "-DUSE_MINIINTERPRETER"]
245 else []
246 -- TABLES_NEXT_TO_CODE affects the info table layout.
247 tntc_gcc_args
248 | mkTablesNextToCode targetUnregisterised
249 = ["-DTABLES_NEXT_TO_CODE"]
250 | otherwise = []
251 cpp_args= map Option (words cpp_args_str)
252 gcc_args = map Option (words gcc_args_str
253 ++ unreg_gcc_args
254 ++ tntc_gcc_args)
255 ldSupportsCompactUnwind <- getBooleanSetting "ld supports compact unwind"
256 ldSupportsBuildId <- getBooleanSetting "ld supports build-id"
257 ldSupportsFilelist <- getBooleanSetting "ld supports filelist"
258 ldIsGnuLd <- getBooleanSetting "ld is GNU ld"
259 perl_path <- getSetting "perl command"
260
261 let pkgconfig_path = installed "package.conf.d"
262 ghc_usage_msg_path = installed "ghc-usage.txt"
263 ghci_usage_msg_path = installed "ghci-usage.txt"
264
265 -- For all systems, unlit, split, mangle are GHC utilities
266 -- architecture-specific stuff is done when building Config.hs
267 unlit_path = libexec cGHC_UNLIT_PGM
268
269 -- split is a Perl script
270 split_script = libexec cGHC_SPLIT_PGM
271
272 windres_path <- getSetting "windres command"
273 libtool_path <- getSetting "libtool command"
274 ar_path <- getSetting "ar command"
275 ranlib_path <- getSetting "ranlib command"
276
277 tmpdir <- getTemporaryDirectory
278
279 touch_path <- getSetting "touch command"
280
281 let -- On Win32 we don't want to rely on #!/bin/perl, so we prepend
282 -- a call to Perl to get the invocation of split.
283 -- On Unix, scripts are invoked using the '#!' method. Binary
284 -- installations of GHC on Unix place the correct line on the
285 -- front of the script at installation time, so we don't want
286 -- to wire-in our knowledge of $(PERL) on the host system here.
287 (split_prog, split_args)
288 | isWindowsHost = (perl_path, [Option split_script])
289 | otherwise = (split_script, [])
290 mkdll_prog <- getSetting "dllwrap command"
291 let mkdll_args = []
292
293 -- cpp is derived from gcc on all platforms
294 -- HACK, see setPgmP below. We keep 'words' here to remember to fix
295 -- Config.hs one day.
296
297
298 -- Other things being equal, as and ld are simply gcc
299 gcc_link_args_str <- getSetting "C compiler link flags"
300 let as_prog = gcc_prog
301 as_args = gcc_args
302 ld_prog = gcc_prog
303 ld_args = gcc_args ++ map Option (words gcc_link_args_str)
304
305 -- We just assume on command line
306 lc_prog <- getSetting "LLVM llc command"
307 lo_prog <- getSetting "LLVM opt command"
308 lcc_prog <- getSetting "LLVM clang command"
309
310 let iserv_prog = libexec "ghc-iserv"
311
312 let platform = Platform {
313 platformArch = targetArch,
314 platformOS = targetOS,
315 platformWordSize = targetWordSize,
316 platformUnregisterised = targetUnregisterised,
317 platformHasGnuNonexecStack = targetHasGnuNonexecStack,
318 platformHasIdentDirective = targetHasIdentDirective,
319 platformHasSubsectionsViaSymbols = targetHasSubsectionsViaSymbols,
320 platformIsCrossCompiling = crossCompiling
321 }
322
323 return $ Settings {
324 sTargetPlatform = platform,
325 sTmpDir = normalise tmpdir,
326 sGhcUsagePath = ghc_usage_msg_path,
327 sGhciUsagePath = ghci_usage_msg_path,
328 sTopDir = top_dir,
329 sRawSettings = mySettings,
330 sExtraGccViaCFlags = words myExtraGccViaCFlags,
331 sSystemPackageConfig = pkgconfig_path,
332 sLdSupportsCompactUnwind = ldSupportsCompactUnwind,
333 sLdSupportsBuildId = ldSupportsBuildId,
334 sLdSupportsFilelist = ldSupportsFilelist,
335 sLdIsGnuLd = ldIsGnuLd,
336 sGccSupportsNoPie = gccSupportsNoPie,
337 sProgramName = "ghc",
338 sProjectVersion = cProjectVersion,
339 sPgm_L = unlit_path,
340 sPgm_P = (cpp_prog, cpp_args),
341 sPgm_F = "",
342 sPgm_c = (gcc_prog, gcc_args),
343 sPgm_s = (split_prog,split_args),
344 sPgm_a = (as_prog, as_args),
345 sPgm_l = (ld_prog, ld_args),
346 sPgm_dll = (mkdll_prog,mkdll_args),
347 sPgm_T = touch_path,
348 sPgm_windres = windres_path,
349 sPgm_libtool = libtool_path,
350 sPgm_ar = ar_path,
351 sPgm_ranlib = ranlib_path,
352 sPgm_lo = (lo_prog,[]),
353 sPgm_lc = (lc_prog,[]),
354 sPgm_lcc = (lcc_prog,[]),
355 sPgm_i = iserv_prog,
356 sOpt_L = [],
357 sOpt_P = [],
358 sOpt_F = [],
359 sOpt_c = [],
360 sOpt_a = [],
361 sOpt_l = [],
362 sOpt_windres = [],
363 sOpt_lcc = [],
364 sOpt_lo = [],
365 sOpt_lc = [],
366 sOpt_i = [],
367 sPlatformConstants = platformConstants
368 }
369
370 -- returns a Unix-format path (relying on getBaseDir to do so too)
371 findTopDir :: Maybe String -- Maybe TopDir path (without the '-B' prefix).
372 -> IO String -- TopDir (in Unix format '/' separated)
373 findTopDir (Just minusb) = return (normalise minusb)
374 findTopDir Nothing
375 = do -- Get directory of executable
376 maybe_exec_dir <- getBaseDir
377 case maybe_exec_dir of
378 -- "Just" on Windows, "Nothing" on unix
379 Nothing -> throwGhcExceptionIO (InstallationError "missing -B<dir> option")
380 Just dir -> return dir
381
382 {- Note [Windows stack usage]
383
384 See: Trac #8870 (and #8834 for related info) and #12186
385
386 On Windows, occasionally we need to grow the stack. In order to do
387 this, we would normally just bump the stack pointer - but there's a
388 catch on Windows.
389
390 If the stack pointer is bumped by more than a single page, then the
391 pages between the initial pointer and the resulting location must be
392 properly committed by the Windows virtual memory subsystem. This is
393 only needed in the event we bump by more than one page (i.e 4097 bytes
394 or more).
395
396 Windows compilers solve this by emitting a call to a special function
397 called _chkstk, which does this committing of the pages for you.
398
399 The reason this was causing a segfault was because due to the fact the
400 new code generator tends to generate larger functions, we needed more
401 stack space in GHC itself. In the x86 codegen, we needed approximately
402 ~12kb of stack space in one go, which caused the process to segfault,
403 as the intervening pages were not committed.
404
405 GCC can emit such a check for us automatically but only when the flag
406 -fstack-check is used.
407
408 See https://gcc.gnu.org/onlinedocs/gnat_ugn/Stack-Overflow-Checking.html
409 for more information.
410
411 -}
412
413 copy :: DynFlags -> String -> FilePath -> FilePath -> IO ()
414 copy dflags purpose from to = copyWithHeader dflags purpose Nothing from to
415
416 copyWithHeader :: DynFlags -> String -> Maybe String -> FilePath -> FilePath
417 -> IO ()
418 copyWithHeader dflags purpose maybe_header from to = do
419 showPass dflags purpose
420
421 hout <- openBinaryFile to WriteMode
422 hin <- openBinaryFile from ReadMode
423 ls <- hGetContents hin -- inefficient, but it'll do for now. ToDo: speed up
424 maybe (return ()) (header hout) maybe_header
425 hPutStr hout ls
426 hClose hout
427 hClose hin
428 where
429 -- write the header string in UTF-8. The header is something like
430 -- {-# LINE "foo.hs" #-}
431 -- and we want to make sure a Unicode filename isn't mangled.
432 header h str = do
433 hSetEncoding h utf8
434 hPutStr h str
435 hSetBinaryMode h True
436
437 {-
438 ************************************************************************
439 * *
440 \subsection{Support code}
441 * *
442 ************************************************************************
443 -}
444
445 -----------------------------------------------------------------------------
446 -- Define getBaseDir :: IO (Maybe String)
447
448 getBaseDir :: IO (Maybe String)
449 #if defined(mingw32_HOST_OS)
450 -- Assuming we are running ghc, accessed by path $(stuff)/<foo>/ghc.exe,
451 -- return the path $(stuff)/lib.
452 getBaseDir = try_size 2048 -- plenty, PATH_MAX is 512 under Win32.
453 where
454 try_size size = allocaArray (fromIntegral size) $ \buf -> do
455 ret <- c_GetModuleFileName nullPtr buf size
456 case ret of
457 0 -> return Nothing
458 _ | ret < size -> do
459 path <- peekCWString buf
460 real <- getFinalPath path -- try to resolve symlinks paths
461 let libdir = (rootDir . sanitize . maybe path id) real
462 exists <- doesDirectoryExist libdir
463 if exists
464 then return $ Just libdir
465 else fail path
466 | otherwise -> try_size (size * 2)
467
468 -- getFinalPath returns paths in full raw form.
469 -- Unfortunately GHC isn't set up to handle these
470 -- So if the call succeeded, we need to drop the
471 -- \\?\ prefix.
472 sanitize s = if "\\\\?\\" `isPrefixOf` s
473 then drop 4 s
474 else s
475
476 rootDir s = case splitFileName $ normalise s of
477 (d, ghc_exe)
478 | lower ghc_exe `elem` ["ghc.exe",
479 "ghc-stage1.exe",
480 "ghc-stage2.exe",
481 "ghc-stage3.exe"] ->
482 case splitFileName $ takeDirectory d of
483 -- ghc is in $topdir/bin/ghc.exe
484 (d', _) -> takeDirectory d' </> "lib"
485 _ -> fail s
486
487 fail s = panic ("can't decompose ghc.exe path: " ++ show s)
488 lower = map toLower
489
490 foreign import WINDOWS_CCONV unsafe "windows.h GetModuleFileNameW"
491 c_GetModuleFileName :: Ptr () -> CWString -> Word32 -> IO Word32
492
493 -- Attempt to resolve symlinks in order to find the actual location GHC
494 -- is located at. See Trac #11759.
495 getFinalPath :: FilePath -> IO (Maybe FilePath)
496 getFinalPath name = do
497 dllHwnd <- failIfNull "LoadLibrary" $ loadLibrary "kernel32.dll"
498 -- Note: The API GetFinalPathNameByHandleW is only available starting from Windows Vista.
499 -- This means that we can't bind directly to it since it may be missing.
500 -- Instead try to find it's address at runtime and if we don't succeed consider the
501 -- function failed.
502 addr_m <- (fmap Just $ failIfNull "getProcAddress" $ getProcAddress dllHwnd "GetFinalPathNameByHandleW")
503 `catch` (\(_ :: SomeException) -> return Nothing)
504 case addr_m of
505 Nothing -> return Nothing
506 Just addr -> do handle <- failIf (==iNVALID_HANDLE_VALUE) "CreateFile"
507 $ createFile name
508 gENERIC_READ
509 fILE_SHARE_READ
510 Nothing
511 oPEN_EXISTING
512 (fILE_ATTRIBUTE_NORMAL .|. fILE_FLAG_BACKUP_SEMANTICS)
513 Nothing
514 let fnPtr = makeGetFinalPathNameByHandle $ castPtrToFunPtr addr
515 -- First try to resolve the path to get the actual path
516 -- of any symlinks or other file system redirections that
517 -- may be in place. However this function can fail, and in
518 -- the event it does fail, we need to try using the
519 -- original path and see if we can decompose that.
520 -- If the call fails Win32.try will raise an exception
521 -- that needs to be caught. See #14159
522 path <- (Win32.try "GetFinalPathName"
523 (\buf len -> fnPtr handle buf len 0) 512
524 `finally` closeHandle handle)
525 `catch`
526 (\(_ :: IOException) -> return name)
527 return $ Just path
528
529 type GetFinalPath = HANDLE -> LPTSTR -> DWORD -> DWORD -> IO DWORD
530
531 foreign import WINDOWS_CCONV unsafe "dynamic"
532 makeGetFinalPathNameByHandle :: FunPtr GetFinalPath -> GetFinalPath
533 #else
534 getBaseDir = return Nothing
535 #endif
536
537 linkDynLib :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
538 linkDynLib dflags0 o_files dep_packages
539 = do
540 let -- This is a rather ugly hack to fix dynamically linked
541 -- GHC on Windows. If GHC is linked with -threaded, then
542 -- it links against libHSrts_thr. But if base is linked
543 -- against libHSrts, then both end up getting loaded,
544 -- and things go wrong. We therefore link the libraries
545 -- with the same RTS flags that we link GHC with.
546 dflags1 = if cGhcThreaded then addWay' WayThreaded dflags0
547 else dflags0
548 dflags2 = if cGhcDebugged then addWay' WayDebug dflags1
549 else dflags1
550 dflags = updateWays dflags2
551
552 verbFlags = getVerbFlags dflags
553 o_file = outputFile dflags
554
555 pkgs <- getPreloadPackagesAnd dflags dep_packages
556
557 let pkg_lib_paths = collectLibraryPaths dflags pkgs
558 let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
559 get_pkg_lib_path_opts l
560 | ( osElfTarget (platformOS (targetPlatform dflags)) ||
561 osMachOTarget (platformOS (targetPlatform dflags)) ) &&
562 dynLibLoader dflags == SystemDependent &&
563 WayDyn `elem` ways dflags
564 = ["-L" ++ l, "-Xlinker", "-rpath", "-Xlinker", l]
565 -- See Note [-Xlinker -rpath vs -Wl,-rpath]
566 | otherwise = ["-L" ++ l]
567
568 let lib_paths = libraryPaths dflags
569 let lib_path_opts = map ("-L"++) lib_paths
570
571 -- We don't want to link our dynamic libs against the RTS package,
572 -- because the RTS lib comes in several flavours and we want to be
573 -- able to pick the flavour when a binary is linked.
574 -- On Windows we need to link the RTS import lib as Windows does
575 -- not allow undefined symbols.
576 -- The RTS library path is still added to the library search path
577 -- above in case the RTS is being explicitly linked in (see #3807).
578 let platform = targetPlatform dflags
579 os = platformOS platform
580 pkgs_no_rts = case os of
581 OSMinGW32 ->
582 pkgs
583 _ ->
584 filter ((/= rtsUnitId) . packageConfigId) pkgs
585 let pkg_link_opts = let (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs_no_rts
586 in package_hs_libs ++ extra_libs ++ other_flags
587
588 -- probably _stub.o files
589 -- and last temporary shared object file
590 let extra_ld_inputs = ldInputs dflags
591
592 -- frameworks
593 pkg_framework_opts <- getPkgFrameworkOpts dflags platform
594 (map unitId pkgs)
595 let framework_opts = getFrameworkOpts dflags platform
596
597 case os of
598 OSMinGW32 -> do
599 -------------------------------------------------------------
600 -- Making a DLL
601 -------------------------------------------------------------
602 let output_fn = case o_file of
603 Just s -> s
604 Nothing -> "HSdll.dll"
605
606 runLink dflags (
607 map Option verbFlags
608 ++ [ Option "-o"
609 , FileOption "" output_fn
610 , Option "-shared"
611 ] ++
612 [ FileOption "-Wl,--out-implib=" (output_fn ++ ".a")
613 | gopt Opt_SharedImplib dflags
614 ]
615 ++ map (FileOption "") o_files
616
617 -- Permit the linker to auto link _symbol to _imp_symbol
618 -- This lets us link against DLLs without needing an "import library"
619 ++ [Option "-Wl,--enable-auto-import"]
620
621 ++ extra_ld_inputs
622 ++ map Option (
623 lib_path_opts
624 ++ pkg_lib_path_opts
625 ++ pkg_link_opts
626 ))
627 _ | os == OSDarwin -> do
628 -------------------------------------------------------------------
629 -- Making a darwin dylib
630 -------------------------------------------------------------------
631 -- About the options used for Darwin:
632 -- -dynamiclib
633 -- Apple's way of saying -shared
634 -- -undefined dynamic_lookup:
635 -- Without these options, we'd have to specify the correct
636 -- dependencies for each of the dylibs. Note that we could
637 -- (and should) do without this for all libraries except
638 -- the RTS; all we need to do is to pass the correct
639 -- HSfoo_dyn.dylib files to the link command.
640 -- This feature requires Mac OS X 10.3 or later; there is
641 -- a similar feature, -flat_namespace -undefined suppress,
642 -- which works on earlier versions, but it has other
643 -- disadvantages.
644 -- -single_module
645 -- Build the dynamic library as a single "module", i.e. no
646 -- dynamic binding nonsense when referring to symbols from
647 -- within the library. The NCG assumes that this option is
648 -- specified (on i386, at least).
649 -- -install_name
650 -- Mac OS/X stores the path where a dynamic library is (to
651 -- be) installed in the library itself. It's called the
652 -- "install name" of the library. Then any library or
653 -- executable that links against it before it's installed
654 -- will search for it in its ultimate install location.
655 -- By default we set the install name to the absolute path
656 -- at build time, but it can be overridden by the
657 -- -dylib-install-name option passed to ghc. Cabal does
658 -- this.
659 -------------------------------------------------------------------
660
661 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
662
663 instName <- case dylibInstallName dflags of
664 Just n -> return n
665 Nothing -> return $ "@rpath" `combine` (takeFileName output_fn)
666 runLink dflags (
667 map Option verbFlags
668 ++ [ Option "-dynamiclib"
669 , Option "-o"
670 , FileOption "" output_fn
671 ]
672 ++ map Option o_files
673 ++ [ Option "-undefined",
674 Option "dynamic_lookup",
675 Option "-single_module" ]
676 ++ (if platformArch platform == ArchX86_64
677 then [ ]
678 else [ Option "-Wl,-read_only_relocs,suppress" ])
679 ++ [ Option "-install_name", Option instName ]
680 ++ map Option lib_path_opts
681 ++ extra_ld_inputs
682 ++ map Option framework_opts
683 ++ map Option pkg_lib_path_opts
684 ++ map Option pkg_link_opts
685 ++ map Option pkg_framework_opts
686 )
687 _ -> do
688 -------------------------------------------------------------------
689 -- Making a DSO
690 -------------------------------------------------------------------
691
692 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
693 let bsymbolicFlag = -- we need symbolic linking to resolve
694 -- non-PIC intra-package-relocations
695 ["-Wl,-Bsymbolic"]
696
697 runLink dflags (
698 map Option verbFlags
699 ++ libmLinkOpts
700 ++ [ Option "-o"
701 , FileOption "" output_fn
702 ]
703 ++ map Option o_files
704 ++ [ Option "-shared" ]
705 ++ map Option bsymbolicFlag
706 -- Set the library soname. We use -h rather than -soname as
707 -- Solaris 10 doesn't support the latter:
708 ++ [ Option ("-Wl,-h," ++ takeFileName output_fn) ]
709 ++ extra_ld_inputs
710 ++ map Option lib_path_opts
711 ++ map Option pkg_lib_path_opts
712 ++ map Option pkg_link_opts
713 )
714
715 -- | Some platforms require that we explicitly link against @libm@ if any
716 -- math-y things are used (which we assume to include all programs). See #14022.
717 libmLinkOpts :: [Option]
718 libmLinkOpts =
719 #if defined(HAVE_LIBM)
720 [Option "-lm"]
721 #else
722 []
723 #endif
724
725 getPkgFrameworkOpts :: DynFlags -> Platform -> [InstalledUnitId] -> IO [String]
726 getPkgFrameworkOpts dflags platform dep_packages
727 | platformUsesFrameworks platform = do
728 pkg_framework_path_opts <- do
729 pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages
730 return $ map ("-F" ++) pkg_framework_paths
731
732 pkg_framework_opts <- do
733 pkg_frameworks <- getPackageFrameworks dflags dep_packages
734 return $ concat [ ["-framework", fw] | fw <- pkg_frameworks ]
735
736 return (pkg_framework_path_opts ++ pkg_framework_opts)
737
738 | otherwise = return []
739
740 getFrameworkOpts :: DynFlags -> Platform -> [String]
741 getFrameworkOpts dflags platform
742 | platformUsesFrameworks platform = framework_path_opts ++ framework_opts
743 | otherwise = []
744 where
745 framework_paths = frameworkPaths dflags
746 framework_path_opts = map ("-F" ++) framework_paths
747
748 frameworks = cmdlineFrameworks dflags
749 -- reverse because they're added in reverse order from the cmd line:
750 framework_opts = concat [ ["-framework", fw]
751 | fw <- reverse frameworks ]