Add includes to bindist (#632)
[hadrian.git] / src / Rules / BinaryDist.hs
1 module Rules.BinaryDist where
2
3 import Context
4 import Expression
5 import GHC
6 import Oracles.Setting
7 import Settings
8 import Target
9 import Utilities
10
11 bindistRules :: Rules ()
12 bindistRules = do
13 root <- buildRootRules
14 phony "binary-dist" $ do
15 -- We 'need' all binaries and libraries
16 targets <- mapM pkgTarget =<< stagePackages Stage1
17 need targets
18 version <- setting ProjectVersion
19 targetPlatform <- setting TargetPlatformFull
20 hostOs <- setting BuildOs
21 hostArch <- setting BuildArch
22 rtsDir <- pkgId $ vanillaContext Stage1 rts
23
24 let ghcBuildDir = root -/- stageString Stage1
25 bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty
26 ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
27 distDir = hostArch ++ "-" ++ hostOs ++ "-ghc-" ++ version
28 rtsIncludeDir = ghcBuildDir -/- "lib" -/- distDir -/- rtsDir
29 -/- "include"
30
31 -- we create the bindist directory at <root>/bindist/ghc-X.Y.Z-platform/
32 -- and populate it with a stage2 build
33 createDirectory bindistFilesDir
34 copyDirectory (ghcBuildDir -/- "bin") bindistFilesDir
35 copyDirectory (ghcBuildDir -/- "lib") bindistFilesDir
36 copyDirectory (rtsIncludeDir) bindistFilesDir
37 {- SHOULD WE SHIP DOCS?
38 need ["docs"]
39 copyDirectory (root -/- "docs") bindistFilesDir
40 -}
41
42 -- we then 'need' all the files necessary to configure and install
43 -- (as in, './configure [...] && make install') this build on some
44 -- other machine.
45 need $ map (bindistFilesDir -/-)
46 (["configure", "Makefile"] ++ bindistInstallFiles)
47 need $ map ((bindistFilesDir -/- "wrappers") -/-) ["check-api-annotations"
48 , "check-ppr", "ghc", "ghc-iserv", "ghc-pkg", "ghc-split"
49 , "ghci-script", "ghci", "haddock", "hpc", "hp2ps", "hsc2hs"
50 , "runhaskell"]
51
52 -- finally, we create the archive, at
53 -- <root>/bindist/ghc-X.Y.Z-platform.tar.xz
54 command [Cwd $ root -/- "bindist"] "tar"
55 [ "-c", "--xz", "-f"
56 , ghcVersionPretty <.> "tar.xz"
57 , ghcVersionPretty
58 ]
59
60 -- prepare binary distribution configure script
61 -- (generated under <ghc root>/distrib/configure by 'autoreconf')
62 root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do
63 ghcRoot <- topDirectory
64 copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4")
65 buildWithCmdOptions [] $
66 target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] []
67 -- we clean after ourselves, moving the configure script we generated in
68 -- our bindist dir
69 removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4")
70 moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
71
72 -- generate the Makefile that enables the "make install" part
73 root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath ->
74 writeFile' makefilePath bindistMakefile
75
76 root -/- "bindist" -/- "ghc-*" -/- "wrappers/*" %> \wrapperPath ->
77 writeFile' wrapperPath $ wrapper (takeFileName wrapperPath)
78
79 -- copy over the various configure-related files needed for a working
80 -- './configure [...] && make install' workflow
81 -- (see the list of files needed in the 'binary-dist' rule above, before
82 -- creating the archive).
83 forM_ bindistInstallFiles $ \file ->
84 root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do
85 ghcRoot <- topDirectory
86 copyFile (ghcRoot -/- fixup file) dest
87
88 where fixup f
89 | f `elem` ["INSTALL", "README"] = "distrib" -/- f
90 | otherwise = f
91
92 -- | A list of files that allow us to support a simple
93 -- @./configure [--prefix=PATH] && make install@ workflow.
94 --
95 -- NOTE: the list surely is incomplete
96 bindistInstallFiles :: [FilePath]
97 bindistInstallFiles =
98 [ "config.sub", "config.guess", "install-sh"
99 , "mk" -/- "config.mk.in", "mk" -/- "install.mk.in"
100 , "mk" -/- "project.mk", "settings.in", "README", "INSTALL"
101 ]
102
103 -- | Auxiliary function that gives us a 'Filepath' we can 'need' for
104 -- all libraries and programs that are needed for a complete build.
105 --
106 -- For libraries, it returns the path to the .conf file in the package db.
107 -- For executables, it returns the path to the compiled executable.
108 pkgTarget :: Package -> Action FilePath
109 pkgTarget pkg
110 | isLibrary pkg = pkgConfFile (Context Stage1 pkg $ read "v")
111 | otherwise = programPath =<< programContext Stage1 pkg
112
113 -- TODO: augment this makefile to match the various parameters that
114 -- the current bindist scripts support.
115 -- | A trivial makefile that only takes @$prefix@ into account,
116 -- and not e.g @$datadir@ (for docs) and other variables, yet.
117 bindistMakefile :: String
118 bindistMakefile = unlines
119 [ "MAKEFLAGS += --no-builtin-rules"
120 , ".SUFFIXES:"
121 , ""
122 , "include mk/install.mk"
123 , "include mk/config.mk"
124 , ""
125 , ".PHONY: default"
126 , "default:"
127 , "\t@echo 'Run \"make install\" to install'"
128 , "\t@false"
129 , ""
130 , "#------------------------------------------------------------------------------"
131 , "# INSTALL RULES"
132 , ""
133 , "# Hacky function to check equality of two strings"
134 , "# TODO : find if a better function exists"
135 , "eq=$(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))"
136 , ""
137 , "define installscript"
138 , "# $1 = package name"
139 , "# $2 = wrapper path"
140 , "# $3 = bindir"
141 , "# $4 = ghcbindir"
142 , "# $5 = Executable binary path"
143 , "# $6 = Library Directory"
144 , "# $7 = Docs Directory"
145 , "# $8 = Includes Directory"
146 , "# We are installing wrappers to programs by searching corresponding wrappers."
147 , "# If wrapper is not found, we are attaching the common wrapper to it "
148 , "# This implementation is a bit hacky and depends on consistency of program"
149 , "# names. For hadrian build this will work as programs have a consistent "
150 , "# naming procefure. This file is tested on Linux(Ubuntu)"
151 , "# TODO : Check implementation in other distributions"
152 , "\trm -f $2"
153 , "\t$(CREATE_SCRIPT) $2"
154 , "\t@echo \"#!$(SHELL)\" >> $2"
155 , "\t@echo \"exedir=\\\"$4\\\"\" >> $2"
156 , "\t@echo \"exeprog=\\\"$1\\\"\" >> $2"
157 , "\t@echo \"executablename=\\\"$5\\\"\" >> $2"
158 , "\t@echo \"bindir=\\\"$3\\\"\" >> $2"
159 , "\t@echo \"libdir=\\\"$6\\\"\" >> $2"
160 , "\t@echo \"docdir=\\\"$7\\\"\" >> $2"
161 , "\t@echo \"includedir=\\\"$8\\\"\" >> $2"
162 , "\t@echo \"\" >> $2 "
163 , "\tcat wrappers/$1 >> $2"
164 , "\t$(EXECUTABLE_FILE) $2 ;"
165 , "endef"
166 , ""
167 , "# QUESTION : should we use shell commands?"
168 , ""
169 , "# Due to the fact that package database is configured relatively"
170 , "# We do not change the relative paths of executables and libraries"
171 , "# But instead use wrapper scripts whenever necessary"
172 , "LIBPARENT = $(shell dirname $(libdir))"
173 , "GHCBINDIR = \"$(LIBPARENT)/bin\""
174 , ""
175 , ".PHONY: install"
176 , "install: install_bin install_lib install_includes"
177 , ""
178 , "# Check if we need to install docs"
179 , "ifeq \"DOCS\" \"YES\""
180 , "install: install_docs"
181 , "endif"
182 , ""
183 , "# If the relative path of binaries and libraries are altered, we will need to"
184 , "# install additional wrapper scripts at bindir."
185 , "ifneq \"$(LIBPARENT)/bin\" \"$(bindir)\""
186 , "install: install_wrappers"
187 , "endif"
188 , ""
189 , "# We need to install binaries relative to libraries."
190 , "BINARIES = $(wildcard ./bin/*)"
191 , "install_bin:"
192 , "\t@echo \"Copying Binaries to $(GHCBINDIR)\""
193 , "\t$(INSTALL_DIR) \"$(GHCBINDIR)\""
194 , "\tfor i in $(BINARIES); do \\"
195 , "\t\tcp -R $$i \"$(GHCBINDIR)\"; \\"
196 , "\tdone"
197 , "\t@echo \"Copying and installing ghci\""
198 , "\trm -f $(GHCBINDIR)/dir"
199 , "\t$(CREATE_SCRIPT) $(GHCBINDIR)/ghci"
200 , "\t@echo \"#!$(SHELL)\" >> $(GHCBINDIR)/ghci"
201 , "\tcat wrappers/ghci-script >> $(GHCBINDIR)/ghci"
202 , "\t$(EXECUTABLE_FILE) $(GHCBINDIR)/ghci"
203 , ""
204 , "LIBRARIES = $(wildcard ./lib/*)"
205 , "install_lib:"
206 , "\t@echo \"Copying libraries to $(libdir)\""
207 , "\t$(INSTALL_DIR) \"$(libdir)\""
208 , "\tfor i in $(LIBRARIES); do \\"
209 , "\t\tcp -R $$i \"$(libdir)/\"; \\"
210 , "\tdone"
211 , ""
212 , "INCLUDES = $(wildcard ./include/*)"
213 , "install_includes:"
214 , "\t@echo \"Copying libraries to $(includedir)\""
215 , "\t$(INSTALL_DIR) \"$(includedir)\""
216 , "\tfor i in $(INCLUDES); do \\"
217 , "\t\tcp -R $$i \"$(includedir)/\"; \\"
218 , "\tdone"
219 , ""
220 , "DOCS = $(wildcard ./docs/*)"
221 , "install_docs:"
222 , "\t@echo \"Copying libraries to $(docdir)\""
223 , "\t$(INSTALL_DIR) \"$(docdir)\""
224 , "\tfor i in $(DOCS); do \\"
225 , "\t\tcp -R $$i \"$(docdir)/\"; \\"
226 , "\tdone"
227 , ""
228 , "BINARY_NAMES=$(shell ls ./bin/)"
229 , "install_wrappers:"
230 , "\t@echo \"Installing Wrapper scripts\""
231 , "\t$(INSTALL_DIR) \"$(bindir)\""
232 , "\t$(foreach p, $(BINARY_NAMES),\\"
233 , "\t\t$(call installscript,$p,$(bindir)/$p,$(bindir),$(GHCBINDIR),$(GHCBINDIR)/$p,$(libdir),$(docdir),$(includedir)))"
234 , ""
235 , "# END INSTALL"
236 , "# -----------------------------------------------------------------------------"
237 ]
238
239 wrapper :: FilePath -> String
240 wrapper "ghc" = ghcWrapper
241 wrapper "ghc-pkg" = ghcPkgWrapper
242 wrapper "ghci" = ghciWrapper
243 wrapper "ghci-script" = ghciScriptWrapper
244 wrapper "haddock" = haddockWrapper
245 wrapper "hsc2hs" = hsc2hsWrapper
246 wrapper "runhaskell" = runhaskellWrapper
247 wrapper _ = commonWrapper
248
249 -- | Wrapper scripts for different programs. Common is default wrapper.
250
251 ghcWrapper :: String
252 ghcWrapper = unlines
253 [ "exec \"$executablename\" -B\"$libdir\" ${1+\"$@\"}"
254 ]
255
256 ghcPkgWrapper :: String
257 ghcPkgWrapper = unlines
258 [ "PKGCONF=\"$libdir/package.conf.d\""
259 , "exec \"$executablename\" --global-package-db \"$PKGCONF\" ${1+\"$@\"}"
260 ]
261
262 ghciWrapper :: String
263 ghciWrapper = unlines
264 ["exec \"$executablename\" --interactive \"$@\""
265 ]
266
267 haddockWrapper :: String
268 haddockWrapper = unlines
269 ["exec \"$executablename\" -B\"$libdir\" -l\"$libdir\" ${1+\"$@\"}"
270 ]
271
272 commonWrapper :: String
273 commonWrapper = unlines
274 ["exec \"$executablename\" ${1+\"$@\"}"
275 ]
276
277 hsc2hsWrapper :: String
278 hsc2hsWrapper = unlines
279 [ "HSC2HS_EXTRA=\"--cflag=-fno-stack-protector --lflag=-fuse-ld=gold\""
280 , "tflag=\"--template=$libdir/template-hsc.h\""
281 , "Iflag=\"-I$includedir/\""
282 , "for arg do"
283 , " case \"$arg\" in"
284 , "# On OS X, we need to specify -m32 or -m64 in order to get gcc to"
285 , "# build binaries for the right target. We do that by putting it in"
286 , "# HSC2HS_EXTRA. When cabal runs hsc2hs, it passes a flag saying which"
287 , "# gcc to use, so if we set HSC2HS_EXTRA= then we don't get binaries"
288 , "# for the right platform. So for now we just don't set HSC2HS_EXTRA="
289 , "# but we probably want to revisit how this works in the future."
290 , "# -c*) HSC2HS_EXTRA=;;"
291 , "# --cc=*) HSC2HS_EXTRA=;;"
292 , " -t*) tflag=;;"
293 , " --template=*) tflag=;;"
294 , " --) break;;"
295 , " esac"
296 , "done"
297 , "exec \"$executablename\" ${tflag:+\"$tflag\"} $HSC2HS_EXTRA ${1+\"$@\"} \"$Iflag\""
298 ]
299
300 runhaskellWrapper :: String
301 runhaskellWrapper = unlines
302 ["exec \"$executablename\" -f \"$exedir/ghc\" ${1+\"$@\"}"
303 ]
304
305 -- | We need to ship ghci executable, which basically just calls ghc with
306 -- | --interactive flag.
307 ghciScriptWrapper :: String
308 ghciScriptWrapper = unlines
309 [ "DIR=`dirname \"$0\"`"
310 , "executable=\"$DIR/ghc\""
311 , "exec $executable --interactive \"$@\""
312 ]
313