2013-11-27 17:29:06 -06:00
|
|
|
require 'formula'
|
|
|
|
|
2013-08-19 12:32:59 -05:00
|
|
|
module SharedEnvExtension
|
|
|
|
CC_FLAG_VARS = %w{CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS}
|
|
|
|
FC_FLAG_VARS = %w{FCFLAGS FFLAGS}
|
|
|
|
|
2013-08-22 22:29:49 -07:00
|
|
|
# Update these every time a new GNU GCC branch is released
|
|
|
|
GNU_GCC_VERSIONS = (3..9)
|
|
|
|
GNU_GCC_REGEXP = /gcc-(4\.[3-9])/
|
|
|
|
|
2013-12-02 01:16:50 -06:00
|
|
|
COMPILER_ALIASES = {'gcc' => 'gcc-4.2', 'llvm' => 'llvm-gcc'}
|
2013-08-24 14:03:16 -07:00
|
|
|
COMPILER_SYMBOL_MAP = { 'gcc-4.0' => :gcc_4_0,
|
|
|
|
'gcc-4.2' => :gcc,
|
|
|
|
'llvm-gcc' => :llvm,
|
|
|
|
'clang' => :clang }
|
2013-08-23 22:25:35 -07:00
|
|
|
|
2013-08-19 12:32:59 -05:00
|
|
|
def remove_cc_etc
|
|
|
|
keys = %w{CC CXX OBJC OBJCXX LD CPP CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS LDFLAGS CPPFLAGS}
|
|
|
|
removed = Hash[*keys.map{ |key| [key, self[key]] }.flatten]
|
|
|
|
keys.each do |key|
|
|
|
|
delete(key)
|
|
|
|
end
|
|
|
|
removed
|
|
|
|
end
|
|
|
|
def append_to_cflags newflags
|
|
|
|
append(CC_FLAG_VARS, newflags)
|
|
|
|
end
|
|
|
|
def remove_from_cflags val
|
|
|
|
remove CC_FLAG_VARS, val
|
|
|
|
end
|
|
|
|
def append keys, value, separator = ' '
|
|
|
|
value = value.to_s
|
|
|
|
Array(keys).each do |key|
|
|
|
|
unless self[key].to_s.empty?
|
2013-08-26 15:02:51 -05:00
|
|
|
self[key] = self[key] + separator + value
|
2013-08-19 12:32:59 -05:00
|
|
|
else
|
2013-08-26 15:02:51 -05:00
|
|
|
self[key] = value
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def prepend keys, value, separator = ' '
|
2013-08-26 15:02:51 -05:00
|
|
|
value = value.to_s
|
2013-08-19 12:32:59 -05:00
|
|
|
Array(keys).each do |key|
|
|
|
|
unless self[key].to_s.empty?
|
2013-08-26 15:02:51 -05:00
|
|
|
self[key] = value + separator + self[key]
|
2013-08-19 12:32:59 -05:00
|
|
|
else
|
2013-08-26 15:02:51 -05:00
|
|
|
self[key] = value
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-08-19 17:21:13 -05:00
|
|
|
|
|
|
|
def append_path key, path
|
|
|
|
append key, path, File::PATH_SEPARATOR if File.directory? path
|
|
|
|
end
|
|
|
|
|
2013-08-19 12:32:59 -05:00
|
|
|
def prepend_path key, path
|
2013-08-15 21:50:13 +02:00
|
|
|
prepend key, path, File::PATH_SEPARATOR if File.directory? path
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
2013-08-19 17:21:13 -05:00
|
|
|
|
2014-01-04 12:49:01 +00:00
|
|
|
def prepend_create_path key, path
|
|
|
|
path = Pathname.new(path) unless path.is_a? Pathname
|
|
|
|
path.mkpath
|
|
|
|
prepend_path key, path
|
|
|
|
end
|
|
|
|
|
2013-08-19 12:32:59 -05:00
|
|
|
def remove keys, value
|
|
|
|
Array(keys).each do |key|
|
|
|
|
next unless self[key]
|
|
|
|
self[key] = self[key].sub(value, '')
|
|
|
|
delete(key) if self[key].to_s.empty?
|
|
|
|
end if value
|
|
|
|
end
|
|
|
|
|
2013-08-29 19:20:52 -05:00
|
|
|
def cc; self['CC']; end
|
|
|
|
def cxx; self['CXX']; end
|
2013-08-19 12:32:59 -05:00
|
|
|
def cflags; self['CFLAGS']; end
|
|
|
|
def cxxflags; self['CXXFLAGS']; end
|
|
|
|
def cppflags; self['CPPFLAGS']; end
|
|
|
|
def ldflags; self['LDFLAGS']; end
|
|
|
|
def fc; self['FC']; end
|
|
|
|
def fflags; self['FFLAGS']; end
|
|
|
|
def fcflags; self['FCFLAGS']; end
|
|
|
|
|
2013-08-24 14:03:16 -07:00
|
|
|
def compiler
|
2013-09-19 23:35:53 -07:00
|
|
|
@compiler ||= if (cc = ARGV.cc)
|
2013-08-22 22:29:49 -07:00
|
|
|
COMPILER_SYMBOL_MAP.fetch(cc) do |other|
|
2014-05-18 13:26:07 -05:00
|
|
|
case other
|
|
|
|
when GNU_GCC_REGEXP
|
|
|
|
other
|
2013-08-22 22:29:49 -07:00
|
|
|
else
|
|
|
|
raise "Invalid value for --cc: #{other}"
|
|
|
|
end
|
|
|
|
end
|
2014-05-18 14:34:31 -05:00
|
|
|
elsif homebrew_cc
|
|
|
|
cc = COMPILER_ALIASES.fetch(homebrew_cc, homebrew_cc)
|
2013-12-02 00:15:32 -06:00
|
|
|
COMPILER_SYMBOL_MAP.fetch(cc) { MacOS.default_compiler }
|
2013-08-24 14:03:16 -07:00
|
|
|
else
|
|
|
|
MacOS.default_compiler
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-10 23:08:17 -07:00
|
|
|
# If the given compiler isn't compatible, will try to select
|
|
|
|
# an alternate compiler, altering the value of environment variables.
|
|
|
|
# If no valid compiler is found, raises an exception.
|
|
|
|
def validate_cc!(formula)
|
2014-05-18 14:40:44 -05:00
|
|
|
if formula.fails_with? compiler
|
2013-12-03 22:16:37 -06:00
|
|
|
send CompilerSelector.new(formula).compiler
|
2013-09-10 23:08:17 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-19 12:32:59 -05:00
|
|
|
# Snow Leopard defines an NCURSES value the opposite of most distros
|
|
|
|
# See: http://bugs.python.org/issue6848
|
|
|
|
# Currently only used by aalib in core
|
|
|
|
def ncurses_define
|
|
|
|
append 'CPPFLAGS', "-DNCURSES_OPAQUE=0"
|
|
|
|
end
|
|
|
|
|
|
|
|
def userpaths!
|
|
|
|
paths = ORIGINAL_PATHS.map { |p| p.realpath.to_s rescue nil } - %w{/usr/X11/bin /opt/X11/bin}
|
2013-08-19 14:07:14 -05:00
|
|
|
self['PATH'] = paths.unshift(*self['PATH'].split(File::PATH_SEPARATOR)).uniq.join(File::PATH_SEPARATOR)
|
2013-08-19 12:32:59 -05:00
|
|
|
# XXX hot fix to prefer brewed stuff (e.g. python) over /usr/bin.
|
2013-08-19 17:21:13 -05:00
|
|
|
prepend_path 'PATH', HOMEBREW_PREFIX/'bin'
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def fortran
|
2013-08-30 19:07:10 -05:00
|
|
|
flags = []
|
|
|
|
|
2013-08-30 19:00:19 -05:00
|
|
|
if fc
|
2013-08-19 12:32:59 -05:00
|
|
|
ohai "Building with an alternative Fortran compiler"
|
|
|
|
puts "This is unsupported."
|
2013-08-30 19:00:19 -05:00
|
|
|
self['F77'] ||= fc
|
2013-08-19 12:32:59 -05:00
|
|
|
|
|
|
|
if ARGV.include? '--default-fortran-flags'
|
2013-08-30 19:07:10 -05:00
|
|
|
flags = FC_FLAG_VARS.reject { |key| self[key] }
|
2013-08-30 18:59:58 -05:00
|
|
|
elsif values_at(*FC_FLAG_VARS).compact.empty?
|
2013-08-19 12:32:59 -05:00
|
|
|
opoo <<-EOS.undent
|
|
|
|
No Fortran optimization information was provided. You may want to consider
|
|
|
|
setting FCFLAGS and FFLAGS or pass the `--default-fortran-flags` option to
|
|
|
|
`brew install` if your compiler is compatible with GCC.
|
|
|
|
|
|
|
|
If you like the default optimization level of your compiler, ignore this
|
|
|
|
warning.
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2014-02-02 12:57:46 -06:00
|
|
|
else
|
|
|
|
if (gfortran = which('gfortran', (HOMEBREW_PREFIX/'bin').to_s))
|
|
|
|
ohai "Using Homebrew-provided fortran compiler."
|
|
|
|
elsif (gfortran = which('gfortran', ORIGINAL_PATHS.join(File::PATH_SEPARATOR)))
|
|
|
|
ohai "Using a fortran compiler found at #{gfortran}."
|
|
|
|
end
|
|
|
|
if gfortran
|
|
|
|
puts "This may be changed by setting the FC environment variable."
|
|
|
|
self['FC'] = self['F77'] = gfortran
|
|
|
|
flags = FC_FLAG_VARS
|
|
|
|
end
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
2013-08-30 19:07:10 -05:00
|
|
|
|
|
|
|
flags.each { |key| self[key] = cflags }
|
|
|
|
set_cpu_flags(flags)
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|
2013-06-04 10:18:14 -05:00
|
|
|
|
2013-09-28 14:57:17 -07:00
|
|
|
# ld64 is a newer linker provided for Xcode 2.5
|
|
|
|
def ld64
|
|
|
|
ld64 = Formula.factory('ld64')
|
|
|
|
self['LD'] = ld64.bin/'ld'
|
2014-04-04 22:02:48 -05:00
|
|
|
append "LDFLAGS", "-B#{ld64.bin}/"
|
2013-09-28 14:57:17 -07:00
|
|
|
end
|
|
|
|
|
2014-04-19 09:11:52 +01:00
|
|
|
def gcc_version_formula(version)
|
2014-05-05 13:40:25 +01:00
|
|
|
gcc_name = "gcc-#{version}"
|
|
|
|
gcc_version_name = "gcc#{version.delete('.')}"
|
2014-04-29 08:51:56 +01:00
|
|
|
|
2014-05-05 13:40:25 +01:00
|
|
|
ivar = "@#{gcc_version_name}_version"
|
|
|
|
return instance_variable_get(ivar) if instance_variable_defined?(ivar)
|
2014-04-30 12:38:22 +01:00
|
|
|
|
2014-05-05 13:40:25 +01:00
|
|
|
gcc_path = HOMEBREW_PREFIX.join "opt/gcc/bin/#{gcc_name}"
|
|
|
|
gcc_formula = Formulary.factory "gcc"
|
|
|
|
gcc_versions_path = \
|
|
|
|
HOMEBREW_PREFIX.join "opt/#{gcc_version_name}/bin/#{gcc_name}"
|
2014-04-30 12:38:22 +01:00
|
|
|
|
2014-05-05 13:40:25 +01:00
|
|
|
formula = if gcc_path.exist?
|
|
|
|
gcc_formula
|
|
|
|
elsif gcc_versions_path.exist?
|
2014-05-06 22:17:59 +01:00
|
|
|
Formulary.factory gcc_version_name
|
2014-04-29 08:51:56 +01:00
|
|
|
elsif gcc_formula.version.to_s.include?(version)
|
|
|
|
gcc_formula
|
2014-05-05 13:40:25 +01:00
|
|
|
elsif (gcc_versions_formula = Formulary.factory(gcc_version_name) rescue nil)
|
2014-04-29 08:51:56 +01:00
|
|
|
gcc_versions_formula
|
2014-04-30 12:38:22 +01:00
|
|
|
else
|
2014-05-05 13:40:25 +01:00
|
|
|
gcc_formula
|
2014-04-29 08:51:56 +01:00
|
|
|
end
|
2014-05-05 13:40:25 +01:00
|
|
|
|
|
|
|
instance_variable_set(ivar, formula)
|
2014-04-19 09:11:52 +01:00
|
|
|
end
|
|
|
|
|
2013-06-04 10:18:14 -05:00
|
|
|
def warn_about_non_apple_gcc(gcc)
|
2014-04-19 09:11:52 +01:00
|
|
|
gcc_name = 'gcc' + gcc.delete('.')
|
|
|
|
|
2013-06-04 10:18:14 -05:00
|
|
|
begin
|
2014-04-19 09:11:52 +01:00
|
|
|
gcc_formula = gcc_version_formula(gcc)
|
|
|
|
if gcc_formula.name == "gcc"
|
|
|
|
return if gcc_formula.opt_prefix.exist?
|
|
|
|
raise <<-EOS.undent
|
|
|
|
The Homebrew GCC was not installed.
|
|
|
|
You must:
|
|
|
|
brew install gcc
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
|
|
|
if !gcc_formula.opt_prefix.exist?
|
2013-06-04 10:18:14 -05:00
|
|
|
raise <<-EOS.undent
|
|
|
|
The requested Homebrew GCC, #{gcc_name}, was not installed.
|
|
|
|
You must:
|
|
|
|
brew tap homebrew/versions
|
|
|
|
brew install #{gcc_name}
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
rescue FormulaUnavailableError
|
|
|
|
raise <<-EOS.undent
|
|
|
|
Homebrew GCC requested, but formula #{gcc_name} not found!
|
|
|
|
You may need to: brew tap homebrew/versions
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
end
|
2014-05-14 00:00:59 -05:00
|
|
|
|
|
|
|
def permit_arch_flags; end
|
2014-05-18 14:34:31 -05:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def cc= val
|
|
|
|
self["CC"] = self["OBJC"] = val.to_s
|
|
|
|
end
|
|
|
|
|
|
|
|
def cxx= val
|
|
|
|
self["CXX"] = self["OBJCXX"] = val.to_s
|
|
|
|
end
|
2014-05-18 14:34:31 -05:00
|
|
|
|
|
|
|
def homebrew_cc
|
|
|
|
self["HOMEBREW_CC"]
|
|
|
|
end
|
2013-08-19 12:32:59 -05:00
|
|
|
end
|