Commit 8f52ab92 authored by Alp Mestanogullari's avatar Alp Mestanogullari 🦑 Committed by Alp Mestanogullari

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
parent 984b75de
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment