From e316cc9296079a212a72ab89c0c11e894b546ef9 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Mon, 25 Apr 2016 18:01:03 +0100 Subject: [PATCH] Make development tools code cross-platform. --- Library/Homebrew/compilers.rb | 4 +- Library/Homebrew/development_tools.rb | 80 +++++++++++++++++ Library/Homebrew/extend/ENV/shared.rb | 2 +- Library/Homebrew/extend/ENV/std.rb | 2 +- Library/Homebrew/extend/ENV/super.rb | 2 +- .../Homebrew/extend/os/development_tools.rb | 5 ++ .../extend/os/mac/development_tools.rb | 36 ++++++++ Library/Homebrew/os/mac.rb | 90 +------------------ Library/Homebrew/os/mac/xcode.rb | 2 +- Library/Homebrew/test/test_tab.rb | 2 +- 10 files changed, 132 insertions(+), 93 deletions(-) create mode 100644 Library/Homebrew/development_tools.rb create mode 100644 Library/Homebrew/extend/os/development_tools.rb create mode 100644 Library/Homebrew/extend/os/mac/development_tools.rb diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb index a04f75f6d1..896b8f363a 100644 --- a/Library/Homebrew/compilers.rb +++ b/Library/Homebrew/compilers.rb @@ -89,11 +89,11 @@ class CompilerSelector } def self.select_for(formula, compilers = self.compilers) - new(formula, MacOS, compilers).compiler + new(formula, DevelopmentTools, compilers).compiler end def self.compilers - COMPILER_PRIORITY.fetch(MacOS.default_compiler) + COMPILER_PRIORITY.fetch(DevelopmentTools.default_compiler) end attr_reader :formula, :failures, :versions, :compilers diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb new file mode 100644 index 0000000000..fd0d2f2630 --- /dev/null +++ b/Library/Homebrew/development_tools.rb @@ -0,0 +1,80 @@ +# @private +class DevelopmentTools + class << self + def locate(tool) + # Don't call tools (cc, make, strip, etc.) directly! + # Give the name of the binary you look for as a string to this method + # in order to get the full path back as a Pathname. + (@locate ||= {}).fetch(tool) do |key| + @locate[key] = if File.executable?(path = "/usr/bin/#{tool}") + Pathname.new path + # Homebrew GCCs most frequently; much faster to check this before xcrun + elsif (path = HOMEBREW_PREFIX/"bin/#{tool}").executable? + path + end + end + end + + def installed? + which("clang") || which("gcc") + end + + def default_cc + cc = DevelopmentTools.locate "cc" + cc.realpath.basename.to_s rescue nil + end + + def default_compiler + case default_cc + # if GCC 4.2 is installed, e.g. via Tigerbrew, prefer it + # over the system's GCC 4.0 + when /^gcc-4.0/ then gcc_42_build_version ? :gcc : :gcc_4_0 + when /^gcc/ then :gcc + when /^llvm/ then :llvm + else :clang + end + end + + def gcc_40_build_version + @gcc_40_build_version ||= + if (path = locate("gcc-4.0")) + `#{path} --version 2>/dev/null`[/build (\d{4,})/, 1].to_i + end + end + alias_method :gcc_4_0_build_version, :gcc_40_build_version + + def gcc_42_build_version + @gcc_42_build_version ||= + begin + gcc = locate("gcc-4.2") || HOMEBREW_PREFIX.join("opt/apple-gcc42/bin/gcc-4.2") + if gcc.exist? && !gcc.realpath.basename.to_s.start_with?("llvm") + `#{gcc} --version 2>/dev/null`[/build (\d{4,})/, 1].to_i + end + end + end + alias_method :gcc_build_version, :gcc_42_build_version + + def llvm_build_version + @llvm_build_version ||= + if (path = locate("llvm-gcc")) && !path.realpath.basename.to_s.start_with?("clang") + `#{path} --version`[/LLVM build (\d{4,})/, 1].to_i + end + end + + def clang_version + @clang_version ||= + if (path = locate("clang")) + `#{path} --version`[/(?:clang|LLVM) version (\d\.\d)/, 1] + end + end + + def clang_build_version + @clang_build_version ||= + if (path = locate("clang")) + `#{path} --version`[/clang-(\d{2,})/, 1].to_i + end + end + end +end + +require "extend/os/development_tools" diff --git a/Library/Homebrew/extend/ENV/shared.rb b/Library/Homebrew/extend/ENV/shared.rb index 2b5f51721d..eeba5bbf9b 100644 --- a/Library/Homebrew/extend/ENV/shared.rb +++ b/Library/Homebrew/extend/ENV/shared.rb @@ -164,7 +164,7 @@ module SharedEnvExtension elsif @formula CompilerSelector.select_for(@formula) else - MacOS.default_compiler + DevelopmentTools.default_compiler end end diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index ae9c3617ca..e5272cace3 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -121,7 +121,7 @@ module Stdenv # @private def determine_cc s = super - MacOS.locate(s) || Pathname.new(s) + DevelopmentTools.locate(s) || Pathname.new(s) end # @private diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index c3ae3362f9..7f335acb2d 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -63,7 +63,7 @@ module Superenv self["CMAKE_INCLUDE_PATH"] = determine_cmake_include_path self["CMAKE_LIBRARY_PATH"] = determine_cmake_library_path self["ACLOCAL_PATH"] = determine_aclocal_path - self["M4"] = MacOS.locate("m4") if deps.any? { |d| d.name == "autoconf" } + self["M4"] = DevelopmentTools.locate("m4") if deps.any? { |d| d.name == "autoconf" } self["HOMEBREW_ISYSTEM_PATHS"] = determine_isystem_paths self["HOMEBREW_INCLUDE_PATHS"] = determine_include_paths self["HOMEBREW_LIBRARY_PATHS"] = determine_library_paths diff --git a/Library/Homebrew/extend/os/development_tools.rb b/Library/Homebrew/extend/os/development_tools.rb new file mode 100644 index 0000000000..7b590dc8b6 --- /dev/null +++ b/Library/Homebrew/extend/os/development_tools.rb @@ -0,0 +1,5 @@ +require "development_tools" + +if OS.mac? + require "extend/os/mac/development_tools" +end diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb new file mode 100644 index 0000000000..648b3e2bda --- /dev/null +++ b/Library/Homebrew/extend/os/mac/development_tools.rb @@ -0,0 +1,36 @@ +# @private +class DevelopmentTools + class << self + alias_method :original_locate, :locate + def locate(tool) + (@locate ||= {}).fetch(tool) do |key| + @locate[key] = if (located_tool = original_locate(tool)) + located_tool + elsif MacOS.version > :tiger + path = Utils.popen_read("/usr/bin/xcrun", "-no-cache", "-find", tool).chomp + Pathname.new(path) if File.executable?(path) + end + end + end + + def default_compiler + case default_cc + # if GCC 4.2 is installed, e.g. via Tigerbrew, prefer it + # over the system's GCC 4.0 + when /^gcc-4.0/ then gcc_42_build_version ? :gcc : :gcc_4_0 + when /^gcc/ then :gcc + when /^llvm/ then :llvm + when "clang" then :clang + else + # guess :( + if Xcode.version >= "4.3" + :clang + elsif Xcode.version >= "4.2" + :llvm + else + :gcc + end + end + end + end +end diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index 98053f4ba5..31469dfddc 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -1,4 +1,5 @@ require "hardware" +require "development_tools" require "os/mac/version" require "os/mac/xcode" require "os/mac/xquartz" @@ -40,31 +41,13 @@ module OS version.to_sym end - def locate(tool) - # Don't call tools (cc, make, strip, etc.) directly! - # Give the name of the binary you look for as a string to this method - # in order to get the full path back as a Pathname. - (@locate ||= {}).fetch(tool) do |key| - @locate[key] = if File.executable?(path = "/usr/bin/#{tool}") - Pathname.new path - # Homebrew GCCs most frequently; much faster to check this before xcrun - elsif (path = HOMEBREW_PREFIX/"bin/#{tool}").executable? - path - # xcrun was introduced in Xcode 3 on Leopard - elsif MacOS.version > :tiger - path = Utils.popen_read("/usr/bin/xcrun", "-no-cache", "-find", tool).chomp - Pathname.new(path) if File.executable?(path) - end - end - end - # Locates a (working) copy of install_name_tool, guaranteed to function # whether the user has developer tools installed or not. def install_name_tool if (path = HOMEBREW_PREFIX/"opt/cctools/bin/install_name_tool").executable? path else - locate("install_name_tool") + DevelopmentTools.locate("install_name_tool") end end @@ -74,7 +57,7 @@ module OS if (path = HOMEBREW_PREFIX/"opt/cctools/bin/otool").executable? path else - locate("otool") + DevelopmentTools.locate("otool") end end @@ -126,75 +109,10 @@ module OS s.path unless s.nil? end - def default_cc - cc = locate "cc" - cc.realpath.basename.to_s rescue nil - end - - def default_compiler - case default_cc - # if GCC 4.2 is installed, e.g. via Tigerbrew, prefer it - # over the system's GCC 4.0 - when /^gcc-4.0/ then gcc_42_build_version ? :gcc : :gcc_4_0 - when /^gcc/ then :gcc - when /^llvm/ then :llvm - when "clang" then :clang - else - # guess :( - if Xcode.version >= "4.3" - :clang - elsif Xcode.version >= "4.2" - :llvm - else - :gcc - end - end - end - - def gcc_40_build_version - @gcc_40_build_version ||= - if (path = locate("gcc-4.0")) - `#{path} --version 2>/dev/null`[/build (\d{4,})/, 1].to_i - end - end - alias_method :gcc_4_0_build_version, :gcc_40_build_version - - def gcc_42_build_version - @gcc_42_build_version ||= - begin - gcc = MacOS.locate("gcc-4.2") || HOMEBREW_PREFIX.join("opt/apple-gcc42/bin/gcc-4.2") - if gcc.exist? && !gcc.realpath.basename.to_s.start_with?("llvm") - `#{gcc} --version 2>/dev/null`[/build (\d{4,})/, 1].to_i - end - end - end - alias_method :gcc_build_version, :gcc_42_build_version - - def llvm_build_version - @llvm_build_version ||= - if (path = locate("llvm-gcc")) && !path.realpath.basename.to_s.start_with?("clang") - `#{path} --version`[/LLVM build (\d{4,})/, 1].to_i - end - end - - def clang_version - @clang_version ||= - if (path = locate("clang")) - `#{path} --version`[/(?:clang|LLVM) version (\d\.\d)/, 1] - end - end - - def clang_build_version - @clang_build_version ||= - if (path = locate("clang")) - `#{path} --version`[/clang-(\d{2,})/, 1].to_i - end - end - def non_apple_gcc_version(cc) (@non_apple_gcc_version ||= {}).fetch(cc) do path = HOMEBREW_PREFIX.join("opt", "gcc", "bin", cc) - path = locate(cc) unless path.exist? + path = DevelopmentTools.locate(cc) unless path.exist? version = `#{path} --version`[/gcc(?:-\d(?:\.\d)? \(.+\))? (\d\.\d\.\d)/, 1] if path @non_apple_gcc_version[cc] = version end diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index fc27626557..de812ae8b8 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -120,7 +120,7 @@ module OS # https://github.com/Homebrew/brew/blob/master/share/doc/homebrew/Xcode.md "4.0" else - case (MacOS.clang_version.to_f * 10).to_i + case (DevelopmentTools.clang_version.to_f * 10).to_i when 0 then "dunno" when 1..14 then "3.2.2" when 15 then "3.2.4" diff --git a/Library/Homebrew/test/test_tab.rb b/Library/Homebrew/test/test_tab.rb index 91a766f04c..ce644b7c2a 100644 --- a/Library/Homebrew/test/test_tab.rb +++ b/Library/Homebrew/test/test_tab.rb @@ -32,7 +32,7 @@ class TabTests < Homebrew::TestCase assert_nil tab.tap assert_nil tab.time assert_nil tab.HEAD - assert_equal MacOS.default_compiler, tab.cxxstdlib.compiler + assert_equal DevelopmentTools.default_compiler, tab.cxxstdlib.compiler assert_nil tab.cxxstdlib.type end