| 
									
										
										
										
											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-30 16:44:49 -05:00
										 |  |  |   def cc= val | 
					
						
							| 
									
										
										
										
											2013-09-03 10:07:53 -05:00
										 |  |  |     self['CC'] = self['OBJC'] = val.to_s | 
					
						
							| 
									
										
										
										
											2013-08-30 16:44:49 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cxx= val | 
					
						
							| 
									
										
										
										
											2013-09-03 10:07:53 -05:00
										 |  |  |     self['CXX'] = self['OBJCXX'] = val.to_s | 
					
						
							| 
									
										
										
										
											2013-08-30 16:44:49 -05:00
										 |  |  |   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| | 
					
						
							|  |  |  |         if other =~ GNU_GCC_REGEXP then other | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           raise "Invalid value for --cc: #{other}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-08-24 14:03:16 -07:00
										 |  |  |     elsif ARGV.include? '--use-gcc' | 
					
						
							|  |  |  |       gcc_installed = Formula.factory('apple-gcc42').installed? rescue false | 
					
						
							|  |  |  |       # fall back to something else on systems without Apple gcc | 
					
						
							|  |  |  |       if MacOS.locate('gcc-4.2') || gcc_installed | 
					
						
							|  |  |  |         :gcc | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         raise "gcc-4.2 not found!" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     elsif ARGV.include? '--use-llvm' | 
					
						
							|  |  |  |       :llvm | 
					
						
							|  |  |  |     elsif ARGV.include? '--use-clang' | 
					
						
							|  |  |  |       :clang | 
					
						
							|  |  |  |     elsif self['HOMEBREW_CC'] | 
					
						
							| 
									
										
										
										
											2013-12-02 01:16:50 -06:00
										 |  |  |       cc = COMPILER_ALIASES.fetch(self['HOMEBREW_CC'], self['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) | 
					
						
							|  |  |  |     if formula.fails_with? ENV.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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-30 16:27:31 -05:00
										 |  |  |     elsif (gfortran = which('gfortran', ORIGINAL_PATHS.join(File::PATH_SEPARATOR))) | 
					
						
							| 
									
										
										
										
											2013-08-19 12:32:59 -05:00
										 |  |  |       ohai "Using Homebrew-provided fortran compiler." | 
					
						
							|  |  |  |       puts "This may be changed by setting the FC environment variable." | 
					
						
							| 
									
										
										
										
											2013-08-30 16:27:31 -05:00
										 |  |  |       self['FC'] = self['F77'] = gfortran | 
					
						
							| 
									
										
										
										
											2013-08-30 19:07:10 -05:00
										 |  |  |       flags = FC_FLAG_VARS | 
					
						
							| 
									
										
										
										
											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' | 
					
						
							|  |  |  |     append "LDFLAGS", "-B#{ld64.bin.to_s+"/"}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-04 10:18:14 -05:00
										 |  |  |   def warn_about_non_apple_gcc(gcc) | 
					
						
							|  |  |  |     opoo "Experimental support for non-Apple GCC enabled. Some builds may fail!" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       gcc_name = 'gcc' + gcc.delete('.') | 
					
						
							| 
									
										
										
										
											2013-09-10 23:08:17 -07:00
										 |  |  |       gcc = Formulary.factory(gcc_name) | 
					
						
							| 
									
										
										
										
											2013-10-16 18:43:56 -07:00
										 |  |  |       if !gcc.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 | 
					
						
							| 
									
										
										
										
											2013-08-19 12:32:59 -05:00
										 |  |  | end |