Module: OS::Mac::FormulaCellarChecks Private

Extended by:
T::Helpers
Included in:
FormulaCellarChecks
Defined in:
extend/os/mac/formula_cellar_checks.rb

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Constant Summary collapse

MACOS_LIB_EXTENSIONS =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

%w[.dylib .framework].freeze

Instance Method Summary collapse

Instance Method Details

#audit_installedvoid

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



129
130
131
132
133
134
135
136
# File 'extend/os/mac/formula_cellar_checks.rb', line 129

def audit_installed
  super
  problem_if_output(check_shadowed_headers)
  problem_if_output(check_openssl_links)
  problem_if_output(check_python_framework_links(formula.lib))
  check_linkage
  problem_if_output(check_flat_namespace(formula))
end

#check_flat_namespace(formula) ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'extend/os/mac/formula_cellar_checks.rb', line 103

def check_flat_namespace(formula)
  return unless formula.prefix.directory?
  return if formula.tap&.audit_exception(:flat_namespace_allowlist, formula.name)

  keg = ::Keg.new(formula.prefix)
  flat_namespace_files = keg.mach_o_files.reject do |file|
    next true unless file.dylib?

    macho = MachO.open(file)
    if MachO::Utils.fat_magic?(macho.magic)
      macho.machos.map(&:header).all? { |h| h.flag? :MH_TWOLEVEL }
    else
      macho.header.flag? :MH_TWOLEVEL
    end
  end
  return if flat_namespace_files.empty?

  <<~EOS
    Libraries were compiled with a flat namespace.
    This can cause linker errors due to name collisions and
    is often due to a bug in detecting the macOS version.
      #{flat_namespace_files * "\n  "}
  EOS
end

#check_linkagevoid

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'extend/os/mac/formula_cellar_checks.rb', line 76

def check_linkage
  return unless formula.prefix.directory?

  keg = ::Keg.new(formula.prefix)

  CacheStoreDatabase.use(:linkage) do |db|
    checker = ::LinkageChecker.new(keg, formula, cache_db: db)
    next unless checker.broken_library_linkage?

    output = <<~EOS
      #{formula} has broken dynamic library links:
        #{checker.display_test_output}
    EOS

    tab = keg.tab
    if tab.poured_from_bottle
      output += <<~EOS
        Rebuild this from source with:
          brew reinstall --build-from-source #{formula}
        If that's successful, file an issue#{formula.tap ? " here:\n  #{formula.tap.issues_url}" : "."}
      EOS
    end
    problem_if_output output
  end
end

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'extend/os/mac/formula_cellar_checks.rb', line 38

def check_openssl_links
  return unless formula.prefix.directory?

  keg = ::Keg.new(formula.prefix)
  system_openssl = keg.mach_o_files.select do |obj|
    dlls = obj.dynamically_linked_libraries
    dlls.any? { |dll| %r{/usr/lib/lib(crypto|ssl|tls)\..*dylib}.match? dll }
  end
  return if system_openssl.empty?

  <<~EOS
    object files were linked against system openssl
    These object files were linked against the deprecated system OpenSSL or
    the system's private LibreSSL.
    Adding `depends_on "openssl"` to the formula may help.
      #{system_openssl * "\n  "}
  EOS
end

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'extend/os/mac/formula_cellar_checks.rb', line 58

def check_python_framework_links(lib)
  python_modules = Pathname.glob lib/"python*/site-packages/**/*.so"
  framework_links = python_modules.select do |obj|
    dlls = obj.dynamically_linked_libraries
    dlls.any? { |dll| dll.include?("Python.framework") }
  end
  return if framework_links.empty?

  <<~EOS
    python modules have explicit framework links
    These python extension modules were linked directly to a Python
    framework binary. They should be linked with -undefined dynamic_lookup
    instead of -lpython or -framework Python.
      #{framework_links * "\n  "}
  EOS
end

#check_shadowed_headersString?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'extend/os/mac/formula_cellar_checks.rb', line 16

def check_shadowed_headers
  return if ["libtool", "subversion", "berkeley-db"].any? do |formula_name|
    formula.name.start_with?(formula_name)
  end

  return if formula.name.match?(Version.formula_optionally_versioned_regex(:php))
  return if formula.keg_only? || !formula.include.directory?

  files  = relative_glob(formula.include, "**/*.h")
  files &= relative_glob("#{MacOS.sdk_path}/usr/include", "**/*.h")
  files.map! { |p| File.join(formula.include, p) }

  return if files.empty?

  <<~EOS
    Header files that shadow system header files were installed to "#{formula.include}"
    The offending files are:
      #{files * "\n  "}
  EOS
end

#valid_library_extension?(filename) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:

  • (Boolean)


141
142
143
# File 'extend/os/mac/formula_cellar_checks.rb', line 141

def valid_library_extension?(filename)
  super || MACOS_LIB_EXTENSIONS.include?(filename.extname)
end