Preliminary macOS 15 (Sequoia) support

This commit is contained in:
Bo Anderson 2024-06-10 18:56:50 +01:00
parent 81fa3c4cc4
commit 7da94a8f01
No known key found for this signature in database
33 changed files with 564 additions and 187 deletions

View File

@ -111,7 +111,7 @@ GEM
rubocop (~> 1.40)
rubocop-sorbet (0.8.3)
rubocop (>= 0.90.0)
ruby-macho (4.0.1)
ruby-macho (4.1.0)
ruby-prof (1.7.0)
ruby-progressbar (1.13.0)
simplecov (0.22.0)

View File

@ -112,7 +112,7 @@ class LinkageChecker
# weakly loaded dylibs may not actually exist on disk, so skip them
# when checking for broken linkage
keg_files_dylibs[file] =
file.dynamically_linked_libraries(except: :LC_LOAD_WEAK_DYLIB)
file.dynamically_linked_libraries(except: :DYLIB_USE_WEAK_LINK)
end
end

View File

@ -19,6 +19,7 @@ class MacOSVersion < Version
# NOTE: When removing symbols here, ensure that they are added
# to `DEPRECATED_MACOS_VERSIONS` in `MacOSRequirement`.
SYMBOLS = {
sequoia: "15",
sonoma: "14",
ventura: "13",
monterey: "12",

View File

@ -86,7 +86,8 @@ module MachOShim
end
def dynamically_linked_libraries(except: :none, resolve_variable_references: true)
lcs = macho.dylib_load_commands.reject { |lc| lc.type == except }
lcs = macho.dylib_load_commands
lcs.reject! { |lc| lc.flag?(except) } if except != :none
names = lcs.map { |lc| lc.name.to_s }.uniq
names.map! { resolve_variable_name(_1) } if resolve_variable_references

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: expat
Version: 2.6.1
Description: expat XML parser
URL: https://libexpat.github.io/
Libs: -L${libdir} -lexpat
Libs.private:
Cflags:
Cflags.private: -DXML_STATIC

View File

@ -0,0 +1,42 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
# This should most probably benefit from getting a "Requires:" field added
# dynamically by configure.
#
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
supported_protocols="DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS IPFS IPNS LDAP LDAPS MQTT POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP"
supported_features="alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL threadsafe UnixSockets"
Name: libcurl
URL: https://curl.se/
Description: Library to transfer files with ftp, http, etc.
Version: 8.7.1
Libs: -L${libdir} -lcurl
Libs.private: -lldap -lz
Cflags:

View File

@ -0,0 +1,12 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libedit
Description: command line editor library provides generic line editing, history, and tokenization functions.
Version: 3.0
Requires:
Libs: -L${libdir} -ledit
Cflags: -I${includedir}/editline

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libexslt
Version: 0.8.20
Description: EXSLT Extension library
Requires: libxml-2.0, libxslt
Cflags:
Libs: -L${libdir} -lexslt
Libs.private:

View File

@ -0,0 +1,12 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
toolexeclibdir=${libdir}
includedir=${prefix}/include/ffi
Name: libffi
Description: Library supporting Foreign Function Interfaces
Version: 3.4-rc1
Libs: -L${toolexeclibdir} -lffi
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
modules=1
Name: libXML
Version: 2.9.13
Description: libXML library version2.
Requires:
Libs: -L${libdir} -lxml2
Libs.private: -lz -lpthread -licucore -lm
Cflags:

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libxslt
Version: 1.1.35
Description: XSLT library version 2.
Requires: libxml-2.0
Cflags:
Libs: -L${libdir} -lxslt
Libs.private:

View File

@ -0,0 +1,17 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
abi_version=5.4
major_version=6
version=6.0.20150808
Name: ncurses
Description: ncurses 6.0 library
Version: ${version}
URL: http://invisible-island.net/ncurses
Requires.private:
Libs: -L${libdir} -lncurses
Libs.private:
Cflags: -D_DARWIN_C_SOURCE

View File

@ -0,0 +1,17 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
abi_version=5.4
major_version=6
version=6.0.20150808
Name: ncursesw
Description: ncurses 6.0 library
Version: ${version}
URL: http://invisible-island.net/ncurses
Requires.private:
Libs: -L${libdir} -lncurses
Libs.private:
Cflags: -D_DARWIN_C_SOURCE

View File

@ -0,0 +1,12 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: SQLite
Description: SQL database engine
Version: 3.43.2
Libs: -L${libdir} -lsqlite3
Libs.private:
Cflags:

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
sharedlibdir=${libdir}
includedir=${prefix}/include/uuid
Name: uuid
Description: Universally unique id library
Version: 1.0
Requires:
Libs:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
homebrew_sdkroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
sharedlibdir=${libdir}
includedir=${prefix}/include
Name: zlib
Description: zlib compression library
Version: 1.2.12
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags:

View File

@ -15,9 +15,11 @@ module OS
# This may be a beta version for a beta macOS.
sig { params(macos: MacOSVersion).returns(String) }
def self.latest_version(macos: MacOS.version)
latest_stable = "15.1"
latest_stable = "15.4"
case macos
when "14", "13" then latest_stable
when "15" then "16.0"
when "14" then latest_stable
when "13" then "15.2"
when "12" then "14.2"
when "11" then "13.2.1"
when "10.15" then "12.4"
@ -40,6 +42,7 @@ module OS
sig { returns(String) }
def self.minimum_version
case MacOS.version
when "15" then "16.0"
when "14" then "15.0"
when "13" then "14.1"
when "12" then "13.1"
@ -253,8 +256,9 @@ module OS
when "13.0.0" then "13.2.1"
when "13.1.6" then "13.4.1"
when "14.0.0" then "14.2"
when "15.0.0" then "15.1"
else "14.3"
when "14.0.3" then "14.3.1"
when "16.0.0" then "16.0"
else "15.4"
end
end
@ -347,7 +351,9 @@ module OS
sig { returns(String) }
def self.latest_clang_version
case MacOS.version
when "14", "13" then "1500.1.0.2.5"
when "15" then "1600.0.20.10"
when "14" then "1500.3.9.4"
when "13" then "1500.1.0.2.5"
when "12" then "1400.0.29.202"
when "11" then "1300.0.29.30"
when "10.15" then "1200.0.32.29"
@ -364,6 +370,7 @@ module OS
sig { returns(String) }
def self.minimum_version
case MacOS.version
when "15" then "16.0.0"
when "14" then "15.0.0"
when "13" then "14.0.0"
when "12" then "13.0.0"

View File

@ -0,0 +1 @@
testball_bottle-0.1.yosemite.bottle.tar.gz

View File

@ -0,0 +1 @@
testball_bottle-0.1.yosemite.bottle.tar.gz

View File

@ -101,7 +101,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec_rails-2.29.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-2.31.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.8.3/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-macho-4.0.1/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-macho-4.1.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/ruby-prof-1.7.0")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-prof-1.7.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-html-0.12.3/lib")

