Remove all target-specific portions of Config.hs
[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 initLlvmConfig,
17
18 -- * Interface to system tools
19 module SysTools.Tasks,
20 module SysTools.Info,
21
22 linkDynLib,
23
24 copy,
25 copyWithHeader,
26
27 -- * General utilities
28 Option(..),
29 expandTopDir,
30
31 -- * Platform-specifics
32 libmLinkOpts,
33
34 -- * Mac OS X frameworks
35 getPkgFrameworkOpts,
36 getFrameworkOpts
37 ) where
38
39 #include "HsVersions.h"
40
41 import GhcPrelude
42
43 import Module
44 import Packages
45 import Config
46 import Outputable
47 import ErrUtils
48 import Platform
49 import Util
50 import DynFlags
51 import Fingerprint
52
53 import System.FilePath
54 import System.IO
55 import System.Directory
56 import SysTools.ExtraObj
57 import SysTools.Info
58 import SysTools.Tasks
59 import SysTools.BaseDir
60
61 {-
62 Note [How GHC finds toolchain utilities]
63 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64
65 SysTools.initSysProgs figures out exactly where all the auxiliary programs
66 are, and initialises mutable variables to make it easy to call them.
67 To do this, it makes use of definitions in Config.hs, which is a Haskell
68 file containing variables whose value is figured out by the build system.
69
70 Config.hs contains two sorts of things
71
72 cGCC, The *names* of the programs
73 cCPP e.g. cGCC = gcc
74 cUNLIT cCPP = gcc -E
75 etc They do *not* include paths
76
77
78 cUNLIT_DIR The *path* to the directory containing unlit, split etc
79 cSPLIT_DIR *relative* to the root of the build tree,
80 for use when running *in-place* in a build tree (only)
81
82
83 ---------------------------------------------
84 NOTES for an ALTERNATIVE scheme (i.e *not* what is currently implemented):
85
86 Another hair-brained scheme for simplifying the current tool location
87 nightmare in GHC: Simon originally suggested using another
88 configuration file along the lines of GCC's specs file - which is fine
89 except that it means adding code to read yet another configuration
90 file. What I didn't notice is that the current package.conf is
91 general enough to do this:
92
93 Package
94 {name = "tools", import_dirs = [], source_dirs = [],
95 library_dirs = [], hs_libraries = [], extra_libraries = [],
96 include_dirs = [], c_includes = [], package_deps = [],
97 extra_ghc_opts = ["-pgmc/usr/bin/gcc","-pgml${topdir}/bin/unlit", ... etc.],
98 extra_cc_opts = [], extra_ld_opts = []}
99
100 Which would have the advantage that we get to collect together in one
101 place the path-specific package stuff with the path-specific tool
102 stuff.
103 End of NOTES
104 ---------------------------------------------
105
106 ************************************************************************
107 * *
108 \subsection{Initialisation}
109 * *
110 ************************************************************************
111 -}
112
113 initLlvmConfig :: String
114 -> IO LlvmConfig
115 initLlvmConfig top_dir
116 = do
117 targets <- readAndParse "llvm-targets" mkLlvmTarget
118 passes <- readAndParse "llvm-passes" id
119 return (targets, passes)
120 where
121 readAndParse name builder =
122 do let llvmConfigFile = top_dir </> name
123 llvmConfigStr <- readFile llvmConfigFile
124 case maybeReadFuzzy llvmConfigStr of
125 Just s -> return (fmap builder <$> s)
126 Nothing -> pgmError ("Can't parse " ++ show llvmConfigFile)
127
128 mkLlvmTarget :: (String, String, String) -> LlvmTarget
129 mkLlvmTarget (dl, cpu, attrs) = LlvmTarget dl cpu (words attrs)
130
131
132 initSysTools :: String -- TopDir path
133 -> IO Settings -- Set all the mutable variables above, holding
134 -- (a) the system programs
135 -- (b) the package-config file
136 -- (c) the GHC usage message
137 initSysTools top_dir
138 = do -- see Note [topdir: How GHC finds its files]
139 -- NB: top_dir is assumed to be in standard Unix
140 -- format, '/' separated
141 mtool_dir <- findToolDir top_dir
142 -- see Note [tooldir: How GHC finds mingw on Windows]
143
144 let installed :: FilePath -> FilePath
145 installed file = top_dir </> file
146 libexec :: FilePath -> FilePath
147 libexec file = top_dir </> "bin" </> file
148 settingsFile = installed "settings"
149 platformConstantsFile = installed "platformConstants"
150
151 settingsStr <- readFile settingsFile
152 platformConstantsStr <- readFile platformConstantsFile
153 mySettings <- case maybeReadFuzzy settingsStr of
154 Just s ->
155 return s
156 Nothing ->
157 pgmError ("Can't parse " ++ show settingsFile)
158 platformConstants <- case maybeReadFuzzy platformConstantsStr of
159 Just s ->
160 return s
161 Nothing ->
162 pgmError ("Can't parse " ++
163 show platformConstantsFile)
164 let getSetting key = case lookup key mySettings of
165 Just xs -> return $ expandTopDir top_dir xs
166 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
167 getToolSetting key = expandToolDir mtool_dir <$> getSetting key
168 getBooleanSetting key = case lookup key mySettings of
169 Just "YES" -> return True
170 Just "NO" -> return False
171 Just xs -> pgmError ("Bad value for " ++ show key ++ ": " ++ show xs)
172 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
173 readSetting key = case lookup key mySettings of
174 Just xs ->
175 case maybeRead xs of
176 Just v -> return v
177 Nothing -> pgmError ("Failed to read " ++ show key ++ " value " ++ show xs)
178 Nothing -> pgmError ("No entry for " ++ show key ++ " in " ++ show settingsFile)
179 crossCompiling <- getBooleanSetting "cross compiling"
180 targetPlatformString <- getSetting "target platform string"
181 targetArch <- readSetting "target arch"
182 targetOS <- readSetting "target os"
183 targetWordSize <- readSetting "target word size"
184 targetUnregisterised <- getBooleanSetting "Unregisterised"
185 targetHasGnuNonexecStack <- readSetting "target has GNU nonexec stack"
186 targetHasIdentDirective <- readSetting "target has .ident directive"
187 targetHasSubsectionsViaSymbols <- readSetting "target has subsections via symbols"
188 tablesNextToCode <- getBooleanSetting "Tables next to code"
189 myExtraGccViaCFlags <- getSetting "GCC extra via C opts"
190 -- On Windows, mingw is distributed with GHC,
191 -- so we look in TopDir/../mingw/bin,
192 -- as well as TopDir/../../mingw/bin for hadrian.
193 -- It would perhaps be nice to be able to override this
194 -- with the settings file, but it would be a little fiddly
195 -- to make that possible, so for now you can't.
196 gcc_prog <- getToolSetting "C compiler command"
197 gcc_args_str <- getSetting "C compiler flags"
198 gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie"
199 cpp_prog <- getToolSetting "Haskell CPP command"
200 cpp_args_str <- getSetting "Haskell CPP flags"
201 let unreg_gcc_args = if targetUnregisterised
202 then ["-DNO_REGS", "-DUSE_MINIINTERPRETER"]
203 else []
204 cpp_args= map Option (words cpp_args_str)
205 gcc_args = map Option (words gcc_args_str
206 ++ unreg_gcc_args)
207 ldSupportsCompactUnwind <- getBooleanSetting "ld supports compact unwind"
208 ldSupportsBuildId <- getBooleanSetting "ld supports build-id"
209 ldSupportsFilelist <- getBooleanSetting "ld supports filelist"
210 ldIsGnuLd <- getBooleanSetting "ld is GNU ld"
211
212 let pkgconfig_path = installed "package.conf.d"
213 ghc_usage_msg_path = installed "ghc-usage.txt"
214 ghci_usage_msg_path = installed "ghci-usage.txt"
215
216 -- For all systems, unlit, split, mangle are GHC utilities
217 -- architecture-specific stuff is done when building Config.hs
218 unlit_path <- getToolSetting "unlit command"
219
220 windres_path <- getToolSetting "windres command"
221 libtool_path <- getToolSetting "libtool command"
222 ar_path <- getToolSetting "ar command"
223 ranlib_path <- getToolSetting "ranlib command"
224
225 tmpdir <- getTemporaryDirectory
226
227 touch_path <- getToolSetting "touch command"
228
229 mkdll_prog <- getToolSetting "dllwrap command"
230 let mkdll_args = []
231
232 -- cpp is derived from gcc on all platforms
233 -- HACK, see setPgmP below. We keep 'words' here to remember to fix
234 -- Config.hs one day.
235
236
237 -- Other things being equal, as and ld are simply gcc
238 gcc_link_args_str <- getSetting "C compiler link flags"
239 let as_prog = gcc_prog
240 as_args = gcc_args
241 ld_prog = gcc_prog
242 ld_args = gcc_args ++ map Option (words gcc_link_args_str)
243
244 -- We just assume on command line
245 lc_prog <- getSetting "LLVM llc command"
246 lo_prog <- getSetting "LLVM opt command"
247 lcc_prog <- getSetting "LLVM clang command"
248
249 let iserv_prog = libexec "ghc-iserv"
250
251 let platform = Platform {
252 platformArch = targetArch,
253 platformOS = targetOS,
254 platformWordSize = targetWordSize,
255 platformUnregisterised = targetUnregisterised,
256 platformHasGnuNonexecStack = targetHasGnuNonexecStack,
257 platformHasIdentDirective = targetHasIdentDirective,
258 platformHasSubsectionsViaSymbols = targetHasSubsectionsViaSymbols,
259 platformIsCrossCompiling = crossCompiling
260 }
261
262 integerLibrary <- getSetting "integer library"
263 integerLibraryType <- case integerLibrary of
264 "integer-gmp" -> pure IntegerGMP
265 "integer-simple" -> pure IntegerSimple
266 _ -> pgmError $ unwords
267 [ "Entry for"
268 , show "integer library"
269 , "must be one of"
270 , show "integer-gmp"
271 , "or"
272 , show "integer-simple"
273 ]
274
275 ghcWithInterpreter <- getBooleanSetting "Use interpreter"
276 ghcWithNativeCodeGen <- getBooleanSetting "Use native code generator"
277 ghcWithSMP <- getBooleanSetting "Support SMP"
278 ghcRTSWays <- getSetting "RTS ways"
279 leadingUnderscore <- getBooleanSetting "Leading underscore"
280 useLibFFI <- getBooleanSetting "Use LibFFI"
281 ghcThreaded <- getBooleanSetting "Use Threads"
282 ghcDebugged <- getBooleanSetting "Use Debugging"
283 ghcRtsWithLibdw <- getBooleanSetting "RTS expects libdw"
284
285 return $ Settings {
286 sTargetPlatform = platform,
287 sTmpDir = normalise tmpdir,
288 sGhcUsagePath = ghc_usage_msg_path,
289 sGhciUsagePath = ghci_usage_msg_path,
290 sToolDir = mtool_dir,
291 sTopDir = top_dir,
292 sRawSettings = mySettings,
293 sExtraGccViaCFlags = words myExtraGccViaCFlags,
294 sSystemPackageConfig = pkgconfig_path,
295 sLdSupportsCompactUnwind = ldSupportsCompactUnwind,
296 sLdSupportsBuildId = ldSupportsBuildId,
297 sLdSupportsFilelist = ldSupportsFilelist,
298 sLdIsGnuLd = ldIsGnuLd,
299 sGccSupportsNoPie = gccSupportsNoPie,
300 sProgramName = "ghc",
301 sProjectVersion = cProjectVersion,
302 sPgm_L = unlit_path,
303 sPgm_P = (cpp_prog, cpp_args),
304 sPgm_F = "",
305 sPgm_c = (gcc_prog, gcc_args),
306 sPgm_a = (as_prog, as_args),
307 sPgm_l = (ld_prog, ld_args),
308 sPgm_dll = (mkdll_prog,mkdll_args),
309 sPgm_T = touch_path,
310 sPgm_windres = windres_path,
311 sPgm_libtool = libtool_path,
312 sPgm_ar = ar_path,
313 sPgm_ranlib = ranlib_path,
314 sPgm_lo = (lo_prog,[]),
315 sPgm_lc = (lc_prog,[]),
316 sPgm_lcc = (lcc_prog,[]),
317 sPgm_i = iserv_prog,
318 sOpt_L = [],
319 sOpt_P = [],
320 sOpt_P_fingerprint = fingerprint0,
321 sOpt_F = [],
322 sOpt_c = [],
323 sOpt_cxx = [],
324 sOpt_a = [],
325 sOpt_l = [],
326 sOpt_windres = [],
327 sOpt_lcc = [],
328 sOpt_lo = [],
329 sOpt_lc = [],
330 sOpt_i = [],
331 sPlatformConstants = platformConstants,
332
333 sTargetPlatformString = targetPlatformString,
334 sIntegerLibrary = integerLibrary,
335 sIntegerLibraryType = integerLibraryType,
336 sGhcWithInterpreter = ghcWithInterpreter,
337 sGhcWithNativeCodeGen = ghcWithNativeCodeGen,
338 sGhcWithSMP = ghcWithSMP,
339 sGhcRTSWays = ghcRTSWays,
340 sTablesNextToCode = tablesNextToCode,
341 sLeadingUnderscore = leadingUnderscore,
342 sLibFFI = useLibFFI,
343 sGhcThreaded = ghcThreaded,
344 sGhcDebugged = ghcDebugged,
345 sGhcRtsWithLibdw = ghcRtsWithLibdw
346 }
347
348
349 {- Note [Windows stack usage]
350
351 See: #8870 (and #8834 for related info) and #12186
352
353 On Windows, occasionally we need to grow the stack. In order to do
354 this, we would normally just bump the stack pointer - but there's a
355 catch on Windows.
356
357 If the stack pointer is bumped by more than a single page, then the
358 pages between the initial pointer and the resulting location must be
359 properly committed by the Windows virtual memory subsystem. This is
360 only needed in the event we bump by more than one page (i.e 4097 bytes
361 or more).
362
363 Windows compilers solve this by emitting a call to a special function
364 called _chkstk, which does this committing of the pages for you.
365
366 The reason this was causing a segfault was because due to the fact the
367 new code generator tends to generate larger functions, we needed more
368 stack space in GHC itself. In the x86 codegen, we needed approximately
369 ~12kb of stack space in one go, which caused the process to segfault,
370 as the intervening pages were not committed.
371
372 GCC can emit such a check for us automatically but only when the flag
373 -fstack-check is used.
374
375 See https://gcc.gnu.org/onlinedocs/gnat_ugn/Stack-Overflow-Checking.html
376 for more information.
377
378 -}
379
380 copy :: DynFlags -> String -> FilePath -> FilePath -> IO ()
381 copy dflags purpose from to = copyWithHeader dflags purpose Nothing from to
382
383 copyWithHeader :: DynFlags -> String -> Maybe String -> FilePath -> FilePath
384 -> IO ()
385 copyWithHeader dflags purpose maybe_header from to = do
386 showPass dflags purpose
387
388 hout <- openBinaryFile to WriteMode
389 hin <- openBinaryFile from ReadMode
390 ls <- hGetContents hin -- inefficient, but it'll do for now. ToDo: speed up
391 maybe (return ()) (header hout) maybe_header
392 hPutStr hout ls
393 hClose hout
394 hClose hin
395 where
396 -- write the header string in UTF-8. The header is something like
397 -- {-# LINE "foo.hs" #-}
398 -- and we want to make sure a Unicode filename isn't mangled.
399 header h str = do
400 hSetEncoding h utf8
401 hPutStr h str
402 hSetBinaryMode h True
403
404 {-
405 ************************************************************************
406 * *
407 \subsection{Support code}
408 * *
409 ************************************************************************
410 -}
411
412 linkDynLib :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
413 linkDynLib dflags0 o_files dep_packages
414 = do
415 let -- This is a rather ugly hack to fix dynamically linked
416 -- GHC on Windows. If GHC is linked with -threaded, then
417 -- it links against libHSrts_thr. But if base is linked
418 -- against libHSrts, then both end up getting loaded,
419 -- and things go wrong. We therefore link the libraries
420 -- with the same RTS flags that we link GHC with.
421 dflags1 = if sGhcThreaded $ settings dflags0
422 then addWay' WayThreaded dflags0
423 else dflags0
424 dflags2 = if sGhcDebugged $ settings dflags1
425 then addWay' WayDebug dflags1
426 else dflags1
427 dflags = updateWays dflags2
428
429 verbFlags = getVerbFlags dflags
430 o_file = outputFile dflags
431
432 pkgs <- getPreloadPackagesAnd dflags dep_packages
433
434 let pkg_lib_paths = collectLibraryPaths dflags pkgs
435 let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
436 get_pkg_lib_path_opts l
437 | ( osElfTarget (platformOS (targetPlatform dflags)) ||
438 osMachOTarget (platformOS (targetPlatform dflags)) ) &&
439 dynLibLoader dflags == SystemDependent &&
440 WayDyn `elem` ways dflags
441 = ["-L" ++ l, "-Xlinker", "-rpath", "-Xlinker", l]
442 -- See Note [-Xlinker -rpath vs -Wl,-rpath]
443 | otherwise = ["-L" ++ l]
444
445 let lib_paths = libraryPaths dflags
446 let lib_path_opts = map ("-L"++) lib_paths
447
448 -- We don't want to link our dynamic libs against the RTS package,
449 -- because the RTS lib comes in several flavours and we want to be
450 -- able to pick the flavour when a binary is linked.
451 -- On Windows we need to link the RTS import lib as Windows does
452 -- not allow undefined symbols.
453 -- The RTS library path is still added to the library search path
454 -- above in case the RTS is being explicitly linked in (see #3807).
455 let platform = targetPlatform dflags
456 os = platformOS platform
457 pkgs_no_rts = case os of
458 OSMinGW32 ->
459 pkgs
460 _ ->
461 filter ((/= rtsUnitId) . packageConfigId) pkgs
462 let pkg_link_opts = let (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs_no_rts
463 in package_hs_libs ++ extra_libs ++ other_flags
464
465 -- probably _stub.o files
466 -- and last temporary shared object file
467 let extra_ld_inputs = ldInputs dflags
468
469 -- frameworks
470 pkg_framework_opts <- getPkgFrameworkOpts dflags platform
471 (map unitId pkgs)
472 let framework_opts = getFrameworkOpts dflags platform
473
474 case os of
475 OSMinGW32 -> do
476 -------------------------------------------------------------
477 -- Making a DLL
478 -------------------------------------------------------------
479 let output_fn = case o_file of
480 Just s -> s
481 Nothing -> "HSdll.dll"
482
483 runLink dflags (
484 map Option verbFlags
485 ++ [ Option "-o"
486 , FileOption "" output_fn
487 , Option "-shared"
488 ] ++
489 [ FileOption "-Wl,--out-implib=" (output_fn ++ ".a")
490 | gopt Opt_SharedImplib dflags
491 ]
492 ++ map (FileOption "") o_files
493
494 -- Permit the linker to auto link _symbol to _imp_symbol
495 -- This lets us link against DLLs without needing an "import library"
496 ++ [Option "-Wl,--enable-auto-import"]
497
498 ++ extra_ld_inputs
499 ++ map Option (
500 lib_path_opts
501 ++ pkg_lib_path_opts
502 ++ pkg_link_opts
503 ))
504 _ | os == OSDarwin -> do
505 -------------------------------------------------------------------
506 -- Making a darwin dylib
507 -------------------------------------------------------------------
508 -- About the options used for Darwin:
509 -- -dynamiclib
510 -- Apple's way of saying -shared
511 -- -undefined dynamic_lookup:
512 -- Without these options, we'd have to specify the correct
513 -- dependencies for each of the dylibs. Note that we could
514 -- (and should) do without this for all libraries except
515 -- the RTS; all we need to do is to pass the correct
516 -- HSfoo_dyn.dylib files to the link command.
517 -- This feature requires Mac OS X 10.3 or later; there is
518 -- a similar feature, -flat_namespace -undefined suppress,
519 -- which works on earlier versions, but it has other
520 -- disadvantages.
521 -- -single_module
522 -- Build the dynamic library as a single "module", i.e. no
523 -- dynamic binding nonsense when referring to symbols from
524 -- within the library. The NCG assumes that this option is
525 -- specified (on i386, at least).
526 -- -install_name
527 -- Mac OS/X stores the path where a dynamic library is (to
528 -- be) installed in the library itself. It's called the
529 -- "install name" of the library. Then any library or
530 -- executable that links against it before it's installed
531 -- will search for it in its ultimate install location.
532 -- By default we set the install name to the absolute path
533 -- at build time, but it can be overridden by the
534 -- -dylib-install-name option passed to ghc. Cabal does
535 -- this.
536 -------------------------------------------------------------------
537
538 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
539
540 instName <- case dylibInstallName dflags of
541 Just n -> return n
542 Nothing -> return $ "@rpath" `combine` (takeFileName output_fn)
543 runLink dflags (
544 map Option verbFlags
545 ++ [ Option "-dynamiclib"
546 , Option "-o"
547 , FileOption "" output_fn
548 ]
549 ++ map Option o_files
550 ++ [ Option "-undefined",
551 Option "dynamic_lookup",
552 Option "-single_module" ]
553 ++ (if platformArch platform == ArchX86_64
554 then [ ]
555 else [ Option "-Wl,-read_only_relocs,suppress" ])
556 ++ [ Option "-install_name", Option instName ]
557 ++ map Option lib_path_opts
558 ++ extra_ld_inputs
559 ++ map Option framework_opts
560 ++ map Option pkg_lib_path_opts
561 ++ map Option pkg_link_opts
562 ++ map Option pkg_framework_opts
563 ++ [ Option "-Wl,-dead_strip_dylibs" ]
564 )
565 _ -> do
566 -------------------------------------------------------------------
567 -- Making a DSO
568 -------------------------------------------------------------------
569
570 let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
571 unregisterised = platformUnregisterised (targetPlatform dflags)
572 let bsymbolicFlag = -- we need symbolic linking to resolve
573 -- non-PIC intra-package-relocations for
574 -- performance (where symbolic linking works)
575 -- See Note [-Bsymbolic assumptions by GHC]
576 ["-Wl,-Bsymbolic" | not unregisterised]
577
578 runLink dflags (
579 map Option verbFlags
580 ++ libmLinkOpts
581 ++ [ Option "-o"
582 , FileOption "" output_fn
583 ]
584 ++ map Option o_files
585 ++ [ Option "-shared" ]
586 ++ map Option bsymbolicFlag
587 -- Set the library soname. We use -h rather than -soname as
588 -- Solaris 10 doesn't support the latter:
589 ++ [ Option ("-Wl,-h," ++ takeFileName output_fn) ]
590 ++ extra_ld_inputs
591 ++ map Option lib_path_opts
592 ++ map Option pkg_lib_path_opts
593 ++ map Option pkg_link_opts
594 )
595
596 -- | Some platforms require that we explicitly link against @libm@ if any
597 -- math-y things are used (which we assume to include all programs). See #14022.
598 libmLinkOpts :: [Option]
599 libmLinkOpts =
600 #if defined(HAVE_LIBM)
601 [Option "-lm"]
602 #else
603 []
604 #endif
605
606 getPkgFrameworkOpts :: DynFlags -> Platform -> [InstalledUnitId] -> IO [String]
607 getPkgFrameworkOpts dflags platform dep_packages
608 | platformUsesFrameworks platform = do
609 pkg_framework_path_opts <- do
610 pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages
611 return $ map ("-F" ++) pkg_framework_paths
612
613 pkg_framework_opts <- do
614 pkg_frameworks <- getPackageFrameworks dflags dep_packages
615 return $ concat [ ["-framework", fw] | fw <- pkg_frameworks ]
616
617 return (pkg_framework_path_opts ++ pkg_framework_opts)
618
619 | otherwise = return []
620
621 getFrameworkOpts :: DynFlags -> Platform -> [String]
622 getFrameworkOpts dflags platform
623 | platformUsesFrameworks platform = framework_path_opts ++ framework_opts
624 | otherwise = []
625 where
626 framework_paths = frameworkPaths dflags
627 framework_path_opts = map ("-F" ++) framework_paths
628
629 frameworks = cmdlineFrameworks dflags
630 -- reverse because they're added in reverse order from the cmd line:
631 framework_opts = concat [ ["-framework", fw]
632 | fw <- reverse frameworks ]
633
634 {-
635 Note [-Bsymbolic assumptions by GHC]
636 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
637
638 GHC has a few assumptions about interaction of relocations in NCG and linker:
639
640 1. -Bsymbolic resolves internal references when the shared library is linked,
641 which is important for performance.
642 2. When there is a reference to data in a shared library from the main program,
643 the runtime linker relocates the data object into the main program using an
644 R_*_COPY relocation.
645 3. If we used -Bsymbolic, then this results in multiple copies of the data
646 object, because some references have already been resolved to point to the
647 original instance. This is bad!
648
649 We work around [3.] for native compiled code by avoiding the generation of
650 R_*_COPY relocations.
651
652 Unregisterised compiler can't evade R_*_COPY relocations easily thus we disable
653 -Bsymbolic linking there.
654
655 See related tickets: #4210, #15338
656 -}