diff options
author | Alp Mestanogullari <alp@well-typed.com> | 2018-11-27 13:17:53 +0100 |
---|---|---|
committer | Alp Mestanogullari <alpmestan@gmail.com> | 2018-11-27 13:18:44 +0100 |
commit | 8f52ab9223544b756010a7a92ea52fffdf1d1c71 (patch) | |
tree | 6ac142ece5cd3d448ee1606ce8444b4b99761b25 /hadrian/src/Rules | |
parent | 984b75de7082689ebcc6e9d17b37f2c9b3702f71 (diff) | |
download | haskell-8f52ab9223544b756010a7a92ea52fffdf1d1c71.tar.gz |
Hadrian: improve bindist rule
As outlined in #15925, hadrian bindists had not made a clear choice with
respect to relocatable GHCs and wrapper scripts. This commit implements
the policy described in the ticket. That is:
- the bindists ship {bin, lib} as they are, modulo the addition of
haddock from stage2/bin
- we now _always_ generate wrapper scripts for all the programs that
are in the bindist's bin/ directory
The idea being that anyone on Linux/Windows/OS X can just unpack
the binary distribution anywhere and start using bin/ghc, while the
installation process systematicaly generates wrapper scripts.
Test Plan: hadrian/build.sh binary-dist ; cd
_build/bindist/ghc-X.Y.Z-arch/; configure --prefix=/tmp/foo && make
install
Reviewers: snowleopard, bgamari, angerman
Reviewed By: snowleopard, bgamari, angerman
Subscribers: rwbarton, carter
GHC Trac Issues: #15925
Differential Revision: https://phabricator.haskell.org/D5371
Diffstat (limited to 'hadrian/src/Rules')
-rw-r--r-- | hadrian/src/Rules/BinaryDist.hs | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs index 667fbf1454..9cf442c3f5 100644 --- a/hadrian/src/Rules/BinaryDist.hs +++ b/hadrian/src/Rules/BinaryDist.hs @@ -10,6 +10,84 @@ import Settings import Target import Utilities +{- +Note [Binary distributions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Hadrian produces binary distributions under: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz + +It is generated by creating an archive from: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/ + +It does so by following the steps below. + +- make sure we have a complete stage 2 compiler + haddock + +- copy the bin and lib directories of the compiler we built: + <build root>/stage1/{bin, lib} + to + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/{bin, lib} + +- copy the generated docs (user guide, haddocks, etc): + <build root>/docs/ + to + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/docs/ + +- copy haddock (built by our stage2 compiler): + <build root>/stage2/bin/haddock + to + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/haddock + +- use autoreconf to generate a `configure` script from + aclocal.m4 and distrib/configure.ac, that we move to: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/configure + +- write a (fixed) Makefile capable of supporting 'make install' to: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/Makefile + +- write some (fixed) supporting bash code for the wrapper scripts to: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/wrappers/<program> + + where <program> is the name of the executable that the bash file will + help wrapping. + +- copy supporting configure/make related files + (see @bindistInstallFiles@) to: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/<file> + +- create a .tar.xz archive of the directory: + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/ + at + <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz + + +Note [Wrapper scripts and binary distributions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Users of Linux, FreeBSD, Windows and OS X can unpack a +binary distribution produced by hadrian for their arch +and OS and start using @bin/ghc@, @bin/ghc-pkg@ and so on +right away, without even having to configure or install +the distribution. They would then be using the real executables +directly, not through wrapper scripts. + +This works because GHCs produced by hadrian on those systems +are relocatable. This means that you can copy the @bin@ and @lib@ +dirs anywhere and GHC will keep working, as long as both +directories sit next to each other. (This is achieved by having +GHC look up its $libdir relatively to where the GHC executable +resides.) + +It is however still possible (and simple) to install a GHC +distribution that uses wrapper scripts. From the unpacked archive, +you can simply do: + + ./configure --prefix=<path> [... other configure options ...] + make install + +-} + bindistRules :: Rules () bindistRules = do root <- buildRootRules @@ -17,6 +95,7 @@ bindistRules = do -- We 'need' all binaries and libraries targets <- mapM pkgTarget =<< stagePackages Stage1 need targets + version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull cabalHostOs <- cabalOsString <$> setting BuildOs @@ -36,9 +115,13 @@ bindistRules = do copyDirectory (ghcBuildDir -/- "bin") bindistFilesDir copyDirectory (ghcBuildDir -/- "lib") bindistFilesDir copyDirectory (rtsIncludeDir) bindistFilesDir - {- TODO: Should we ship docs? need ["docs"] - copyDirectory (root -/- "docs") bindistFilesDir -} + copyDirectory (root -/- "docs") bindistFilesDir + + -- We copy the binary (<build root>/stage2/bin/haddock) to + -- the bindist's bindir (<build root>/bindist/ghc-.../bin/). + haddockPath <- programPath (vanillaContext Stage2 haddock) + copyFile haddockPath (bindistFilesDir -/- "bin" -/- "haddock") -- We then 'need' all the files necessary to configure and install -- (as in, './configure [...] && make install') this build on some @@ -88,9 +171,8 @@ bindistRules = do fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f | otherwise = f --- TODO: This list is surely incomplete -- fix this. -- | A list of files that allow us to support a simple --- @./configure [--prefix=PATH] && make install@ workflow. +-- @./configure [...] && make install@ workflow. bindistInstallFiles :: [FilePath] bindistInstallFiles = [ "config.sub", "config.guess", "install-sh", "mk" -/- "config.mk.in" @@ -123,7 +205,7 @@ bindistMakefile = unlines , "\t@echo 'Run \"make install\" to install'" , "\t@false" , "" - , "#------------------------------------------------------------------------------" + , "#-----------------------------------------------------------------------" , "# INSTALL RULES" , "" , "# Hacky function to check equality of two strings" @@ -139,12 +221,11 @@ bindistMakefile = unlines , "# $6 = Library Directory" , "# $7 = Docs Directory" , "# $8 = Includes Directory" - , "# We are installing wrappers to programs by searching corresponding wrappers." - , "# If wrapper is not found, we are attaching the common wrapper to it " - , "# This implementation is a bit hacky and depends on consistency of program" - , "# names. For hadrian build this will work as programs have a consistent " - , "# naming procefure. This file is tested on Linux(Ubuntu)" - , "# TODO : Check implementation in other distributions" + , "# We are installing wrappers to programs by searching corresponding" + , "# wrappers. If wrapper is not found, we are attaching the common wrapper" + , "# to it. This implementation is a bit hacky and depends on consistency" + , "# of program names. For hadrian build this will work as programs have a" + , "# consistent naming procedure." , "\trm -f $2" , "\t$(CREATE_SCRIPT) $2" , "\t@echo \"#!$(SHELL)\" >> $2" @@ -162,40 +243,29 @@ bindistMakefile = unlines , "" , "# QUESTION : should we use shell commands?" , "" - , "# Due to the fact that package database is configured relatively" - , "# We do not change the relative paths of executables and libraries" - , "# But instead use wrapper scripts whenever necessary" - , "LIBPARENT = $(shell dirname $(libdir))" - , "GHCBINDIR = \"$(LIBPARENT)/bin\"" , "" , ".PHONY: install" - , "install: install_bin install_lib install_includes" - , "" - , "# Check if we need to install docs" - , "ifeq \"DOCS\" \"YES\"" - , "install: install_docs" - , "endif" + , "install: install_lib install_bin install_includes" + , "install: install_docs install_wrappers install_ghci" , "" - , "# If the relative path of binaries and libraries are altered, we will need to" - , "# install additional wrapper scripts at bindir." - , "ifneq \"$(LIBPARENT)/bin\" \"$(bindir)\"" - , "install: install_wrappers" - , "endif" + , "ActualBinsDir=${ghclibdir}/bin" + , "WrapperBinsDir=${bindir}" , "" , "# We need to install binaries relative to libraries." , "BINARIES = $(wildcard ./bin/*)" , "install_bin:" - , "\t@echo \"Copying Binaries to $(GHCBINDIR)\"" - , "\t$(INSTALL_DIR) \"$(GHCBINDIR)\"" + , "\t@echo \"Copying binaries to $(ActualBinsDir)\"" + , "\t$(INSTALL_DIR) \"$(ActualBinsDir)\"" , "\tfor i in $(BINARIES); do \\" - , "\t\tcp -R $$i \"$(GHCBINDIR)\"; \\" + , "\t\tcp -R $$i \"$(ActualBinsDir)\"; \\" , "\tdone" + , "" + , "install_ghci:" , "\t@echo \"Copying and installing ghci\"" - , "\trm -f $(GHCBINDIR)/dir" - , "\t$(CREATE_SCRIPT) $(GHCBINDIR)/ghci" - , "\t@echo \"#!$(SHELL)\" >> $(GHCBINDIR)/ghci" - , "\tcat wrappers/ghci-script >> $(GHCBINDIR)/ghci" - , "\t$(EXECUTABLE_FILE) $(GHCBINDIR)/ghci" + , "\t$(CREATE_SCRIPT) $(WrapperBinsDir)/ghci" + , "\t@echo \"#!$(SHELL)\" >> $(WrapperBinsDir)/ghci" + , "\tcat wrappers/ghci-script >> $(WrapperBinsDir)/ghci" + , "\t$(EXECUTABLE_FILE) $(WrapperBinsDir)/ghci" , "" , "LIBRARIES = $(wildcard ./lib/*)" , "install_lib:" @@ -224,12 +294,15 @@ bindistMakefile = unlines , "BINARY_NAMES=$(shell ls ./bin/)" , "install_wrappers:" , "\t@echo \"Installing Wrapper scripts\"" - , "\t$(INSTALL_DIR) \"$(bindir)\"" + , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\"" , "\t$(foreach p, $(BINARY_NAMES),\\" - , "\t\t$(call installscript,$p,$(bindir)/$p,$(bindir),$(GHCBINDIR),$(GHCBINDIR)/$p,$(libdir),$(docdir),$(includedir)))" + , "\t\t$(call installscript,$p,$(WrapperBinsDir)/$p," ++ + "$(WrapperBinsDir),$(ActualBinsDir),$(ActualBinsDir)/$p," ++ + "$(libdir),$(docdir),$(includedir)))" , "" , "# END INSTALL" - , "# -----------------------------------------------------------------------------" ] + , "# ----------------------------------------------------------------------" + ] wrapper :: FilePath -> String wrapper "ghc" = ghcWrapper |