View File

@ -16,7 +16,7 @@ require_relative "macho/tools"
# The primary namespace for ruby-macho.
module MachO
# release version
VERSION = "4.0.1"
VERSION = "4.1.0"
# Opens the given filename as a MachOFile or FatFile, depending on its magic.
# @param filename [String] the file being opened

View File

@ -65,6 +65,7 @@ module MachO
(LC_REQ_DYLD | 0x33) => :LC_DYLD_EXPORTS_TRIE,
(LC_REQ_DYLD | 0x34) => :LC_DYLD_CHAINED_FIXUPS,
(LC_REQ_DYLD | 0x35) => :LC_FILESET_ENTRY,
0x36 => :LC_ATOM_INFO,
}.freeze
# association of symbol representations to load command constants
@ -110,7 +111,7 @@ module MachO
# "reserved for internal use only", no public struct
:LC_PREPAGE => "LoadCommand",
:LC_DYSYMTAB => "DysymtabCommand",
:LC_LOAD_DYLIB => "DylibCommand",
:LC_LOAD_DYLIB => "DylibUseCommand",
:LC_ID_DYLIB => "DylibCommand",
:LC_LOAD_DYLINKER => "DylinkerCommand",
:LC_ID_DYLINKER => "DylinkerCommand",
@ -122,7 +123,7 @@ module MachO
:LC_SUB_LIBRARY => "SubLibraryCommand",
:LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
:LC_PREBIND_CKSUM => "PrebindCksumCommand",
:LC_LOAD_WEAK_DYLIB => "DylibCommand",
:LC_LOAD_WEAK_DYLIB => "DylibUseCommand",
:LC_SEGMENT_64 => "SegmentCommand64",
:LC_ROUTINES_64 => "RoutinesCommand64",
:LC_UUID => "UUIDCommand",
@ -153,6 +154,7 @@ module MachO
:LC_DYLD_EXPORTS_TRIE => "LinkeditDataCommand",
:LC_DYLD_CHAINED_FIXUPS => "LinkeditDataCommand",
:LC_FILESET_ENTRY => "FilesetEntryCommand",
:LC_ATOM_INFO => "LinkeditDataCommand",
}.freeze
# association of segment name symbols to names
@ -193,6 +195,20 @@ module MachO
:SG_READ_ONLY => 0x10,
}.freeze
# association of dylib use flag symbols to values
# @api private
DYLIB_USE_FLAGS = {
:DYLIB_USE_WEAK_LINK => 0x1,
:DYLIB_USE_REEXPORT => 0x2,
:DYLIB_USE_UPWARD => 0x4,
:DYLIB_USE_DELAYED_INIT => 0x8,
}.freeze
# the marker used to denote a newer style dylib use command.
# the value is the timestamp 24 January 1984 18:12:16
# @api private
DYLIB_USE_MARKER = 0x1a741800
# The top-level Mach-O load command structure.
#
# This is the most generic load command -- only the type ID and size are
@ -231,6 +247,13 @@ module MachO
# cmd will be filled in, view and cmdsize will be left unpopulated
klass_arity = klass.min_args - 3
# macOS 15 introduces a new dylib load command that adds a flags field to the end.
# It uses the same commands with it dynamically being created if the dylib has a flags field
if klass == DylibUseCommand && (args[1] != DYLIB_USE_MARKER || args.size <= DylibCommand.min_args - 3)
klass = DylibCommand
klass_arity = klass.min_args - 3
end
raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity > args.size
klass.new(nil, cmd, nil, *args)
@ -526,6 +549,23 @@ module MachO
# @return [Integer] the library's compatibility version number
field :compatibility_version, :uint32
# @example
# puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
# @param flag [Symbol] a dylib use command flag symbol
# @return [Boolean] true if `flag` applies to this dylib command
def flag?(flag)
case cmd
when LOAD_COMMAND_CONSTANTS[:LC_LOAD_WEAK_DYLIB]
flag == :DYLIB_USE_WEAK_LINK
when LOAD_COMMAND_CONSTANTS[:LC_REEXPORT_DYLIB]
flag == :DYLIB_USE_REEXPORT
when LOAD_COMMAND_CONSTANTS[:LC_LOAD_UPWARD_DYLIB]
flag == :DYLIB_USE_UPWARD
else
false
end
end
# @param context [SerializationContext]
# the context
# @return [String] the serialized fields of the load command
@ -551,6 +591,65 @@ module MachO
end
end
# The newer format of load command representing some aspect of shared libraries,
# depending on filetype. Corresponds to LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB.
class DylibUseCommand < DylibCommand
# @return [Integer] any flags associated with this dylib use command
field :flags, :uint32
alias marker timestamp
# Instantiates a new DylibCommand or DylibUseCommand.
# macOS 15 and later use a new format for dylib commands (DylibUseCommand),
# which is determined based on a special timestamp and the name offset.
# @param view [MachO::MachOView] the load command's raw view
# @return [DylibCommand] the new dylib load command
# @api private
def self.new_from_bin(view)
dylib_command = DylibCommand.new_from_bin(view)
if dylib_command.timestamp == DYLIB_USE_MARKER &&
dylib_command.name.to_i == DylibUseCommand.bytesize
super(view)
else
dylib_command
end
end
# @example
# puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
# @param flag [Symbol] a dylib use command flag symbol
# @return [Boolean] true if `flag` applies to this dylib command
def flag?(flag)
flag = DYLIB_USE_FLAGS[flag]
return false if flag.nil?
flags & flag == flag
end
# @param context [SerializationContext]
# the context
# @return [String] the serialized fields of the load command
# @api private
def serialize(context)
format = Utils.specialize_format(self.class.format, context.endianness)
string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
context.alignment,
:name => name.to_s)
cmdsize = self.class.bytesize + string_payload.bytesize
[cmd, cmdsize, string_offsets[:name], marker, current_version,
compatibility_version, flags].pack(format) + string_payload
end
# @return [Hash] a hash representation of this {DylibUseCommand}
def to_h
{
"flags" => flags,
}.merge super
end
end
# A load command representing some aspect of the dynamic linker, depending
# on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
# LC_DYLD_ENVIRONMENT.
@ -958,7 +1057,7 @@ module MachO
# the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE,
# LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
# LC_DYLIB_CODE_SIGN_DRS, LC_LINKER_OPTIMIZATION_HINT, LC_DYLD_EXPORTS_TRIE,
# or LC_DYLD_CHAINED_FIXUPS.
# LC_DYLD_CHAINED_FIXUPS, or LC_ATOM_INFO.
class LinkeditDataCommand < LoadCommand
# @return [Integer] offset to the data in the __LINKEDIT segment
field :dataoff, :uint32