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
This commit is contained in:
parent
f266acff2d
commit
04abc51d1f
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 = []
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user