diff options
Diffstat (limited to 'Library')
| l--------- | Library/ENV/4.3/c++ | 1 | ||||
| -rwxr-xr-x | Library/ENV/4.3/cc | 140 | ||||
| l--------- | Library/ENV/4.3/clang | 1 | ||||
| l--------- | Library/ENV/4.3/clang++ | 1 | ||||
| l--------- | Library/ENV/4.3/cpp | 1 | ||||
| l--------- | Library/ENV/4.3/g++ | 1 | ||||
| l--------- | Library/ENV/4.3/gcc | 1 | ||||
| l--------- | Library/ENV/4.3/i686-apple-darwin11-llvm-g++-4.2 | 1 | ||||
| l--------- | Library/ENV/4.3/i686-apple-darwin11-llvm-gcc-4.2 | 1 | ||||
| l--------- | Library/ENV/4.3/ld | 1 | ||||
| l--------- | Library/ENV/4.3/llvm-g++ | 1 | ||||
| l--------- | Library/ENV/4.3/llvm-g++-4.2 | 1 | ||||
| l--------- | Library/ENV/4.3/llvm-gcc | 1 | ||||
| l--------- | Library/ENV/4.3/llvm-gcc-4.2 | 1 | ||||
| -rwxr-xr-x | Library/ENV/4.3/xcrun | 12 | ||||
| -rw-r--r-- | Library/ENV/libsuperenv.rb | 41 | ||||
| -rwxr-xr-x | Library/Homebrew/build.rb | 61 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/--env.rb | 6 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/audit.rb | 3 | ||||
| -rw-r--r-- | Library/Homebrew/extend/ENV.rb | 121 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 4 | ||||
| -rw-r--r-- | Library/Homebrew/macos.rb | 10 | ||||
| -rw-r--r-- | Library/Homebrew/superenv.rb | 240 |
23 files changed, 545 insertions, 106 deletions
diff --git a/Library/ENV/4.3/c++ b/Library/ENV/4.3/c++ new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/c++ @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/cc b/Library/ENV/4.3/cc new file mode 100755 index 000000000..8673c7527 --- /dev/null +++ b/Library/ENV/4.3/cc @@ -0,0 +1,140 @@ +#!/usr/bin/ruby -W0 +#TODO make it work with homebrew/dupes/gcc +#TODO? If we find -mmacosx-version-min=10.8, change sdkroot? warn visibly if no such SDK? +#TODO fix pkg-config files, should point to /usr/local or /usr/local/opt +#TODO for easier to understand code, don't monkey-patch ENV, just set via a hash from a helper class +#TODO create mechanism to specify build effects like %w{-O0 -O4 vanilla-arg-parsing sdk=10.6} etc. +#TODO DSL for lame-env (and rename to typical-env or something better) +#TODO consider always setting CC to cc and instead having HOMEBREW_CC to force cc choice in end toolchain +# in verbose mode print out things like "gcc called, but redirecting to clang" if that happens +#TODO `brew sh`: https://github.com/mxcl/homebrew/issues/14381#issuecomment-8017538 + +require "#{File.dirname __FILE__}/../libsuperenv" +require 'set' + +def cccfg? flags + flags.split('').all?{|c| ENV['HOMEBREW_CCCFG'].include? c } if ENV['HOMEBREW_CCCFG'] +end +def nclt? + $sdkroot != nil +end +def cmake_prefixes + @prefixes ||= ENV['CMAKE_PREFIX_PATH'].split(':').reject do |path| + case path + when '/usr/local' then !nclt? + when '/usr', '/', "#$sdkroot/usr" then true + end + end +end + +class Cmd + def initialize path, args + @cmd = path.basename.freeze + @args = args.freeze + end + def mode + if @cmd == 'cpp' or @cmd == 'ld' + @cmd.to_sym + elsif @args.include? '-c' + :cc + elsif @args.include? '-E' + :cpp + else + :ccld + end + end + def tool + case @cmd + when /gcc/ then 'gcc' + when /g\+\+/ then 'g++' + when 'clang', 'clang++' + @cmd + when 'ld', 'cpp', 'cc' + ENV['HOMEBREW_CC'].chuzzle or 'clang' + when 'c++' + case ENV['HOMEBREW_CC'] + when /gcc/ then 'g++' + else 'clang++' + end + else + abort "Unknown command: #{@cmd}" + end + end + def args + args = if cccfg? 'O' + refurbished_args + else + @args.dup + end + args.unshift("--sysroot=#$sdkroot") if nclt? + case mode + when :cpp + %w{-E} + cppflags + args + when :ld + ldflags + args + when :cc + cflags + cppflags + args + when :ccld + cflags + cppflags + ldflags + args + end.compact + end + def refurbished_args + iset = Set.new(cmake_prefixes.map{|prefix| "#{prefix}/include" }) + lset = Set.new + args = [] + whittler = @args.each + loop do + case arg = whittler.next + when '-arch', /^-Xarch_/ + whittler.next + when /^-g\d?/, /^-gstabs\d+/, '-gstabs+', /^-ggdb\d?/, '-gdwarf-2', + /^-march=.+/, /^-mtune=.+/, '-m64', '-m32', + /^-O[0-9zs]/, '-fast', + %r{^-[IL]/opt/local}, %r{^-[IL]/sw}, # no macports/fink + %r{^-[IL]/usr/X11}, %r{^-[IL]/opt/X11}, # we add X11 ourselves + '-pedantic', '-pedantic-errors' + when /^-W.*/ + args << arg if arg =~ /^-Wl,/ + when /^-I(.+)/ + # it is okay to add a space after the -I; so let's support it + path = $1.chuzzle || whittler.next + args << "-I#{path}" if iset.add?(path.cleanpath) + when /^-l(.+)/ + lib = $1.chuzzle || whittler.next + args << "-l#{lib}" if lset.add?(lib) + else + args << arg + end + end + args + end + def cflags + if cccfg? 'Ob' + %w{-mtune=generic -Oz} + elsif cccfg? 'O' + u = '-arch i386 -arch x86_64' if cccfg? 'u' + c = case tool when 'clang', 'clang++' then '-march=native' end + %w{-pipe -w -Os} << u << c + else + [] + end + end + def ldflags + cmake_prefixes.map{|prefix| "#{prefix}/lib" }.to_flags('-L') + end + def cppflags + all = cmake_prefixes.map{|prefix| "#{prefix}/include" } + opt = all.select{|prefix| prefix =~ %r{^#$brewfix/opt} } + sys = all - opt + ENV['CMAKE_INCLUDE_PATH'].split(':') + # we want our keg-only includes to be found before system includes so that + # they override the system options. + sys.to_flags('-isystem') + opt.to_flags('-I') + end +end + +####################################################################### sanity +abort "The build-tool has reset ENV. --lame-env required." unless ENV['HOMEBREW_BREW_FILE'] + +######################################################################### main +cmd = Cmd.new($0, ARGV) +exec "xcrun", cmd.tool, *cmd.args diff --git a/Library/ENV/4.3/clang b/Library/ENV/4.3/clang new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/clang @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/clang++ b/Library/ENV/4.3/clang++ new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/clang++ @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/cpp b/Library/ENV/4.3/cpp new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/cpp @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/g++ b/Library/ENV/4.3/g++ new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/g++ @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/gcc b/Library/ENV/4.3/gcc new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/gcc @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/i686-apple-darwin11-llvm-g++-4.2 b/Library/ENV/4.3/i686-apple-darwin11-llvm-g++-4.2 new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/i686-apple-darwin11-llvm-g++-4.2 @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/i686-apple-darwin11-llvm-gcc-4.2 b/Library/ENV/4.3/i686-apple-darwin11-llvm-gcc-4.2 new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/i686-apple-darwin11-llvm-gcc-4.2 @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/ld b/Library/ENV/4.3/ld new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/ld @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/llvm-g++ b/Library/ENV/4.3/llvm-g++ new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/llvm-g++ @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/llvm-g++-4.2 b/Library/ENV/4.3/llvm-g++-4.2 new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/llvm-g++-4.2 @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/llvm-gcc b/Library/ENV/4.3/llvm-gcc new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/llvm-gcc @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/llvm-gcc-4.2 b/Library/ENV/4.3/llvm-gcc-4.2 new file mode 120000 index 000000000..2652f5f42 --- /dev/null +++ b/Library/ENV/4.3/llvm-gcc-4.2 @@ -0,0 +1 @@ +cc
\ No newline at end of file diff --git a/Library/ENV/4.3/xcrun b/Library/ENV/4.3/xcrun new file mode 100755 index 000000000..3d2dd642e --- /dev/null +++ b/Library/ENV/4.3/xcrun @@ -0,0 +1,12 @@ +#!/bin/bash +# This wrapper because 4.3 xcrun doesn't work with CLT-only configurations +# But many build-systems expect it to work. This fixes that. +# NOTE only works if they call xcrun without a full-path. Cross your fingers! + +if [ $HOMEBREW_SDKROOT ]; then + exec /usr/bin/xcrun "$@" +else + cmd="$1" + shift + exec "/usr/bin/$cmd" "$@" +fi diff --git a/Library/ENV/libsuperenv.rb b/Library/ENV/libsuperenv.rb new file mode 100644 index 000000000..dcd97efce --- /dev/null +++ b/Library/ENV/libsuperenv.rb @@ -0,0 +1,41 @@ +# Yes, a good deal of this could be imported from Homebrew-proper +# But Homebrew-proper is dog-slow currently, and I didn't want every cc +# instantiation to be slower be a tangible amount. + +class String + def directory?; File.directory? self end + def basename; File.basename self end + def cleanpath; require 'pathname'; Pathname.new(self).realpath.to_s rescue self end + def chuzzle; s = chomp; s unless s.empty? end + def dirname; File.dirname(self) end +end + +class NilClass + def chuzzle; end + def directory?; false end + def split(x); [] end +end + +class Array + def to_flags prefix + select{|path| path.directory? }.uniq.map{|path| prefix+path } + end +end + +module Kernel extend self + alias :_exec :exec + def exec *args + path = File.expand_path('~/Library/Logs/Homebrew/cc.log') + open(path, 'a') do |f| + f.print '[', $0 + f.print " -%s" % ENV['HOMEBREW_CCCFG'] if ENV['HOMEBREW_CCCFG'] + f.print '] ' + f.puts args.join(' ') + f.puts + end + _exec *args + end +end if ENV['HOMEBREW_LOG'] + +$brewfix = "#{__FILE__}/../../../".cleanpath.freeze +$sdkroot = ENV['HOMEBREW_SDKROOT'].freeze diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index dd3e02442..6742f4203 100755 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -13,22 +13,6 @@ at_exit do error_pipe = nil begin - raise $! if $! # an exception was already thrown when parsing the formula - - require 'extend/ENV' - require 'hardware' - require 'keg' - - ENV.extend(HomebrewEnvExtension) - ENV.setup_build_environment - # we must do this or tools like pkg-config won't get found by configure scripts etc. - ENV.prepend 'PATH', "#{HOMEBREW_PREFIX}/bin", ':' unless ORIGINAL_PATHS.include? HOMEBREW_PREFIX/'bin' - - # Force any future invocations of sudo to require the user's password to be - # re-entered. This is in-case any build script call sudo. Certainly this is - # can be inconvenient for the user. But we need to be safe. - system "/usr/bin/sudo -k" - # The main Homebrew process expects to eventually see EOF on the error # pipe in FormulaInstaller#build. However, if any child process fails to # terminate (i.e, fails to close the descriptor), this won't happen, and @@ -41,6 +25,16 @@ at_exit do error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) end + raise $! if $! # an exception was already thrown when parsing the formula + + require 'hardware' + require 'keg' + + # Force any future invocations of sudo to require the user's password to be + # re-entered. This is in-case any build script call sudo. Certainly this is + # can be inconvenient for the user. But we need to be safe. + system "/usr/bin/sudo -k" + install(Formula.factory($0)) rescue Exception => e unless error_pipe.nil? @@ -56,27 +50,36 @@ at_exit do end def install f - f.recursive_requirements.each { |req| req.modify_build_environment } + keg_only_deps = f.recursive_deps.uniq.select{|dep| dep.keg_only? } - f.recursive_deps.uniq.each do |dep| - dep = Formula.factory dep - if dep.keg_only? - opt = HOMEBREW_PREFIX/:opt/dep.name + require 'superenv' - raise "#{opt} not present\nReinstall #{dep}." unless opt.directory? + ENV.setup_build_environment unless superenv? - ENV.prepend 'LDFLAGS', "-L#{opt}/lib" - ENV.prepend 'CPPFLAGS', "-I#{opt}/include" - ENV.prepend 'PATH', "#{opt}/bin", ':' + keg_only_deps.each do |dep| + opt = HOMEBREW_PREFIX/:opt/dep.name - pcdir = opt/'lib/pkgconfig' - ENV.prepend 'PKG_CONFIG_PATH', pcdir, ':' if pcdir.directory? + #TODO try to fix, if only one key, easy, otherwise check formula.version + raise "#{opt} not present\nReinstall #{dep}. Sorry :(" unless opt.directory? - acdir = opt/'share/aclocal' - ENV.prepend 'ACLOCAL_PATH', acdir, ':' if acdir.directory? + if not superenv? + ENV.prepend_path 'PATH', "#{opt}/bin" + ENV.prepend_path 'PKG_CONFIG_PATH', "#{opt}/lib/pkgconfig" + ENV.prepend_path 'PKG_CONFIG_PATH', "#{opt}/share/pkgconfig" + ENV.prepend_path 'ACLOCAL_PATH', "#{opt}/share/aclocal" + ENV.prepend_path 'CMAKE_PREFIX_PATH', opt + ENV.prepend 'LDFLAGS', "-L#{opt}/lib" if (opt/:lib).directory? + ENV.prepend 'CPPFLAGS', "-I#{opt}/include" if (opt/:include).directory? end end + if superenv? + ENV.deps = keg_only_deps.map(&:to_s) + ENV.setup_build_environment + end + + f.recursive_requirements.each { |req| req.modify_build_environment } + if f.fails_with? ENV.compiler cs = CompilerSelector.new f cs.select_compiler diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 79323c300..b5d1253fe 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -1,9 +1,8 @@ -require 'extend/ENV' +require 'superenv' require 'hardware' module Homebrew extend self def __env - ENV.extend(HomebrewEnvExtension) ENV.setup_build_environment ENV.universal_binary if ARGV.build_universal? if $stdout.tty? @@ -17,10 +16,11 @@ module Homebrew extend self def build_env_keys env %w[ CC CXX LD CFLAGS CXXFLAGS CPPFLAGS LDFLAGS SDKROOT - CMAKE_PREFIX_PATH CMAKE_INBLUDE_PATH CMAKE_FRAMEWORK_PATH MAKEFLAGS + CMAKE_PREFIX_PATH CMAKE_INCLUDE_PATH CMAKE_FRAMEWORK_PATH MAKEFLAGS MACOSX_DEPLOYMENT_TARGET PKG_CONFIG_PATH HOMEBREW_BUILD_FROM_SOURCE HOMEBREW_DEBUG HOMEBREW_MAKE_JOBS HOMEBREW_VERBOSE HOMEBREW_USE_CLANG HOMEBREW_USE_GCC HOMEBREW_USE_LLVM HOMEBREW_SVN + MAKE GIT CPP ACLOCAL_PATH OBJC PATH ].select{ |key| env[key] } end diff --git a/Library/Homebrew/cmd/audit.rb b/Library/Homebrew/cmd/audit.rb index 18382de59..8244d40aa 100644 --- a/Library/Homebrew/cmd/audit.rb +++ b/Library/Homebrew/cmd/audit.rb @@ -1,6 +1,6 @@ require 'formula' require 'utils' -require 'extend/ENV' +require 'superenv' module Homebrew extend self def audit @@ -245,7 +245,6 @@ class FormulaAuditor def audit_patches # Some formulae use ENV in patches, so set up an environment - ENV.extend(HomebrewEnvExtension) ENV.setup_build_environment Patches.new(f.patches).select { |p| p.external? }.each do |p| diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 90ff517b1..69947879e 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -178,6 +178,8 @@ module HomebrewEnvExtension end def fortran + fc_flag_vars = %w{FCFLAGS FFLAGS} + if self['FC'] ohai "Building with an alternative Fortran compiler. This is unsupported." self['F77'] = self['FC'] unless self['F77'] @@ -333,28 +335,6 @@ Please take one of the following actions: remove_from_cflags '-Qunused-arguments' end - # Snow Leopard defines an NCURSES value the opposite of most distros - # See: http://bugs.python.org/issue6848 - def ncurses_define - append 'CPPFLAGS', "-DNCURSES_OPAQUE=0" - end - - # Shortcuts for reading common flags - def cc; self['CC'] or "gcc"; end - def cxx; self['CXX'] or "g++"; end - def cflags; self['CFLAGS']; end - def cxxflags;self['CXXFLAGS']; end - def cppflags;self['CPPFLAGS']; end - def ldflags; self['LDFLAGS']; end - - # Shortcuts for lists of common flags - def cc_flag_vars - %w{CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS} - end - def fc_flag_vars - %w{FCFLAGS FFLAGS} - end - def m64 append_to_cflags '-m64' append 'LDFLAGS', '-arch x86_64' @@ -376,49 +356,6 @@ Please take one of the following actions: end end - def prepend key, value, separator = ' ' - # Value should be a string, but if it is a pathname then coerce it. - value = value.to_s - - [*key].each do |key| - unless self[key].to_s.empty? - self[key] = value + separator + self[key] - else - self[key] = value - end - end - end - - def append key, value, separator = ' ' - # Value should be a string, but if it is a pathname then coerce it. - value = value.to_s - - [*key].each do |key| - unless self[key].to_s.empty? - self[key] = self[key] + separator + value - else - self[key] = value - end - end - end - - def append_to_cflags f - append cc_flag_vars, f - end - - def remove key, value - [*key].each do |key| - next if self[key].nil? - self[key] = self[key].sub value, '' # can't use sub! on ENV - self[key] = self[key].gsub /\s+/, ' ' # compact whitespace - self[key] = nil if self[key].empty? # keep things clean - end - end - - def remove_from_cflags f - remove cc_flag_vars, f - end - def replace_in_cflags before, after cc_flag_vars.each do |key| self[key] = self[key].sub before, after if self[key] @@ -491,13 +428,65 @@ Please take one of the following actions: Hardware.processor_count end end +end +class << ENV def remove_cc_etc keys = %w{CC CXX LD CPP CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS LDFLAGS CPPFLAGS} removed = Hash[*keys.map{ |key| [key, self[key]] }.flatten] keys.each do |key| - self[key] = nil + delete(key) end removed end + def cc_flag_vars + %w{CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS} + end + def append_to_cflags newflags + append(cc_flag_vars, newflags) + end + def remove_from_cflags f + remove cc_flag_vars, f + end + def append key, value, separator = ' ' + value = value.to_s + [*key].each do |key| + unless self[key].to_s.empty? + self[key] = self[key] + separator + value.to_s + else + self[key] = value.to_s + end + end + end + def prepend key, value, separator = ' ' + [*key].each do |key| + unless self[key].to_s.empty? + self[key] = value.to_s + separator + self[key] + else + self[key] = value.to_s + end + end + end + def prepend_path key, path + prepend key, path, ':' if File.directory? path + end + def remove key, value + [*key].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 + def cc; self['CC'] or "cc"; end + def cxx; self['CXX'] or "c++"; end + def cflags; self['CFLAGS']; end + def cxxflags;self['CXXFLAGS']; end + def cppflags;self['CPPFLAGS']; end + def ldflags; self['LDFLAGS']; end + + # Snow Leopard defines an NCURSES value the opposite of most distros + # See: http://bugs.python.org/issue6848 + def ncurses_define + append 'CPPFLAGS', "-DNCURSES_OPAQUE=0" + end end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 78209feb7..08e01a7d7 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -470,6 +470,8 @@ protected removed_ENV_variables = case if args.empty? then cmd.split(' ').first else cmd end when "xcodebuild" ENV.remove_cc_etc + when /^make\b/ + ENV.append 'HOMEBREW_CCCFG', "O", '' end if ARGV.verbose? @@ -500,6 +502,8 @@ protected rescue raise BuildError.new(self, cmd, args, $?) + ensure + ENV['HOMEBREW_CCCFG'] = ENV['HOMEBREW_CCCFG'].delete('O') if ENV['HOMEBREW_CCCFG'] end public diff --git a/Library/Homebrew/macos.rb b/Library/Homebrew/macos.rb index e6b0fbee3..a50639d20 100644 --- a/Library/Homebrew/macos.rb +++ b/Library/Homebrew/macos.rb @@ -1,7 +1,5 @@ module MacOS extend self - MDITEM_BUNDLE_ID_KEY = "kMDItemCFBundleIdentifier" - def version require 'version' MacOSVersion.new(MACOS_VERSION.to_s) @@ -212,12 +210,12 @@ module MacOS extend self end def app_with_bundle_id id - mdfind(MDITEM_BUNDLE_ID_KEY, id) + path = mdfind(id).first + Pathname.new(path) unless path.nil? or path.empty? end - def mdfind attribute, id - path = `/usr/bin/mdfind "#{attribute} == '#{id}'"`.split("\n").first - Pathname.new(path) unless path.nil? or path.empty? + def mdfind id + `/usr/bin/mdfind "kMDItemCFBundleIdentifier == '#{id}'"`.split("\n") end def pkgutil_info id diff --git a/Library/Homebrew/superenv.rb b/Library/Homebrew/superenv.rb new file mode 100644 index 000000000..8061abaf4 --- /dev/null +++ b/Library/Homebrew/superenv.rb @@ -0,0 +1,240 @@ +require 'extend/ENV' +require 'macos' + +### Why `superenv`? +# 1) Only specify the environment we need (NO LDFLAGS for cmake) +# 2) Only apply compiler specific options when we are calling that compiler +# 3) Force all incpaths and libpaths into the cc instantiation (less bugs) +# 4) Cater toolchain usage to specific Xcode versions +# 5) Remove flags that we don't want or that will break builds +# 6) Simpler code +# 7) Simpler formula that *just work* +# 8) Build-system agnostic configuration of the tool-chain + +def superenv_bin + @bin ||= (HOMEBREW_REPOSITORY/"Library/ENV").children.reject{|d| d.basename.to_s > MacOS::Xcode.version }.max +end + +def superenv? + not MacOS::Xcode.bad_xcode_select_path? and # because xcrun won't work + not MacOS::Xcode.folder.nil? and # because xcrun won't work + superenv_bin.directory? and + not ARGV.include? "--env=std" +end + +class << ENV + attr :deps, true + + def reset + %w{CC CXX LD CPP OBJC MAKE + CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS LDFLAGS CPPFLAGS + MACOS_DEPLOYMENT_TARGET SDKROOT + CMAKE_PREFIX_PATH CMAKE_INCLUDE_PATH CMAKE_FRAMEWORK_PATH + HOMEBREW_CCCFG HOMEBREW_DEP_PREFIXES + MAKEFLAGS MAKEJOBS}. + each{ |x| delete(x) } + delete('CDPATH') # avoid make issues that depend on changing directories + delete('GREP_OPTIONS') # can break CMake + delete('CLICOLOR_FORCE') # autotools doesn't like this + + if MacOS.mountain_lion? + # Fix issue with sed barfing on unicode characters on Mountain Lion + delete('LC_ALL') + ENV['LC_CTYPE'] = "C" + end + end + + def setup_build_environment + reset + ENV['CC'] = 'cc' + ENV['CXX'] = 'c++' + ENV['LD'] = 'ld' + ENV['CPP'] = 'cpp' + ENV['MAKE'] = 'make' + ENV['MAKEFLAGS'] ||= "-j#{Hardware.processor_count}" + ENV['PATH'] = determine_path + ENV['PKG_CONFIG_PATH'] = determine_pkg_config_path + ENV['HOMEBREW_CC'] = determine_cc + ENV['HOMEBREW_CCCFG'] = 'b' if ARGV.build_bottle? + ENV['HOMEBREW_SDKROOT'] = "#{MacOS.sdk_path}" if MacSystem.xcode43_without_clt? + ENV['CMAKE_PREFIX_PATH'] = determine_cmake_prefix_path + ENV['CMAKE_FRAMEWORK_PATH'] = "#{MacOS.sdk_path}/System/Library/Frameworks" if MacSystem.xcode43_without_clt? + ENV['CMAKE_INCLUDE_PATH'] = determine_cmake_include_path + ENV['ACLOCAL_PATH'] = determine_aclocal_path + end + + def universal_binary + append 'HOMEBREW_CCCFG', "u", '' + end + + private + + def determine_cc + if ARGV.include? '--use-gcc' + "gcc" + elsif ARGV.include? '--use-llvm' + "llvm-gcc" + elsif ARGV.include? '--use-clang' + "clang" + elsif ENV['HOMEBREW_USE_CLANG'] + opoo %{HOMEBREW_USE_CLANG is deprecated, use HOMEBREW_CC="clang" instead} + "clang" + elsif ENV['HOMEBREW_USE_LLVM'] + opoo %{HOMEBREW_USE_LLVM is deprecated, use HOMEBREW_CC="llvm" instead} + "llvm-gcc" + elsif ENV['HOMEBREW_USE_GCC'] + opoo %{HOMEBREW_USE_GCC is deprecated, use HOMEBREW_CC="gcc" instead} + "gcc" + elsif ENV['HOMEBREW_CC'] + case ENV['HOMEBREW_CC'] + when 'clang', 'gcc' then ENV['HOMEBREW_CC'] + when 'llvm', 'llvm-gcc' then 'llvm-gcc' + else + opoo "Invalid value for HOMEBREW_CC: #{ENV['HOMEBREW_CC']}" + raise # use default + end + else + raise + end + rescue + "clang" + end + + def determine_path + paths = [superenv_bin] + if MacSystem.xcode43_without_clt? + paths << "#{MacSystem.xcode43_developer_dir}/usr/bin" + paths << "#{MacSystem.xcode43_developer_dir}/Toolchains/XcodeDefault.xctoolchain/usr/bin" + end + paths += deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/bin" } + paths << HOMEBREW_PREFIX/:bin + paths << "#{MacSystem.x11_prefix}/bin" + paths += %w{/usr/bin /bin /usr/sbin /sbin} + paths.to_path_s + end + + def determine_pkg_config_path + paths = deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/lib/pkgconfig" } + paths += deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/share/pkgconfig" } + paths << "#{HOMEBREW_REPOSITORY}/lib/pkgconfig" + paths << "#{HOMEBREW_REPOSITORY}/share/pkgconfig" + # we put our paths before X because we dupe some of the X libraries + paths << "#{MacSystem.x11_prefix}/lib/pkgconfig" << "#{MacSystem.x11_prefix}/share/pkgconfig" + # Mountain Lion no longer ships some .pcs; ensure we pick up our versions + paths << "#{HOMEBREW_REPOSITORY}/Library/Homebrew/pkgconfig" if MacOS.mountain_lion? + paths.to_path_s + end + + def determine_cmake_prefix_path + paths = deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}" } + paths << "#{MacOS.sdk_path}/usr" if MacSystem.xcode43_without_clt? + paths << HOMEBREW_PREFIX.to_s # again always put ourselves ahead of X11 + paths << MacSystem.x11_prefix + paths.to_path_s + end + + def determine_cmake_include_path + sdk = MacOS.sdk_path if MacSystem.xcode43_without_clt? + paths = %W{#{MacSystem.x11_prefix}/include/freetype2} + paths << "#{sdk}/usr/include/libxml2" unless deps.include? 'libxml2' + # TODO prolly shouldn't always do this? + paths << "#{sdk}/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7" if MacSystem.xcode43_without_clt? + paths.to_path_s + end + + def determine_aclocal_path + paths = deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/share/aclocal" } + paths << "#{HOMEBREW_PREFIX}/share/aclocal" + paths << "/opt/X11/share/aclocal" + paths.to_path_s + end + + public + +### NO LONGER NECESSARY OR NO LONGER SUPPORTED + def noop(*args); end + %w[m64 m32 gcc_4_0_1 fast O4 O3 O2 Os Og O1 libxml2 minimal_optimization + no_optimization enable_warnings fortran x11 + macosxsdk remove_macosxsdk].each{|s| alias_method s, :noop } + +### DEPRECATE THESE + def compiler + case ENV['HOMEBREW_CC'] + when "llvm-gcc" then :llvm + when "gcc", "clang" then ENV['HOMEBREW_CC'].to_sym + else + raise + end + end + def deparallelize + delete('MAKEFLAGS') + end + alias_method :j1, :deparallelize + def gcc + ENV['CC'] = "gcc" + ENV['CXX'] = "g++" + end + def llvm + ENV['CC'] = "llvm-gcc" + ENV['CXX'] = "llvm-g++" + end + def clang + ENV['CC'] = "clang" + ENV['CXX'] = "clang++" + end + def make_jobs + ENV['MAKEFLAGS'] =~ /-\w*j(\d)+/ + [$1.to_i, 1].max + end + +end if superenv? + + +if not superenv? + ENV.extend(HomebrewEnvExtension) + # we must do this or tools like pkg-config won't get found by configure scripts etc. + ENV.prepend 'PATH', "#{HOMEBREW_PREFIX}/bin", ':' unless ORIGINAL_PATHS.include? HOMEBREW_PREFIX/'bin' +else + ENV.deps = [] +end + + +class Array + def to_path_s + map(&:to_s).select{|s| s and File.directory? s }.join(':').chuzzle + end +end + +# new code because I don't really trust the Xcode code now having researched it more +module MacSystem extend self + def xcode_clt_installed? + File.executable? "/usr/bin/clang" and File.executable? "/usr/bin/lldb" + end + + def xcode43_without_clt? + MacOS::Xcode.version >= "4.3" and not MacSystem.xcode_clt_installed? + end + + def x11_prefix + @x11_prefix ||= %W[/usr/X11 /opt/X11 + #{MacOS.sdk_path}/usr/X11].find{|path| File.directory? "#{path}/include" } + end + + def xcode43_developer_dir + @xcode43_developer_dir ||= + tst(ENV['DEVELOPER_DIR']) || + tst(`xcode-select -print-path 2>/dev/null`) || + tst("/Applications/Xcode.app/Contents/Developer") || + MacOS.mdfind("com.apple.dt.Xcode").find{|path| tst(path) } + raise unless @xcode43_developer_dir + @xcode43_developer_dir + end + + private + + def tst prefix + prefix = prefix.to_s.chomp + xcrun = "#{prefix}/usr/bin/xcrun" + prefix if xcrun != "/usr/bin/xcrun" and File.executable? xcrun + end +end |
