1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
require "formula"
require "compilers"
module SharedEnvExtension
include CompilerConstants
CC_FLAG_VARS = %w{CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS}
FC_FLAG_VARS = %w{FCFLAGS FFLAGS}
COMPILER_SYMBOL_MAP = {
"gcc-4.0" => :gcc_4_0,
"gcc-4.2" => :gcc,
"llvm-gcc" => :llvm,
"clang" => :clang,
}
COMPILERS = COMPILER_SYMBOL_MAP.values +
GNU_GCC_VERSIONS.map { |n| "gcc-4.#{n}" }
SANITIZED_VARS = %w[
CDPATH GREP_OPTIONS CLICOLOR_FORCE
CPATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH OBJC_INCLUDE_PATH
CC CXX OBJC OBJCXX CPP MAKE LD LDSHARED
CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS LDFLAGS CPPFLAGS
MACOSX_DEPLOYMENT_TARGET SDKROOT DEVELOPER_DIR
CMAKE_PREFIX_PATH CMAKE_INCLUDE_PATH CMAKE_FRAMEWORK_PATH
GOBIN
]
def reset
SANITIZED_VARS.each { |k| delete(k) }
end
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|
old = self[key]
if old.nil? || old.empty?
self[key] = value
else
self[key] += separator + value
end
end
end
def prepend keys, value, separator = ' '
value = value.to_s
Array(keys).each do |key|
old = self[key]
if old.nil? || old.empty?
self[key] = value
else
self[key] = value + separator + old
end
end
end
def append_path key, path
append key, path, File::PATH_SEPARATOR if File.directory? path
end
def prepend_path key, path
prepend key, path, File::PATH_SEPARATOR if File.directory? path
end
def prepend_create_path key, path
path = Pathname.new(path) unless path.is_a? Pathname
path.mkpath
prepend_path key, path
end
def remove keys, value
Array(keys).each do |key|
next unless self[key]
self[key] = self[key].sub(value, '')
delete(key) if self[key].empty?
end if value
end
def cc; self['CC']; end
def cxx; self['CXX']; end
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
def compiler
@compiler ||= if (cc = ARGV.cc || homebrew_cc)
COMPILER_SYMBOL_MAP.fetch(cc) do |other|
case other
when GNU_GCC_REGEXP
other
else
raise "Invalid value for --cc: #{other}"
end
end
else
MacOS.default_compiler
end
end
def determine_cc
COMPILER_SYMBOL_MAP.invert.fetch(compiler, compiler)
end
COMPILERS.each do |compiler|
define_method(compiler) do
@compiler = compiler
self.cc = determine_cc
self.cxx = determine_cxx
end
end
# 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)
send CompilerSelector.new(formula).compiler
end
# 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}
self['PATH'] = paths.unshift(*self['PATH'].split(File::PATH_SEPARATOR)).uniq.join(File::PATH_SEPARATOR)
# XXX hot fix to prefer brewed stuff (e.g. python) over /usr/bin.
prepend_path 'PATH', HOMEBREW_PREFIX/'bin'
end
def fortran
flags = []
if fc
ohai "Building with an alternative Fortran compiler"
puts "This is unsupported."
self['F77'] ||= fc
if ARGV.include? '--default-fortran-flags'
flags = FC_FLAG_VARS.reject { |key| self[key] }
elsif values_at(*FC_FLAG_VARS).compact.empty?
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
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
end
flags.each { |key| self[key] = cflags }
set_cpu_flags(flags)
end
# ld64 is a newer linker provided for Xcode 2.5
def ld64
ld64 = Formulary.factory('ld64')
self['LD'] = ld64.bin/'ld'
append "LDFLAGS", "-B#{ld64.bin}/"
end
def gcc_version_formula(version)
gcc_name = "gcc-#{version}"
gcc_version_name = "gcc#{version.delete('.')}"
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}"
if gcc_path.exist?
gcc_formula
elsif gcc_versions_path.exist?
Formulary.factory gcc_version_name
elsif gcc_formula.version.to_s.include?(version)
gcc_formula
elsif (gcc_versions_formula = Formulary.factory(gcc_version_name) rescue nil)
gcc_versions_formula
else
gcc_formula
end
end
def warn_about_non_apple_gcc(gcc)
gcc_name = 'gcc' + gcc.delete('.')
begin
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?
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
def permit_arch_flags; end
private
def cc= val
self["CC"] = self["OBJC"] = val.to_s
end
def cxx= val
self["CXX"] = self["OBJCXX"] = val.to_s
end
def homebrew_cc
self["HOMEBREW_CC"]
end
end
|