Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 1c47747b32
Fetching contributors…

Cannot retrieve contributors at this time

executable file 201 lines (190 sloc) 5.654 kB
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/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 create mechanism to specify build effects like %w{-O0 -O4 vanilla-arg-parsing sdk=10.6} etc.
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 syspath
if nclt?
%W{#$sdkroot/usr #$sdkroot/usr/local}
else
%W{/usr /usr/local}
end
end
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
Kernel.exec *args
end if ENV['HOMEBREW_LOG']
class Cmd
def initialize path, args
@arg0 = path.basename.freeze
@args = args.freeze
end
def mode
if @arg0 == 'cpp' or @arg0 == 'ld'
@arg0.to_sym
elsif @args.include? '-c'
:cc
elsif @args.include? '-E'
:cpp
else
:ccld
end
end
def tool
@tool ||= case @arg0
when 'ld' then 'ld'
when 'cc', 'c99', 'c89', 'cpp'
# Ideally we would run `cx9`, however these tools are POSIX compliant
# and don't support many flags. We need -isystem for instance, but also
# reliability is generally much higher if we just get clang/gcc to do
# the work since Makefiles are dumb and include a lot of excess flags.
ENV['HOMEBREW_CC']
when 'c++'
if ENV['HOMEBREW_CC'] =~ /gcc/
'g++'
else
'clang++'
end
else
@arg0
end
end
def args
args = if not cccfg? 'O' or tool == 'ld'
@args.dup
else
refurbished_args
end
if tool != 'ld'
args << "--sysroot=#$sdkroot"
else
args << "-syslibroot" << $sdkroot
end if nclt?
case mode
when :cpp
%w{-E} + args + cppflags
when :ld
ldflags + args
when :cc
cflags + args + cppflags
when :ccld
cflags + args + cppflags + ldflags
end.compact
end
def refurbished_args
lset = Set.new(libpath + syslibpath)
iset = Set.new(cpath.flatten)
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',
'-pedantic', '-pedantic-errors'
when '-fopenmp', '-lgomp'
# clang doesn't support OpenMP
args << arg if not tool =~ /^clang/
when /^-W.*/
args << arg if arg =~ /^-Wl,/
when '-macosx_version_min', '-dylib_install_name'
args << "-Wl,#{arg},#{whittler.next}"
when '-dylib'
args << "-Wl,#{arg}"
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(.+)/
path = $1.chuzzle || whittler.next
case path.cleanpath
when %r{^/opt}, %r{^/sw}, %r{/usr/X11}
# NOOP
else
args << "-L#{path}" if lset.add?(path.cleanpath)
end
else
args << arg
end
end
make_fuss(args)
args
end
def cflags
if cccfg? 'Ob'
%w{-mtune=generic -Oz}
elsif cccfg? 'O'
args = %w{-pipe -w -Os}
args << '-march=native' if tool =~ /clang/
args += %w{-arch i386 -arch x86_64} if cccfg? 'u'
args << "--std=#{@arg0}" if @arg0 =~ /c[89]9/
args
else
[]
end
end
def syslibpath
# We reject brew's lib as we explicitly add this as a -L flag, thus it
# is given higher priority by cc, so it surpasses the system libpath.
# NOTE this only counts if Homebrew is installed at /usr/local
syspath.map{|d| "#{d}/lib" }.reject{ "#$brewfix/lib" }
end
def syscpath
isystem, _ = cpath
isystem + syspath.map{|d| "#{d}/include" }
end
def cpath
cpath = ENV['CMAKE_PREFIX_PATH'].split(':').map{|d| "#{d}/include" } + ENV['CMAKE_INCLUDE_PATH'].split(':')
opt = cpath.select{|prefix| prefix =~ %r{^#$brewfix/opt} }
sys = cpath - opt
[sys, opt]
end
def libpath
ENV['CMAKE_PREFIX_PATH'].split(':').map{|d| "#{d}/lib" } +
ENV['CMAKE_LIBRARY_PATH'].split(':') -
syslibpath
end
def ldflags
libpath.to_flags('-L')
end
def cppflags
sys, opt = cpath
# we want our keg-only includes to be found before system includes *and*
# before any other includes the build-system adds
sys.to_flags('-isystem') + opt.to_flags('-I')
end
def make_fuss args
dels = @args - args
adds = args - @args
dups = dels & args
STDERR.puts "brew: superenv removed: #{dels*' '}" unless dels.empty?
STDERR.puts "brew: superenv deduped: #{dels}" unless dups.empty?
STDERR.puts "brew: superenv added: #{adds*' '}" unless adds.empty?
end
end
####################################################################### sanity
abort "The build-tool has reset ENV. --env=std required." unless ENV['HOMEBREW_BREW_FILE']
case ENV['HOMEBREW_CC'].chuzzle when 'cc', nil
# those values are not allowed
ENV['HOMEBREW_CC'] = 'clang'
end
######################################################################### main
cmd = Cmd.new($0, ARGV)
exec "xcrun", cmd.tool, *cmd.args
Jump to Line
Something went wrong with that request. Please try again.