102 lines
3.5 KiB
Ruby
Raw Normal View History

module Language
module Haskell
module Cabal
def self.included(base)
# use llvm-gcc on Lion or below, as when building GHC)
base.fails_with(:clang) if MacOS.version <= :lion
end
def cabal_sandbox(options = {})
pwd = Pathname.pwd
home = options[:home] || pwd
# pretend HOME is elsewhere, so that ~/.cabal is kept as untouched
# as possible (except for ~/.cabal/setup-exe-cache)
# https://github.com/haskell/cabal/issues/1234
saved_home = ENV["HOME"]
ENV["HOME"] = home
system "cabal", "sandbox", "init"
2015-12-30 21:09:36 +00:00
cabal_sandbox_bin = pwd/".cabal-sandbox/bin"
mkdir_p cabal_sandbox_bin
# make available any tools that will be installed in the sandbox
saved_path = ENV["PATH"]
ENV.prepend_path "PATH", cabal_sandbox_bin
# avoid updating the cabal package database more than once
2015-12-30 21:09:36 +00:00
system "cabal", "update" unless (home/".cabal/packages").exist?
yield
# remove the sandbox and all build products
rm_rf [".cabal-sandbox", "cabal.sandbox.config", "dist"]
# avoid installing any Haskell libraries, as a matter of policy
rm_rf lib unless options[:keep_lib]
# restore the environment
ENV["HOME"] = saved_home
ENV["PATH"] = saved_path
end
def cabal_sandbox_add_source(*args)
system "cabal", "sandbox", "add-source", *args
end
def cabal_install(*args)
# cabal hardcodes 64 as the maximum number of parallel jobs
# https://github.com/Homebrew/legacy-homebrew/issues/49509
make_jobs = ENV.make_jobs > 64 ? 64 : ENV.make_jobs
# cabal-install's dependency-resolution backtracking strategy can easily
# need more than the default 2,000 maximum number of "backjumps," since
# Hackage is a fast-moving, rolling-release target. The highest known
# needed value by a formula at this time (February 2016) was 43,478 for
# git-annex, so 100,000 should be enough to avoid most gratuitous
# backjumps build failures.
system "cabal", "install", "--jobs=#{make_jobs}", "--max-backjumps=100000", *args
end
def cabal_configure(flags)
system "cabal", "configure", flags
end
def cabal_install_tools(*tools)
# install tools sequentially, as some tools can depend on other tools
tools.each { |tool| cabal_install tool }
# unregister packages installed as dependencies for the tools, so
# that they can't cause dependency conflicts for the main package
rm_rf Dir[".cabal-sandbox/*packages.conf.d/"]
end
def install_cabal_package(*args)
options = args[-1].is_a?(Hash) ? args.pop : {}
cabal_sandbox do
cabal_install_tools(*options[:using]) if options[:using]
# if we have build flags, we have to pass them to cabal install to resolve the necessary
# dependencies, and call cabal configure afterwards to set the flags again for compile
2016-09-23 11:01:40 +02:00
flags = "--flags=#{options[:flags].join(" ")}" if options[:flags]
args_and_flags = args
2016-09-23 11:01:40 +02:00
args_and_flags << flags unless flags.nil?
# install dependencies in the sandbox
cabal_install "--only-dependencies", *args_and_flags
# call configure if build flags are set
2016-09-23 11:01:40 +02:00
cabal_configure flags unless flags.nil?
# install the main package in the destination dir
cabal_install "--prefix=#{prefix}", *args
yield if block_given?
end
end
end
end
end