1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
module Rules.Libffi (libffiRules, libffiDependencies) where
import Hadrian.Utilities
import Packages
import Settings.Builders.Common
import Target
import Utilities
libffiDependencies :: [FilePath]
libffiDependencies = ["ffi.h", "ffitarget.h"]
libffiLibrary :: FilePath
libffiLibrary = "inst/lib/libffi.a"
rtsLibffiLibrary :: Stage -> Way -> Action FilePath
rtsLibffiLibrary stage way = do
name <- libffiLibraryName
suf <- libsuf way
rtsPath <- rtsBuildPath stage
return $ rtsPath -/- "lib" ++ name ++ suf
fixLibffiMakefile :: FilePath -> String -> String
fixLibffiMakefile top =
replace "-MD" "-MMD"
. replace "@toolexeclibdir@" "$(libdir)"
. replace "@INSTALL@" ("$(subst ../install-sh," ++ top ++ "/install-sh,@INSTALL@)")
-- TODO: check code duplication w.r.t. ConfCcArgs
configureEnvironment :: Stage -> Action [CmdOption]
configureEnvironment stage = do
cFlags <- interpretInContext (libffiContext stage) $ mconcat
[ cArgs
, getStagedSettingList ConfCcArgs ]
ldFlags <- interpretInContext (libffiContext stage) ldArgs
sequence [ builderEnvironment "CC" $ Cc CompileC stage
, builderEnvironment "CXX" $ Cc CompileC stage
, builderEnvironment "LD" (Ld stage)
, builderEnvironment "AR" (Ar Unpack stage)
, builderEnvironment "NM" Nm
, builderEnvironment "RANLIB" Ranlib
, return . AddEnv "CFLAGS" $ unwords cFlags ++ " -w"
, return . AddEnv "LDFLAGS" $ unwords ldFlags ++ " -w" ]
libffiRules :: Rules ()
libffiRules =
forM_ [Stage1 ..] $ \stage -> do
root <- buildRootRules
fmap ((root -/- stageString stage -/- "rts/build") -/-) libffiDependencies
&%> \_ -> do
libffiPath <- libffiBuildPath stage
need [libffiPath -/- libffiLibrary]
-- we set a higher priority because this overlaps
-- with the static lib rule from Rules.Library.libraryRules.
priority 2.0 $ root -/- stageString stage <//> libffiLibrary %> \_ -> do
useSystemFfi <- flag UseSystemFfi
rtsPath <- rtsBuildPath stage
if useSystemFfi
then do
ffiIncludeDir <- setting FfiIncludeDir
putBuild "| System supplied FFI library will be used"
forM_ ["ffi.h", "ffitarget.h"] $ \file ->
copyFile (ffiIncludeDir -/- file) (rtsPath -/- file)
putSuccess "| Successfully copied system FFI library header files"
else do
libffiPath <- libffiBuildPath stage
build $ target (libffiContext stage) (Make libffiPath) [] []
hs <- getDirectoryFiles "" [libffiPath -/- "inst/include/*"]
forM_ hs $ \header ->
copyFile header (rtsPath -/- takeFileName header)
ways <- interpretInContext (libffiContext stage)
(getLibraryWays <> getRtsWays)
forM_ (nubOrd ways) $ \way -> do
rtsLib <- rtsLibffiLibrary stage way
copyFileUntracked (libffiPath -/- libffiLibrary) rtsLib
putSuccess "| Successfully built custom library 'libffi'"
root -/- stageString stage -/- "libffi/build/Makefile.in" %> \mkIn -> do
libffiPath <- libffiBuildPath stage
removeDirectory libffiPath
tarball <- unifyPath . fromSingleton "Exactly one LibFFI tarball is expected"
<$> getDirectoryFiles "" ["libffi-tarballs/libffi*.tar.gz"]
need [tarball]
-- Go from 'libffi-3.99999+git20171002+77e130c.tar.gz' to 'libffi-3.99999'
let libname = takeWhile (/= '+') $ takeFileName tarball
root <- buildRoot
removeDirectory (root -/- libname)
-- TODO: Simplify.
actionFinally (do
build $ target (libffiContext stage) (Tar Extract)
[tarball]
[root -/- stageString stage]
moveDirectory (root -/- stageString stage -/- libname) libffiPath) $
removeFiles (root -/- stageString stage) [libname <//> "*"]
top <- topDirectory
fixFile mkIn (fixLibffiMakefile top)
-- TODO: Get rid of hard-coded @libffi@.
root -/- stageString stage -/- "libffi/build/Makefile" %> \mk -> do
need [mk <.> "in"]
libffiPath <- libffiBuildPath stage
forM_ ["config.guess", "config.sub"] $ \file -> do
copyFile file (libffiPath -/- file)
env <- configureEnvironment stage
buildWithCmdOptions env $
target (libffiContext stage) (Configure libffiPath) [mk <.> "in"] [mk]
|