4 # A script to bootstrap cabal-install.
6 # It works by downloading and installing the Cabal, zlib and
7 # HTTP packages. It then installs cabal-install itself.
8 # It expects to be run inside the cabal-install directory.
10 # Install settings, you can override these by setting environment vars. E.g. if
11 # you don't want profiling and dynamic versions of libraries to be installed in
12 # addition to vanilla, run 'EXTRA_CONFIGURE_OPTS="" ./bootstrap.sh'
15 DEFAULT_CONFIGURE_OPTS
="--enable-library-profiling --enable-shared"
16 EXTRA_CONFIGURE_OPTS
=${EXTRA_CONFIGURE_OPTS-$DEFAULT_CONFIGURE_OPTS}
21 printf "\nError during cabal-install bootstrap:\n%s\n" "$1" >&2
25 # programs, you can override these by setting environment vars
27 GHC_PKG
="${GHC_PKG:-ghc-pkg}"
28 GHC_VER
="$(${GHC} --numeric-version)"
29 HADDOCK
=${HADDOCK:-haddock}
32 FETCH
="${FETCH:-fetch}"
34 GZIP_PROGRAM
="${GZIP_PROGRAM:-gzip}"
36 # The variable SCOPE_OF_INSTALLATION can be set on the command line to
37 # use/install the libaries needed to build cabal-install to a custom package
38 # database instead of the user or global package database.
42 # $ ghc-pkg init /my/package/database
43 # $ SCOPE_OF_INSTALLATION='--package-db=/my/package/database' ./bootstrap.sh
45 # You can also combine SCOPE_OF_INSTALLATION with PREFIX:
47 # $ ghc-pkg init /my/prefix/packages.conf.d
48 # $ SCOPE_OF_INSTALLATION='--package-db=/my/prefix/packages.conf.d' \
49 # PREFIX=/my/prefix ./bootstrap.sh
51 # If you use the --global,--user or --sandbox arguments, this will
52 # override the SCOPE_OF_INSTALLATION setting and not use the package
53 # database you pass in the SCOPE_OF_INSTALLATION variable.
55 SCOPE_OF_INSTALLATION
="${SCOPE_OF_INSTALLATION:---user}"
56 DEFAULT_PREFIX
="${HOME}/.cabal"
58 TMPDIR
=$
(mktemp
-d -p /tmp
-t cabal-XXXXXXX || mktemp
-d -t cabal-XXXXXXX
)
61 # Check for a C compiler, using user-set $CC, if any, first.
62 for c
in $CC gcc clang cc icc
; do
63 $c --version 1>/dev
/null
2>&1 && CC
=$c &&
64 echo "Using $c for C compiler. If this is not what you want, set CC." >&2 &&
69 [ -"$CC"- = -""- ] && die
'C compiler not found (or could not be run).
70 If a C compiler is installed make sure it is on your PATH, or set $CC.'
72 # Find the correct linker/linker-wrapper.
74 # See https://github.com/haskell/cabal/pull/4187#issuecomment-269074153.
75 LINK
="$(for link in collect2 ld; do
76 if [ $($CC -print-prog-name=$link) = $link ]
80 $CC -print-prog-name=$link && break
84 # Fall back to "ld"... might work.
85 [ -$LINK- = -""- ] && LINK
=ld
87 # And finally, see if we can compile and link something.
88 echo 'int main(){}' |
$CC -xc - -o /dev
/null ||
89 die
"C compiler and linker could not compile a simple test program.
90 Please check your toolchain."
92 # Warn that were's overriding $LD if set (if you want).
93 [ -"$LD"- != -""- ] && [ -"$LD"- != -"$LINK"- ] &&
94 echo "Warning: value set in $LD is not the same as C compiler's $LINK." >&2
95 echo "Using $LINK instead." >&2
97 # Set LD, overriding environment if necessary.
100 # Check we're in the right directory, etc.
101 grep "cabal-install" .
/cabal-install.cabal
> /dev
/null
2>&1 ||
102 die
"The bootstrap.sh script must be run in the cabal-install directory"
104 ${GHC} --numeric-version > /dev
/null
2>&1 ||
105 die
"${GHC} not found (or could not be run).
106 If ghc is installed, make sure it is on your PATH,
107 or set the GHC and GHC_PKG vars."
109 ${GHC_PKG} --version > /dev
/null
2>&1 || die
"${GHC_PKG} not found."
111 GHC_PKG_VER
="$(${GHC_PKG} --version | cut -d' ' -f 5)"
113 [ ${GHC_VER} = ${GHC_PKG_VER} ] ||
114 die
"Version mismatch between ${GHC} and ${GHC_PKG}.
115 If you set the GHC variable then set GHC_PKG too."
118 while [ "$#" -gt 0 ]; do
121 SCOPE_OF_INSTALLATION
="${1}"
124 SCOPE_OF_INSTALLATION
="${1}"
125 DEFAULT_PREFIX
="/usr/local"
129 # check if there is another argument which doesn't start with --
130 if [ "$#" -le 0 ] ||
[ ! -z $
(echo "${1}" |
grep "^--") ]
132 SANDBOX
=".cabal-sandbox"
142 # check if there is another argument which doesn't start with - or --
144 ||
[ ! -z $
(echo "${1}" |
grep "^-") ] \
145 ||
[ ! -z $
(echo "${1}" |
grep "^--") ]
153 echo "Unknown argument or option, quitting: ${1}"
154 echo "usage: bootstrap.sh [OPTION]"
157 echo " -j/--jobs Number of concurrent workers to use (Default: 1)"
158 echo " -j without an argument will use all available cores"
159 echo " --user Install for the local user (default)"
160 echo " --global Install systemwide (must be run as root)"
161 echo " --no-doc Do not generate documentation for installed"\
163 echo " --sandbox Install to a sandbox in the default location"\
165 echo " --sandbox path Install to a sandbox located at path"
170 # Do not try to use -j with GHC 7.8 or older
179 abspath
() { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";;
182 if [ ! -z "$SANDBOX" ]
183 then # set up variables for sandbox bootstrap
184 # Make the sandbox path absolute since it will be used from
185 # different working directories when the dependency packages are
187 SANDBOX
=$
(abspath
"$SANDBOX")
188 # Get the name of the package database which cabal sandbox would use.
189 GHC_ARCH
=$
(ghc
--info |
190 sed -n 's/.*"Target platform".*"\([^-]\+\)-[^-]\+-\([^"]\+\)".*/\1-\2/p')
191 PACKAGEDB
="$SANDBOX/${GHC_ARCH}-ghc-${GHC_VER}-packages.conf.d"
192 # Assume that if the directory is already there, it is already a
193 # package database. We will get an error immediately below if it
194 # isn't. Uses -r to try to be compatible with Solaris, and allow
195 # symlinks as well as a normal dir/file.
196 [ ! -r "$PACKAGEDB" ] && ghc-pkg init
"$PACKAGEDB"
198 SCOPE_OF_INSTALLATION
="--package-db=$PACKAGEDB"
199 echo Bootstrapping
in sandbox
at \'$SANDBOX\'.
202 # Check for haddock unless no documentation should be generated.
203 if [ ! ${NO_DOCUMENTATION} ]
205 ${HADDOCK} --version > /dev
/null
2>&1 || die
"${HADDOCK} not found."
208 PREFIX
=${PREFIX:-${DEFAULT_PREFIX}}
210 # Versions of the packages to install.
211 # The version regex says what existing installed versions are ok.
212 PARSEC_VER
="3.1.13.0"; PARSEC_VER_REGEXP
="[3]\.[1]\."
214 DEEPSEQ_VER
="1.4.3.0"; DEEPSEQ_VER_REGEXP
="1\.[1-9]\."
216 BINARY_VER
="0.8.5.1"; BINARY_VER_REGEXP
="[0]\.[78]\."
218 TEXT_VER
="1.2.3.0"; TEXT_VER_REGEXP
="[1]\.[2]\."
220 NETWORK_URI_VER
="2.6.1.0"; NETWORK_URI_VER_REGEXP
="2\.6\.(0\.[2-9]|[1-9])"
221 # >= 2.6.0.2 && < 2.7
222 NETWORK_VER
="2.7.0.0"; NETWORK_VER_REGEXP
="2\.[0-7]\."
224 CABAL_VER
="2.5.0.0"; CABAL_VER_REGEXP
="2\.5\.[0-9]"
226 TRANS_VER
="0.5.5.0"; TRANS_VER_REGEXP
="0\.[45]\."
228 MTL_VER
="2.2.2"; MTL_VER_REGEXP
="[2]\."
230 HTTP_VER
="4000.3.12"; HTTP_VER_REGEXP
="4000\.(2\.([5-9]|1[0-9]|2[0-9])|3\.?)"
231 # >= 4000.2.5 < 4000.4
232 ZLIB_VER
="0.6.2"; ZLIB_VER_REGEXP
="(0\.5\.([3-9]|1[0-9])|0\.6)"
234 TIME_VER
="1.9.1" TIME_VER_REGEXP
="1\.[1-9]\.?"
236 RANDOM_VER
="1.1" RANDOM_VER_REGEXP
="1\.[01]\.?"
238 STM_VER
="2.4.5.0"; STM_VER_REGEXP
="2\."
240 HASHABLE_VER
="1.2.7.0"; HASHABLE_VER_REGEXP
="1\."
242 ASYNC_VER
="2.2.1"; ASYNC_VER_REGEXP
="2\."
244 BASE16_BYTESTRING_VER
="0.1.1.6"; BASE16_BYTESTRING_VER_REGEXP
="0\.1"
246 BASE64_BYTESTRING_VER
="1.0.0.1"; BASE64_BYTESTRING_VER_REGEXP
="1\."
248 CRYPTOHASH_SHA256_VER
="0.11.101.0"; CRYPTOHASH_SHA256_VER_REGEXP
="0\.11\.?"
250 RESOLV_VER
="0.1.1.1"; RESOLV_VER_REGEXP
="0\.1\.[1-9]"
252 MINTTY_VER
="0.1.2"; MINTTY_VER_REGEXP
="0\.1\.?"
254 ECHO_VER
="0.1.3"; ECHO_VER_REGEXP
="0\.1\.[3-9]"
256 EDIT_DISTANCE_VER
="0.2.2.1"; EDIT_DISTANCE_VER_REGEXP
="0\.2\.2\.?"
258 ED25519_VER
="0.0.5.0"; ED25519_VER_REGEXP
="0\.0\.?"
260 HACKAGE_SECURITY_VER
="0.5.3.0"; HACKAGE_SECURITY_VER_REGEXP
="0\.5\.((2\.[2-9]|[3-9])|3)"
262 TAR_VER
="0.5.1.0"; TAR_VER_REGEXP
="0\.5\.([1-9]|1[0-9]|0\.[3-9]|0\.1[0-9])\.?"
263 # >= 0.5.0.3 && < 0.6
264 DIGEST_VER
="0.0.1.2"; DIGEST_REGEXP
="0\.0\.(1\.[2-9]|[2-9]\.?)"
265 # >= 0.0.1.2 && < 0.1
266 ZIP_ARCHIVE_VER
="0.3.3"; ZIP_ARCHIVE_REGEXP
="0\.3\.[3-9]"
269 HACKAGE_URL
="https://hackage.haskell.org/package"
271 # Haddock fails for hackage-security for GHC <8,
272 # c.f. https://github.com/well-typed/hackage-security/issues/149
273 NO_DOCS_PACKAGES_VER_REGEXP
="hackage-security-0\.5\.[0-9]+\.[0-9]+"
275 # Cache the list of packages:
276 echo "Checking installed packages for ghc-${GHC_VER}..."
277 ${GHC_PKG} list
--global ${SCOPE_OF_INSTALLATION} > ghc-pkg.list ||
278 die
"running '${GHC_PKG} list' failed"
280 # Will we need to install this package, or is a suitable version installed?
284 if egrep " ${PKG}-${VER_MATCH}" ghc-pkg.list
> /dev
/null
2>&1
290 #Note: we cannot use "! grep" here as Solaris 9 /bin/sh doesn't like it.
298 if need_pkg
${PKG} ${VER_MATCH}
300 if [ -r "${PKG}-${VER}.tar.gz" ]
302 echo "${PKG}-${VER} will be installed from local tarball."
304 echo "${PKG}-${VER} will be downloaded and installed."
307 echo "${PKG} is already installed and the version is ok."
315 URL_PKG
=${HACKAGE_URL}/${PKG}-${VER}/${PKG}-${VER}.
tar.gz
316 URL_PKGDESC
=${HACKAGE_URL}/${PKG}-${VER}/${PKG}.cabal
317 if which ${CURL} > /dev
/null
319 ${CURL} -L --fail -C - -O ${URL_PKG} || die "Failed to download ${PKG}.
"
320 ${CURL} -L --fail -C - -O ${URL_PKGDESC} \
321 || die "Failed to download
'${PKG}.cabal'.
"
322 elif which ${WGET} > /dev/null
324 ${WGET} -c ${URL_PKG} || die "Failed to download ${PKG}."
325 ${WGET} -c ${URL_PKGDESC} || die "Failed to download '${PKG}.cabal
'."
326 elif which ${FETCH} > /dev/null
328 ${FETCH} ${URL_PKG} || die "Failed to download ${PKG}."
329 ${FETCH} ${URL_PKGDESC} || die "Failed to download '${PKG}.cabal'.
"
331 die "Failed to
find a downloader.
'curl', 'wget' or
'fetch' is required.
"
333 [ -f "${PKG}-${VER}.
tar.gz
" ] ||
334 die "Downloading
${URL_PKG} did not create ${PKG}-${VER}.
tar.gz
"
335 [ -f "${PKG}.cabal
" ] ||
336 die "Downloading
${URL_PKGDESC} did not create
${PKG}.cabal
"
337 mv "${PKG}.cabal
" "${PKG}.cabal.hackage
"
344 rm -rf "${PKG}-${VER}.tar" "${PKG}-${VER}"
345 ${GZIP_PROGRAM} -d < "${PKG}-${VER}.tar.gz" | ${TAR} -xf -
346 [ -d "${PKG}-${VER}" ] || die "Failed to unpack ${PKG}-${VER}.
tar.gz
"
347 cp "${PKG}.cabal.hackage" "${PKG}-${VER}/${PKG}.cabal
"
354 [ -x Setup ] && ./Setup clean
355 [ -f Setup ] && rm Setup
357 PKG_DBS=$(printf '%s\n' "${SCOPE_OF_INSTALLATION}" \
358 | sed -e 's/--package-db/-package-db/' \
359 -e 's/--global/-global-package-db/' \
360 -e 's/--user/-user-package-db/')
362 ${GHC} --make ${JOBS} ${PKG_DBS} Setup -o Setup -XRank2Types -XFlexibleContexts ||
363 die "Compiling the Setup
script failed.
"
365 [ -x Setup ] || die "The Setup
script does not exist or cannot be run
"
367 args="${SCOPE_OF_INSTALLATION} --prefix=${PREFIX} --with-compiler=${GHC}"
368 args="$args --with-hc-pkg=${GHC_PKG} --with-gcc=${CC} --with-ld=${LD}"
369 args="$args ${EXTRA_CONFIGURE_OPTS} ${VERBOSE}"
371 ./Setup configure $args || die "Configuring the
${PKG} package failed.
"
373 ./Setup build ${JOBS} ${EXTRA_BUILD_OPTS} ${VERBOSE} ||
374 die "Building the
${PKG} package failed.
"
376 if [ ! ${NO_DOCUMENTATION} ]
378 if echo "${PKG}-${VER}" | egrep ${NO_DOCS_PACKAGES_VER_REGEXP} \
381 echo "Skipping documentation for the ${PKG} package."
383 .
/Setup haddock
--with-ghc=${GHC} --with-haddock=${HADDOCK} ${VERBOSE} ||
384 die
"Documenting the ${PKG} package failed."
388 .
/Setup
install ${EXTRA_INSTALL_OPTS} ${VERBOSE} ||
389 die
"Installing the ${PKG} package failed."
397 if need_pkg
${PKG} ${VER_MATCH}
400 if [ -r "${PKG}-${VER}.tar.gz" ]
402 echo "Using local tarball for ${PKG}-${VER}."
404 echo "Downloading ${PKG}-${VER}..."
405 fetch_pkg
${PKG} ${VER}
407 unpack_pkg
"${PKG}" "${VER}"
408 (cd "${PKG}-${VER}" && install_pkg ${PKG} ${VER})
412 # If we're bootstrapping from a Git clone, install the local version of Cabal
413 # instead of downloading one from Hackage.
417 if need_pkg "Cabal
" ${CABAL_VER_REGEXP}
419 echo "Cabal-
${CABAL_VER} will be installed from the
local Git clone.
"
420 (cd ../Cabal && install_pkg ${CABAL_VER} ${CABAL_VER_REGEXP})
422 echo "Cabal is already installed and the version is ok.
"
425 info_pkg "Cabal
" ${CABAL_VER} ${CABAL_VER_REGEXP}
426 do_pkg "Cabal
" ${CABAL_VER} ${CABAL_VER_REGEXP}
430 # Actually do something!
432 info_pkg "deepseq
" ${DEEPSEQ_VER} ${DEEPSEQ_VER_REGEXP}
433 info_pkg "binary
" ${BINARY_VER} ${BINARY_VER_REGEXP}
434 info_pkg "time" ${TIME_VER} ${TIME_VER_REGEXP}
435 info_pkg "transformers
" ${TRANS_VER} ${TRANS_VER_REGEXP}
436 info_pkg "mtl
" ${MTL_VER} ${MTL_VER_REGEXP}
437 info_pkg "text
" ${TEXT_VER} ${TEXT_VER_REGEXP}
438 info_pkg "parsec
" ${PARSEC_VER} ${PARSEC_VER_REGEXP}
439 info_pkg "network-uri
" ${NETWORK_URI_VER} ${NETWORK_URI_VER_REGEXP}
440 info_pkg "network
" ${NETWORK_VER} ${NETWORK_VER_REGEXP}
441 info_pkg "HTTP
" ${HTTP_VER} ${HTTP_VER_REGEXP}
442 info_pkg "zlib
" ${ZLIB_VER} ${ZLIB_VER_REGEXP}
443 info_pkg "random
" ${RANDOM_VER} ${RANDOM_VER_REGEXP}
444 info_pkg "stm
" ${STM_VER} ${STM_VER_REGEXP}
445 info_pkg "hashable
" ${HASHABLE_VER} ${HASHABLE_VER_REGEXP}
446 info_pkg "async
" ${ASYNC_VER} ${ASYNC_VER_REGEXP}
447 info_pkg "base16-bytestring
" ${BASE16_BYTESTRING_VER} \
448 ${BASE16_BYTESTRING_VER_REGEXP}
449 info_pkg "base64-bytestring
" ${BASE64_BYTESTRING_VER} \
450 ${BASE64_BYTESTRING_VER_REGEXP}
451 info_pkg "cryptohash-sha256
" ${CRYPTOHASH_SHA256_VER} \
452 ${CRYPTOHASH_SHA256_VER_REGEXP}
453 info_pkg "resolv
" ${RESOLV_VER} ${RESOLV_VER_REGEXP}
454 info_pkg "mintty
" ${MINTTY_VER} ${MINTTY_VER_REGEXP}
455 info_pkg "echo" ${ECHO_VER} ${ECHO_VER_REGEXP}
456 info_pkg "edit-distance
" ${EDIT_DISTANCE_VER} ${EDIT_DISTANCE_VER_REGEXP}
457 info_pkg "ed25519
" ${ED25519_VER} ${ED25519_VER_REGEXP}
458 info_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP}
459 info_pkg "digest
" ${DIGEST_VER} ${DIGEST_REGEXP}
460 info_pkg "zip-archive
" ${ZIP_ARCHIVE_VER} ${ZIP_ARCHIVE_REGEXP}
461 info_pkg "hackage-security
" ${HACKAGE_SECURITY_VER} \
462 ${HACKAGE_SECURITY_VER_REGEXP}
464 do_pkg "deepseq
" ${DEEPSEQ_VER} ${DEEPSEQ_VER_REGEXP}
465 do_pkg "binary
" ${BINARY_VER} ${BINARY_VER_REGEXP}
466 do_pkg "time" ${TIME_VER} ${TIME_VER_REGEXP}
468 # Cabal might depend on these
469 do_pkg "transformers
" ${TRANS_VER} ${TRANS_VER_REGEXP}
470 do_pkg "mtl
" ${MTL_VER} ${MTL_VER_REGEXP}
471 do_pkg "text
" ${TEXT_VER} ${TEXT_VER_REGEXP}
472 do_pkg "parsec
" ${PARSEC_VER} ${PARSEC_VER_REGEXP}
474 # Install the Cabal library from the local Git clone if possible.
477 do_pkg "network-uri
" ${NETWORK_URI_VER} ${NETWORK_URI_VER_REGEXP}
478 do_pkg "network
" ${NETWORK_VER} ${NETWORK_VER_REGEXP}
479 do_pkg "HTTP
" ${HTTP_VER} ${HTTP_VER_REGEXP}
480 do_pkg "zlib
" ${ZLIB_VER} ${ZLIB_VER_REGEXP}
481 do_pkg "random
" ${RANDOM_VER} ${RANDOM_VER_REGEXP}
482 do_pkg "stm
" ${STM_VER} ${STM_VER_REGEXP}
483 do_pkg "hashable
" ${HASHABLE_VER} ${HASHABLE_VER_REGEXP}
484 do_pkg "async
" ${ASYNC_VER} ${ASYNC_VER_REGEXP}
485 do_pkg "base16-bytestring
" ${BASE16_BYTESTRING_VER} \
486 ${BASE16_BYTESTRING_VER_REGEXP}
487 do_pkg "base64-bytestring
" ${BASE64_BYTESTRING_VER} \
488 ${BASE64_BYTESTRING_VER_REGEXP}
489 do_pkg "cryptohash-sha256
" ${CRYPTOHASH_SHA256_VER} \
490 ${CRYPTOHASH_SHA256_VER_REGEXP}
491 do_pkg "resolv
" ${RESOLV_VER} ${RESOLV_VER_REGEXP}
492 do_pkg "mintty
" ${MINTTY_VER} ${MINTTY_VER_REGEXP}
493 do_pkg "echo" ${ECHO_VER} ${ECHO_VER_REGEXP}
494 do_pkg "edit-distance
" ${EDIT_DISTANCE_VER} ${EDIT_DISTANCE_VER_REGEXP}
495 do_pkg "ed25519
" ${ED25519_VER} ${ED25519_VER_REGEXP}
496 do_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP}
497 do_pkg "digest
" ${DIGEST_VER} ${DIGEST_REGEXP}
498 do_pkg "zip-archive
" ${ZIP_ARCHIVE_VER} ${ZIP_ARCHIVE_REGEXP}
499 do_pkg "hackage-security
" ${HACKAGE_SECURITY_VER} \
500 ${HACKAGE_SECURITY_VER_REGEXP}
503 install_pkg "cabal-install
"
505 # Use the newly built cabal to turn the prefix/package database into a
506 # legit cabal sandbox. This works because 'cabal sandbox init' will
507 # reuse the already existing package database and other files if they
508 # are in the expected locations.
509 [ ! -z "$SANDBOX" ] && $SANDBOX/bin/cabal sandbox init --sandbox $SANDBOX
512 echo "==========================================="
513 CABAL_BIN="$PREFIX/bin
"
514 if [ -x "$CABAL_BIN/cabal
" ]
516 echo "The
'cabal' program has been installed
in $CABAL_BIN/"
517 echo "You should either add
$CABAL_BIN to your PATH
"
518 echo "or copy the cabal program to a directory that is on your PATH.
"
520 echo "The first thing to
do is to get the latest list of packages with
:"
522 echo "This will also create a default config
file (if it does not already
"
523 echo "exist
) at $HOME/.cabal
/config
"
525 echo "By default cabal will
install programs to
$HOME/.cabal
/bin
"
526 echo "If you
do not want to add this directory to your PATH
then you can
"
527 echo "change the setting
in the config
file, for example you could use
:"
528 echo "symlink-bindir
: $HOME/bin
"
530 echo "Sorry
, something went wrong.
"
531 echo "The
'cabal' executable was not successfully installed into
"