diff --git a/Library/Homebrew/shims/linux/super/cc b/Library/Homebrew/shims/linux/super/cc deleted file mode 100755 index 8a1f606a1b..0000000000 --- a/Library/Homebrew/shims/linux/super/cc +++ /dev/null @@ -1,366 +0,0 @@ -#!/bin/sh -# Make sure this shim uses the same Ruby interpreter that is used by Homebrew. -unset RUBYLIB -unset RUBYOPT -if [ -z "$HOMEBREW_RUBY_PATH" ] -then - echo "${0##*/}: The build tool has reset ENV; --env=std required." >&2 - exit 1 -fi -exec "$HOMEBREW_RUBY_PATH" -x "$0" "$@" -#!/usr/bin/env ruby -W0 - -require "pathname" -require "set" - -class Cmd - attr_reader :config, :prefix, :cellar, :opt, :tmpdir, :deps - attr_reader :archflags, :optflags, :keg_regex, :formula_prefix - - def initialize(arg0, args) - @arg0 = arg0 - @args = args.freeze - @config = ENV.fetch("HOMEBREW_CCCFG") { "" } - @prefix = ENV["HOMEBREW_PREFIX"] - @cellar = ENV["HOMEBREW_CELLAR"] - @opt = ENV["HOMEBREW_OPT"] - @tmpdir = ENV["HOMEBREW_TEMP"] - @archflags = ENV.fetch("HOMEBREW_ARCHFLAGS") { "" }.split(" ") - @optflags = ENV.fetch("HOMEBREW_OPTFLAGS") { "" }.split(" ") - @deps = Set.new(ENV.fetch("HOMEBREW_DEPENDENCIES") { "" }.split(",")) - @formula_prefix = ENV["HOMEBREW_FORMULA_PREFIX"] - # matches opt or cellar prefix and formula name - @keg_regex = %r[(#{Regexp.escape(opt)}|#{Regexp.escape(cellar)})/([\w+-.@]+)] - end - - def mode - if @arg0 == "cpp" || @arg0 == "ld" - @arg0.to_sym - elsif @arg0 == "gold" || @arg0 == "ld.gold" - :ld - elsif @args.include? "-c" - if @arg0 =~ /(?:c|g|clang)\+\+/ - :cxx - else - :cc - end - elsif @args.include?("-xc++-header") || @args.each_cons(2).include?(["-x", "c++-header"]) - :cxx - elsif @args.include? "-E" - :ccE - else - if @arg0 =~ /(?:c|g|clang)\+\+/ - :cxxld - else - :ccld - end - end - end - - def tool - @tool ||= case @arg0 - when "ld" then "ld" - when "gold", "ld.gold" then "ld.gold" - when "cpp" then "cpp" - when /llvm_(clang(\+\+)?)/ - "#{ENV["HOMEBREW_PREFIX"]}/opt/llvm/bin/#{$1}" - when /\w\+\+(-\d(\.\d)?)?$/ - case ENV["HOMEBREW_CC"] - when /clang/ - "clang++" - when /llvm-gcc/ - "llvm-g++-4.2" - when /gcc(-\d(\.\d)?)?$/ - "g++" + $1.to_s - end - else - # Note that this is a universal fallback, so that we'll always invoke - # HOMEBREW_CC regardless of what name under which the tool was invoked. - ENV["HOMEBREW_CC"] - end - end - - def args - if @args.length == 1 && @args[0] == "-v" - # Don't add linker arguments if -v passed as sole option. This stops gcc - # -v with no other arguments from outputting a linker error. Some - # software uses gcc -v (wrongly) to sniff the GCC version. - return @args.dup - end - - if !refurbish_args? || tool == "ld" || configure? - args = @args.dup - else - args = refurbished_args - end - - case mode - when :ccld - cflags + args + cppflags + ldflags - when :cxxld - cxxflags + args + cppflags + ldflags - when :cc - cflags + args + cppflags - when :cxx - cxxflags + args + cppflags - when :ccE - args + cppflags - when :cpp - args + cppflags - when :ld - ldflags + args - end - end - - def refurbished_args - @lset = Set.new(library_paths) - @iset = Set.new(isystem_paths + include_paths) - - args = [] - enum = @args.each - - loop do - case arg = enum.next - when "-arch" - if permit_arch_flags? - args << arg << enum.next - else - enum.next - end - when "-m32", "-m64" - args << arg if permit_arch_flags? - when /^-Xarch_/ - refurbished = refurbish_arg(enum.next, enum) - unless refurbished.empty? - args << arg - args += refurbished - end - else - args += refurbish_arg(arg, enum) - end - end - - args - end - - def refurbish_arg(arg, enum) - args = [] - - case arg - when /^-g\d?$/, /^-gstabs\d+/, "-gstabs+", /^-ggdb\d?/, - /^-march=.+/, /^-mtune=.+/, /^-mcpu=.+/, - /^-O[0-9zs]?$/, "-fast", "-no-cpp-precomp", - "-pedantic", "-pedantic-errors", "-Wno-long-double", - "-Wno-unused-but-set-variable" - when "-fopenmp", "-lgomp", "-mno-fused-madd", "-fforce-addr", "-fno-defer-pop", - "-mno-dynamic-no-pic", "-fearly-inlining", /^-f(?:no-)?inline-functions-called-once/, - /^-finline-limit/, /^-f(?:no-)?check-new/, "-fno-delete-null-pointer-checks", - "-fcaller-saves", "-fthread-jumps", "-fno-reorder-blocks", "-fcse-skip-blocks", - "-frerun-cse-after-loop", "-frerun-loop-opt", "-fcse-follow-jumps", - "-fno-regmove", "-fno-for-scope", "-fno-tree-pre", "-fno-tree-dominator-opts", - "-fuse-linker-plugin", "-frounding-math" - # clang doesn't support these flags - args << arg unless tool =~ /^clang/ - when "--fast-math" - arg = "-ffast-math" if tool =~ /^clang/ - args << arg - when "-Wno-deprecated-register" - # older gccs don't support these flags - args << arg unless tool =~ /^g..-4.[02]/ - when /^-Wl,-z,defs/ - # -Wl,-undefined,error is already the default - when /^-W[alp],/, /^-Wno-/ - args << arg - when /^-W.*/ - # prune warnings - when "-macosx_version_min", "-dylib_install_name" - args << "-Wl,#{arg},#{enum.next}" - when "-multiply_definedsuppress" - args << "-Wl,-multiply_defined,suppress" - when "-undefineddynamic_lookup" - args << "-Wl,-undefined,dynamic_lookup" - when /^-I(.+)?/ - # Support both "-Ifoo" (one argument) and "-I foo" (two arguments) - val = chuzzle($1) || enum.next - path = canonical_path(val) - args << "-I#{val}" if keep?(path) && @iset.add?(path) - when /^-L(.+)?/ - val = chuzzle($1) || enum.next - path = canonical_path(val) - args << "-L#{val}" if keep?(path) && @lset.add?(path) - else - args << arg - end - - args - end - - def keep?(path) - # Allow references to self - if formula_prefix && path.start_with?("#{formula_prefix}/") - true - # first two paths: reject references to Cellar or opt paths - # for unspecified dependencies - elsif path.start_with?(cellar) || path.start_with?(opt) - dep = path[keg_regex, 2] - dep && @deps.include?(dep) - else - path.start_with?(prefix, tmpdir) - end - end - - def cflags - args = [] - - return args unless refurbish_args? || configure? - - args << "-pipe" - args << "-w" unless configure? - args << "-#{ENV["HOMEBREW_OPTIMIZATION_LEVEL"]}" - args.concat(optflags) - args.concat(archflags) - args << "-std=#{@arg0}" if @arg0 =~ /c[89]9/ - args - end - - def cxxflags - args = cflags - args << "-std=c++11" if cxx11? - args << "-stdlib=libc++" if libcxx? - args << "-stdlib=libstdc++" if libstdcxx? - args - end - - def cppflags - path_flags("-isystem", isystem_paths) + path_flags("-I", include_paths) - end - - def ldflags - wl = "-Wl," unless mode == :ld - args = [] - args += ["#{wl}--dynamic-linker=#{dynamic_linker_path}"] if dynamic_linker_path - args << "-B#{@opt}/glibc/lib" unless mode == :ld - args += path_flags("-L", library_paths) - args += rpath_flags("#{wl}-rpath=", rpath_paths) - end - - def isystem_paths - path_split("HOMEBREW_ISYSTEM_PATHS") - end - - def include_paths - path_split("HOMEBREW_INCLUDE_PATHS") - end - - def library_paths - path_split("HOMEBREW_LIBRARY_PATHS") - end - - def rpath_paths - path_split("HOMEBREW_RPATH_PATHS") - end - - def dynamic_linker_path - chuzzle(ENV["HOMEBREW_DYNAMIC_LINKER"]) - end - - def configure? - # configure scripts generated with autoconf 2.61 or later export as_nl - ENV.key? "as_nl" - end - - def refurbish_args? - config.include?("O") - end - - def cxx11? - config.include?("x") - end - - def libcxx? - config.include?("g") - end - - def libstdcxx? - config.include?("h") - end - - def permit_arch_flags? - config.include?("K") - end - - def canonical_path(path) - path = Pathname.new(path) - path = path.realpath if path.exist? - path.to_s - end - - def path_flags(prefix, paths) - paths = paths.uniq.select { |path| File.directory?(path) } - paths.map! { |path| prefix + path } - end - - # Unlike path_flags, do not prune non-existant directories. - # formula.lib for example does not yet exist, but should not be pruned. - def rpath_flags(prefix, paths) - paths.uniq.map { |path| prefix + path } - end - - def path_split(key) - ENV.fetch(key) { "" }.split(File::PATH_SEPARATOR) - end - - def chuzzle(val) - return val if val.nil? - val = val.chomp - return val unless val.empty? - end -end - -def log(basename, argv, tool, args) - return unless ENV.key?("HOMEBREW_CC_LOG_PATH") - - adds = args - argv - dels = argv - args - - s = "" - s << "#{basename} called with: #{argv.join(" ")}\n" - s << "superenv removed: #{dels.join(" ")}\n" unless dels.empty? - s << "superenv added: #{adds.join(" ")}\n" unless adds.empty? - s << "superenv executed: #{tool} #{args.join(" ")}\n\n" - File.open("#{ENV["HOMEBREW_CC_LOG_PATH"]}.cc", "a+") { |f| f.write(s) } -end - -def remove_superbin_from_path(paths) - superbin = Pathname.new(__FILE__).dirname.realpath - paths.reject do |x| - path = Pathname.new(x) - path.directory? && path.realpath == superbin - end -end - -if __FILE__ == $PROGRAM_NAME - ##################################################################### sanity - - if (cc = ENV["HOMEBREW_CC"]).nil? || cc.empty? || cc == "cc" - # those values are not allowed - ENV["HOMEBREW_CC"] = "clang" - end - - ####################################################################### main - - dirname, basename = File.split($0) - - cmd = Cmd.new(basename, ARGV) - tool = cmd.tool - args = cmd.args - - log(basename, ARGV, tool, args) - - paths = ENV["PATH"].split(":") - paths = remove_superbin_from_path(paths) - paths.unshift "#{ENV["HOMEBREW_PREFIX"]}/bin" - ENV["PATH"] = paths.join(":") - args << { :close_others => false } - exec tool, *args -end diff --git a/Library/Homebrew/shims/linux/super/cc b/Library/Homebrew/shims/linux/super/cc new file mode 120000 index 0000000000..76ba8b5370 --- /dev/null +++ b/Library/Homebrew/shims/linux/super/cc @@ -0,0 +1 @@ +../../super/cc \ No newline at end of file diff --git a/Library/Homebrew/shims/super/cc b/Library/Homebrew/shims/super/cc index afe72156fb..3e71f3d11a 100755 --- a/Library/Homebrew/shims/super/cc +++ b/Library/Homebrew/shims/super/cc @@ -13,6 +13,14 @@ exec "$HOMEBREW_RUBY_PATH" -x "$0" "$@" require "pathname" require "set" +def mac? + RUBY_PLATFORM[/darwin/] +end + +def linux? + RUBY_PLATFORM[/linux/] +end + class Cmd attr_reader :config, :prefix, :cellar, :opt, :tmpdir, :sysroot, :deps attr_reader :archflags, :optflags, :keg_regex, :formula_prefix @@ -35,8 +43,10 @@ class Cmd end def mode - if @arg0 == "cpp" || @arg0 == "ld" - @arg0.to_sym + if @arg0 == "cpp" + :cpp + elsif ["ld", "ld.gold", "gold"].include? @arg0 + :ld elsif @args.include? "-c" if @arg0 =~ /(?:c|g|clang)\+\+/ :cxx @@ -59,6 +69,7 @@ class Cmd def tool @tool ||= case @arg0 when "ld" then "ld" + when "gold", "ld.gold" then "ld.gold" when "cpp" then "cpp" when /llvm_(clang(\+\+)?)/ "#{ENV["HOMEBREW_PREFIX"]}/opt/llvm/bin/#{$1}" @@ -190,9 +201,13 @@ class Cmd when "-undefineddynamic_lookup" args << "-Wl,-undefined,dynamic_lookup" when /^-isysroot/, /^--sysroot/ - sdk = enum.next - # We set the sysroot for macOS SDKs - args << "-isysroot" << sdk unless sdk.downcase.include? "osx" + if mac? + sdk = enum.next + # We set the sysroot for macOS SDKs + args << "-isysroot" << sdk unless sdk.downcase.include? "osx" + else + args << arg << enum.next + end when "-dylib" args << "-Wl,#{arg}" when /^-I(.+)?/ @@ -220,11 +235,15 @@ class Cmd elsif path.start_with?(cellar) || path.start_with?(opt) dep = path[keg_regex, 2] dep && @deps.include?(dep) - elsif path.start_with?(prefix) + elsif path.start_with?(prefix, tmpdir) + true + elsif path.start_with?("/opt/local", "/opt/boxen/homebrew", "/opt/X11", "/sw", "/usr/X11") + # ignore MacPorts, Boxen's Homebrew, X11, fink + false + elsif mac? true else - # ignore MacPorts, Boxen's Homebrew, X11, fink - !path.start_with?("/opt/local", "/opt/boxen/homebrew", "/opt/X11", "/sw", "/usr/X11") + false end end @@ -254,8 +273,7 @@ class Cmd path_flags("-isystem", isystem_paths) + path_flags("-I", include_paths) end - def ldflags - args = path_flags("-L", library_paths) + def ldflags_mac(args) case mode when :ld args << "-headerpad_max_install_names" @@ -267,6 +285,27 @@ class Cmd args end + def ldflags_linux(args) + unless mode == :ld + wl = "-Wl," + args << "-B#{@opt}/glibc/lib" + end + args += rpath_flags("#{wl}-rpath=", rpath_paths) + args += ["#{wl}--dynamic-linker=#{dynamic_linker_path}"] if dynamic_linker_path + args + end + + def ldflags + args = path_flags("-L", library_paths) + if mac? + ldflags_mac(args) + elsif linux? + ldflags_linux(args) + else + args + end + end + def isystem_paths path_split("HOMEBREW_ISYSTEM_PATHS") end @@ -279,6 +318,14 @@ class Cmd path_split("HOMEBREW_LIBRARY_PATHS") end + def rpath_paths + path_split("HOMEBREW_RPATH_PATHS") + end + + def dynamic_linker_path + chuzzle(ENV["HOMEBREW_DYNAMIC_LINKER"]) + end + def system_library_paths paths = ["#{sysroot}/usr/lib"] paths << "/usr/local/lib" unless sysroot || ENV["SDKROOT"] @@ -325,6 +372,12 @@ class Cmd paths.map! { |path| prefix + path } end + # Unlike path_flags, do not prune non-existant directories. + # formula.lib for example does not yet exist, but should not be pruned. + def rpath_flags(prefix, paths) + paths.uniq.map { |path| prefix + path } + end + def path_split(key) ENV.fetch(key) { "" }.split(File::PATH_SEPARATOR) end @@ -350,6 +403,14 @@ def log(basename, argv, tool, args) File.open("#{ENV["HOMEBREW_CC_LOG_PATH"]}.cc", "a+") { |f| f.write(s) } end +def remove_superbin_from_path(paths) + superbin = Pathname.new(__FILE__).dirname.realpath + paths.reject do |x| + path = Pathname.new(x) + path.directory? && path.realpath == superbin + end +end + if __FILE__ == $PROGRAM_NAME ##################################################################### sanity @@ -369,5 +430,13 @@ if __FILE__ == $PROGRAM_NAME log(basename, ARGV, tool, args) args << { :close_others => false } - exec "#{dirname}/xcrun", tool, *args + if mac? + exec "#{dirname}/xcrun", tool, *args + else + paths = ENV["PATH"].split(":") + paths = remove_superbin_from_path(paths) + paths.unshift "#{ENV["HOMEBREW_PREFIX"]}/bin" + ENV["PATH"] = paths.join(":") + exec tool, *args + end end