From 04abc51d1f2c8b0ab35bfd340afe5414925b7ac8 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Fri, 2 Apr 2021 12:38:39 +0100 Subject: [PATCH] Cleanup use of CxxStdlib - remove usage on macOS as we don't care about it there - don't error out on incompatibility but still store stdlib on Linux - remove (now) unused methods --- Library/Homebrew/build.rb | 6 +-- Library/Homebrew/cxxstdlib.rb | 46 +------------------ .../Homebrew/extend/os/mac/keg_relocate.rb | 21 +-------- Library/Homebrew/formula_installer.rb | 8 ---- Library/Homebrew/test/cxxstdlib_spec.rb | 43 ----------------- 5 files changed, 5 insertions(+), 119 deletions(-) diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 7429e77423..655e0206c7 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -8,7 +8,6 @@ old_trap = trap("INT") { exit! 130 } require_relative "global" require "build_options" -require "cxxstdlib" require "keg" require "extend/ENV" require "debrew" @@ -174,7 +173,7 @@ class Build "#{formula.full_name} #{formula.build.used_options.sort.join(" ")}".strip formula.install - stdlibs = detect_stdlibs(ENV.compiler) + stdlibs = detect_stdlibs tab = Tab.create(formula, ENV.compiler, stdlibs.first) tab.write @@ -186,9 +185,8 @@ class Build end end - def detect_stdlibs(compiler) + def detect_stdlibs keg = Keg.new(formula.prefix) - CxxStdlib.check_compatibility(formula, deps, keg, compiler) # The stdlib recorded in the install receipt is used during dependency # compatibility checks, so we only care about the stdlib that libraries diff --git a/Library/Homebrew/cxxstdlib.rb b/Library/Homebrew/cxxstdlib.rb index 6fdf97353e..b595848a2a 100644 --- a/Library/Homebrew/cxxstdlib.rb +++ b/Library/Homebrew/cxxstdlib.rb @@ -22,52 +22,14 @@ class CxxStdlib def self.create(type, compiler) raise ArgumentError, "Invalid C++ stdlib type: #{type}" if type && [:libstdcxx, :libcxx].exclude?(type) - apple_compiler = !compiler.to_s.match?(GNU_GCC_REGEXP) - CxxStdlib.new(type, compiler, apple_compiler) - end - - def self.check_compatibility(formula, deps, keg, compiler) - return if formula.skip_cxxstdlib_check? - - stdlib = create(keg.detect_cxx_stdlibs.first, compiler) - - begin - stdlib.check_dependencies(formula, deps) - rescue CompatibilityError => e - opoo e.message - end + CxxStdlib.new(type, compiler) end attr_reader :type, :compiler - def initialize(type, compiler, apple_compiler) + def initialize(type, compiler) @type = type @compiler = compiler.to_sym - @apple_compiler = apple_compiler - end - - # If either package doesn't use C++, all is well. - # libstdc++ and libc++ aren't ever intercompatible. - # libstdc++ is compatible across Apple compilers, but - # not between Apple and GNU compilers, nor between GNU compiler versions. - def compatible_with?(other) - return true if type.nil? || other.type.nil? - - return false unless type == other.type - - apple_compiler? && other.apple_compiler? || - !other.apple_compiler? && compiler.to_s[4..6] == other.compiler.to_s[4..6] - end - - def check_dependencies(formula, deps) - deps.each do |dep| - # Software is unlikely to link against libraries from build-time deps, so - # it doesn't matter if they link against different C++ stdlibs. - next if dep.build? - - dep_stdlib = Tab.for_formula(dep.to_formula).cxxstdlib - raise CompatibilityError.new(formula, dep, dep_stdlib) unless compatible_with? dep_stdlib - end end def type_string @@ -78,8 +40,4 @@ class CxxStdlib def inspect "#<#{self.class.name}: #{compiler} #{type}>" end - - def apple_compiler? - @apple_compiler - end end diff --git a/Library/Homebrew/extend/os/mac/keg_relocate.rb b/Library/Homebrew/extend/os/mac/keg_relocate.rb index 604a494db7..86dc1258e8 100644 --- a/Library/Homebrew/extend/os/mac/keg_relocate.rb +++ b/Library/Homebrew/extend/os/mac/keg_relocate.rb @@ -16,7 +16,7 @@ class Keg end end - undef relocate_dynamic_linkage, detect_cxx_stdlibs + undef relocate_dynamic_linkage def relocate_dynamic_linkage(relocation) mach_o_files.each do |file| @@ -39,25 +39,6 @@ class Keg end end - # Detects the C++ dynamic libraries in-place, scanning the dynamic links - # of the files within the keg. - # Note that this doesn't attempt to distinguish between libstdc++ versions, - # for instance between Apple libstdc++ and GNU libstdc++. - def detect_cxx_stdlibs(options = {}) - skip_executables = options.fetch(:skip_executables, false) - results = Set.new - - mach_o_files.each do |file| - next if file.mach_o_executable? && skip_executables - - dylibs = file.dynamically_linked_libraries - results << :libcxx unless dylibs.grep(/libc\+\+.+\.dylib/).empty? - results << :libstdcxx unless dylibs.grep(/libstdc\+\+.+\.dylib/).empty? - end - - results.to_a - end - def fix_dynamic_linkage mach_o_files.each do |file| file.ensure_writable do diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 67fd981421..b194865a05 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -1,7 +1,6 @@ # typed: false # frozen_string_literal: true -require "cxxstdlib" require "formula" require "keg" require "tab" @@ -1137,13 +1136,6 @@ class FormulaInstaller skip_linkage = formula.bottle_specification.skip_relocation? keg.replace_placeholders_with_locations tab.changed_files, skip_linkage: skip_linkage - unless ignore_deps? - CxxStdlib.check_compatibility( - formula, formula.recursive_dependencies, - Keg.new(formula.prefix), tab.compiler - ) - end - # fill in missing/outdated parts of the tab # keep in sync with Tab#to_bottle_json tab.used_options = [] diff --git a/Library/Homebrew/test/cxxstdlib_spec.rb b/Library/Homebrew/test/cxxstdlib_spec.rb index e16af54ec3..9da0a32b29 100644 --- a/Library/Homebrew/test/cxxstdlib_spec.rb +++ b/Library/Homebrew/test/cxxstdlib_spec.rb @@ -6,50 +6,7 @@ require "cxxstdlib" describe CxxStdlib do let(:clang) { described_class.create(:libstdcxx, :clang) } - let(:gcc6) { described_class.create(:libstdcxx, "gcc-6") } - let(:gcc7) { described_class.create(:libstdcxx, "gcc-7") } let(:lcxx) { described_class.create(:libcxx, :clang) } - let(:purec) { described_class.create(nil, :clang) } - - describe "#compatible_with?" do - specify "compatibility with itself" do - expect(gcc7).to be_compatible_with(gcc7) - expect(clang).to be_compatible_with(clang) - end - - specify "Apple/GNU libstdcxx incompatibility" do - expect(clang).not_to be_compatible_with(gcc7) - expect(gcc7).not_to be_compatible_with(clang) - end - - specify "GNU cross-version incompatibility" do - expect(gcc6).not_to be_compatible_with(gcc7) - expect(gcc7).not_to be_compatible_with(gcc6) - end - - specify "libstdcxx and libcxx incompatibility" do - expect(clang).not_to be_compatible_with(lcxx) - expect(lcxx).not_to be_compatible_with(clang) - end - - specify "compatibility for non-cxx software" do - expect(purec).to be_compatible_with(clang) - expect(clang).to be_compatible_with(purec) - expect(purec).to be_compatible_with(purec) - expect(purec).to be_compatible_with(gcc7) - expect(gcc7).to be_compatible_with(purec) - end - end - - describe "#apple_compiler?" do - it "returns true for Apple compilers" do - expect(clang).to be_an_apple_compiler - end - - it "returns false for non-Apple compilers" do - expect(gcc7).not_to be_an_apple_compiler - end - end describe "#type_string" do specify "formatting" do