Skip to content

Add support for maccatalyst #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
BUILD_NUMBER: ${{ steps.build-vars.outputs.BUILD_NUMBER }}
strategy:
matrix:
target: [ "iOS", "tvOS", "watchOS" ]
target: [ "iOS", "tvOS", "watchOS", "MacCatalyst" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the release workflow - it doesn't address the CI workflow that I added a couple of days ago to make it possible to test this PR. You may need to merge with main to get that update.

steps:
- name: Checkout
uses: actions/[email protected]
Expand Down
27 changes: 21 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,38 @@
# - iOS - build everything for iOS
# - tvOS - build everything for tvOS
# - watchOS - build everything for watchOS
# - MacCatalyst - build everything for MacCatalyst
# - BZip2 - build BZip2 for all platforms
# - BZip2-iOS - build BZip2 for iOS
# - BZip2-tvOS - build BZip2 for tvOS
# - BZip2-watchOS - build BZip2 for watchOS
# - BZip2-MacCatalyst - build BZip2 for MacCatalyst
# - XZ - build XZ for all platforms
# - XZ-iOS - build XZ for iOS
# - XZ-tvOS - build XZ for tvOS
# - XZ-watchOS - build XZ for watchOS
# - XZ-MacCatalyst - build XZ for MacCatalyst
# - OpenSSL - build OpenSSL for all platforms
# - OpenSSL-iOS - build OpenSSL for iOS
# - OpenSSL-tvOS - build OpenSSL for tvOS
# - OpenSSL-watchOS - build OpenSSL for watchOS
# - OpenSSL-MacCatalyst - build OpenSSL for MacCatalyst
# - mpdecimal - build mpdecimal for all platforms
# - mpdecimal-iOS - build mpdecimal for iOS
# - mpdecimal-tvOS - build mpdecimal for tvOS
# - mpdecimal-watchOS - build mpdecimal for watchOS
# - mpdecimal-MacCatalyst - build mpdecimal for MacCatalyst
# - libFFI-iOS - build libFFI for iOS
# - libFFI-tvOS - build libFFI for tvOS
# - libFFI-watchOS - build libFFI for watchOS
# - libFFI-MacCatalyst - build libFFI for MacCatalyst

# Current directory
PROJECT_DIR=$(shell pwd)

# Supported OS and products
PRODUCTS=BZip2 XZ OpenSSL libFFI
OS_LIST=iOS tvOS watchOS
OS_LIST=iOS tvOS watchOS MacCatalyst

# The versions to compile by default.
# In practice, these should be
Expand Down Expand Up @@ -61,6 +67,11 @@ TARGETS-iOS=iphonesimulator.x86_64 iphonesimulator.arm64 iphoneos.arm64
VERSION_MIN-iOS=13.0
CFLAGS-iOS=-mios-version-min=$(VERSION_MIN-iOS)

# MacCatalyst targets
TARGETS-MacCatalyst=maccatalyst.x86_64 maccatalyst.arm64
VERSION_MIN-MacCatalyst=14.2
CFLAGS-MacCatalyst=-mios-version-min=$(VERSION_MIN-MacCatalyst)

# tvOS targets
TARGETS-tvOS=appletvsimulator.x86_64 appletvsimulator.arm64 appletvos.arm64
VERSION_MIN-tvOS=9.0
Expand Down Expand Up @@ -168,13 +179,15 @@ os=$2
OS_LOWER-$(target)=$(shell echo $(os) | tr '[:upper:]' '[:lower:]')

# $(target) can be broken up into is composed of $(SDK).$(ARCH)
SDK-$(target)=$$(basename $(target))
SDK-$(target)=$$(subst maccatalyst,macosx,$$(basename $(target)))
ARCH-$(target)=$$(subst .,,$$(suffix $(target)))

ifeq ($$(findstring simulator,$$(SDK-$(target))),)
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))
else
ifneq ($$(findstring simulator,$$(SDK-$(target))),)
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))-simulator
else ifneq ($$(findstring maccatalyst,$$(target)),)
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-ios$$(VERSION_MIN-$(os))-macabi
else
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))
endif

SDK_ROOT-$(target)=$$(shell xcrun --sdk $$(SDK-$(target)) --show-sdk-path)
Expand Down Expand Up @@ -550,9 +563,11 @@ $$(LIBFFI_SRCDIR-$(os))/darwin_common/include/ffi.h: downloads/libffi-$(LIBFFI_V
@echo ">>> Unpack and configure libFFI sources on $(os)"
mkdir -p $$(LIBFFI_SRCDIR-$(os))
tar zxf $$< --strip-components 1 -C $$(LIBFFI_SRCDIR-$(os))
# Patch the source to add support for maccatalyst/remove i386+armv7
cd $$(LIBFFI_SRCDIR-$(os)) && patch -p1 < $(PROJECT_DIR)/patch/libffi.patch
# Configure the build
cd $$(LIBFFI_SRCDIR-$(os)) && \
python3 generate-darwin-source-and-headers.py --only-$(shell echo $(os) | tr '[:upper:]' '[:lower:]') \
python3 generate-darwin-source-and-headers.py --only-$(shell echo $(os) | tr '[:upper:]' '[:lower:]') --disable-i386 --disable-armv7 \
2>&1 | tee -a ../libffi-$(LIBFFI_VERSION).config.log

###########################################################################
Expand Down
174 changes: 174 additions & 0 deletions patch/libffi.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
diff -Naur libffi-3.4.7-orig/config.sub libffi-3.4.7/config.sub
--- libffi-3.4.7-orig/config.sub 2024-12-13 10:38:19
+++ libffi-3.4.7/config.sub 2025-03-11 19:17:04
@@ -1768,7 +1768,7 @@
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* | ironclad* )
+ | fiwix* | mlibc* | cos* | mbr* | ironclad* | macabi)
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1864,8 +1864,8 @@
;;
os2-emx-)
;;
- ios*-simulator* | tvos*-simulator* | watchos*-simulator*)
- ;;
+ ios*-simulator* | tvos*-simulator* | watchos*-simulator* | ios*macabi*)
+ ;;
*-eabi*- | *-gnueabi*-)
;;
none--*)
diff -Naur libffi-3.4.7-orig/generate-darwin-source-and-headers.py libffi-3.4.7/generate-darwin-source-and-headers.py
--- libffi-3.4.7-orig/generate-darwin-source-and-headers.py 2024-06-01 18:42:02
+++ libffi-3.4.7/generate-darwin-source-and-headers.py 2025-03-09 14:29:38
@@ -8,7 +8,7 @@


class Platform(object):
- pass
+ abi = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the usage in this PR - what's the difference between the sdk and the abi? Why can't MacCatalyst builds be referenced as sdk="macabi"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I posted a comment above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... where is this comment? I'm not sure I follow what you're referring to.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macosx is the sdk and the macabi instructs the compiler to use the Mac Catalyst ABI. It allows the iOS(iPad) version of the app to run on Mac. The Mac Catalyst version only supports the iOS APIs (no access to the MacOSX APIs) and is therefore closely aligned with iOS and for all intents and purposes behaves as such.

The purpose of Mac Catalyst is to allow taking an iPad app and using all the iPad apis in a Mac app.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what Mac Catalyst is conceptually - I'm asking why it's necessary to separate sdk and abi in this configuration. What functional purpose is met by adding an entirely new configuration flag? It's a flag that is only used in the macabi situation, and is literally blank everywhere else. It's mutually exclusive with sdk="iphoneos". You're not making any other use of abi as a logic differentiator... so why make the distinction? Or, if you do want to keep the two separate - why isn't that separation followed through to the rest of the SDK/ABI handling (i.e., every platform has an SDK and an ABI - so why not define them an exploit that to simplify other logic)?



class i386_platform(Platform):
@@ -153,7 +153,22 @@
arch = 'arm64_32'
version_min = '-mwatchos-version-min=4.0'

+class macosx_x86_64_platform(x86_64_platform):
+ target = 'x86_64-apple-ios-macabi'
+ directory = 'darwin_maccatalyst'
+ sdk = 'macosx'
+ version_min = '-mios-version-min=14.2'
+ abi = 'macabi'

+
+class macosx_arm64_platform(arm64_platform):
+ target = 'arm64-apple-ios-macabi'
+ directory = 'darwin_maccatalyst'
+ sdk = 'macosx'
+ version_min = '-mios-version-min=14.2'
+ abi = 'macabi'
+
+
def mkdir_p(path):
try:
os.makedirs(path)
@@ -219,7 +234,7 @@
"../configure",
f"--host={platform.target}",
] + (
- [] if platform.sdk == "macosx" else [f"--build={os.uname().machine}-apple-darwin"]
+ [] if platform.sdk == "macosx" and platform.abi != "macabi" else [f"--build={os.uname().machine}-apple-darwin"]
),
env=env
)
@@ -243,16 +258,24 @@
generate_ios=True,
generate_tvos=True,
generate_watchos=True,
+ generate_maccatalyst=True,
+ enable_i386=True,
+ enable_armv7=True,
):
copy_files('src', 'darwin_common/src', pattern='*.c')
copy_files('include', 'darwin_common/include', pattern='*.h')

if generate_ios:
- copy_src_platform_files(ios_simulator_i386_platform)
+ if enable_i386:
+ copy_src_platform_files(ios_simulator_i386_platform)
copy_src_platform_files(ios_simulator_x86_64_platform)
copy_src_platform_files(ios_simulator_arm64_platform)
- copy_src_platform_files(ios_device_armv7_platform)
+ if enable_armv7:
+ copy_src_platform_files(ios_device_armv7_platform)
copy_src_platform_files(ios_device_arm64_platform)
+ if generate_maccatalyst:
+ copy_src_platform_files(macosx_x86_64_platform)
+ copy_src_platform_files(macosx_arm64_platform)
if generate_osx:
copy_src_platform_files(desktop_x86_64_platform)
copy_src_platform_files(desktop_arm64_platform)
@@ -261,20 +284,27 @@
copy_src_platform_files(tvos_simulator_arm64_platform)
copy_src_platform_files(tvos_device_arm64_platform)
if generate_watchos:
- copy_src_platform_files(watchos_simulator_i386_platform)
+ if enable_i386:
+ copy_src_platform_files(watchos_simulator_i386_platform)
copy_src_platform_files(watchos_simulator_x86_64_platform)
copy_src_platform_files(watchos_simulator_arm64_platform)
- copy_src_platform_files(watchos_device_armv7k_platform)
+ if enable_armv7:
+ copy_src_platform_files(watchos_device_armv7k_platform)
copy_src_platform_files(watchos_device_arm64_32_platform)

platform_headers = collections.defaultdict(set)

if generate_ios:
- build_target(ios_simulator_i386_platform, platform_headers)
+ if enable_i386:
+ build_target(ios_simulator_i386_platform, platform_headers)
build_target(ios_simulator_x86_64_platform, platform_headers)
build_target(ios_simulator_arm64_platform, platform_headers)
- build_target(ios_device_armv7_platform, platform_headers)
+ if enable_armv7:
+ build_target(ios_device_armv7_platform, platform_headers)
build_target(ios_device_arm64_platform, platform_headers)
+ if generate_maccatalyst:
+ build_target(macosx_x86_64_platform, platform_headers)
+ build_target(macosx_arm64_platform, platform_headers)
if generate_osx:
build_target(desktop_x86_64_platform, platform_headers)
build_target(desktop_arm64_platform, platform_headers)
@@ -283,10 +313,12 @@
build_target(tvos_simulator_arm64_platform, platform_headers)
build_target(tvos_device_arm64_platform, platform_headers)
if generate_watchos:
- build_target(watchos_simulator_i386_platform, platform_headers)
+ if enable_i386:
+ build_target(watchos_simulator_i386_platform, platform_headers)
build_target(watchos_simulator_x86_64_platform, platform_headers)
build_target(watchos_simulator_arm64_platform, platform_headers)
- build_target(watchos_device_armv7k_platform, platform_headers)
+ if enable_armv7:
+ build_target(watchos_device_armv7k_platform, platform_headers)
build_target(watchos_device_arm64_32_platform, platform_headers)

mkdir_p('darwin_common/include')
@@ -298,15 +330,24 @@

if __name__ == '__main__':
parser = argparse.ArgumentParser()
- parser.add_argument('--only-ios', action='store_true', default=False)
- parser.add_argument('--only-osx', action='store_true', default=False)
- parser.add_argument('--only-tvos', action='store_true', default=False)
- parser.add_argument('--only-watchos', action='store_true', default=False)
+ only_group = parser.add_mutually_exclusive_group()
+ # Enforce only one of these options to be specified, default is all
+ only_group.add_argument('--only-ios', action='store_true', default=False)
+ only_group.add_argument('--only-osx', action='store_true', default=False)
+ only_group.add_argument('--only-tvos', action='store_true', default=False)
+ only_group.add_argument('--only-watchos', action='store_true', default=False)
+ only_group.add_argument('--only-maccatalyst', action='store_true', default=False)
+ parser.add_argument('--disable-i386', action='store_true', default=False)
+ parser.add_argument('--disable-armv7', action='store_true', default=False)
args = parser.parse_args()

+ enable_all = not any((args.only_ios, args.only_osx, args.only_tvos, args.only_watchos, args.only_maccatalyst))
generate_source_and_headers(
- generate_osx=not args.only_ios and not args.only_tvos and not args.only_watchos,
- generate_ios=not args.only_osx and not args.only_tvos and not args.only_watchos,
- generate_tvos=not args.only_ios and not args.only_osx and not args.only_watchos,
- generate_watchos=not args.only_ios and not args.only_osx and not args.only_tvos,
+ generate_osx=enable_all or args.only_osx,
+ generate_ios=enable_all or args.only_ios,
+ generate_tvos=enable_all or args.only_tvos,
+ generate_watchos=enable_all or args.only_watchos,
+ generate_maccatalyst=enable_all or args.only_maccatalyst,
+ enable_i386=not args.disable_i386,
+ enable_armv7=not args.disable_armv7,
)
17 changes: 13 additions & 4 deletions patch/mpdecimal.patch
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
diff -ur mpdecimal-4.0.0-orig/config.sub mpdecimal-4.0.0/config.sub
--- mpdecimal-4.0.0-orig/config.sub 2024-01-10 08:25:00
+++ mpdecimal-4.0.0/config.sub 2024-07-24 13:16:35
diff -Naur --mi mpdecimal-4.0.0-orig/config.sub mpdecimal-4.0.0/config.sub
--- mpdecimal-4.0.0-orig/config.sub 2024-01-10 00:25:00
+++ mpdecimal-4.0.0/config.sub 2025-03-11 19:35:50
@@ -1127,7 +1127,7 @@
xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
Expand All @@ -10,12 +10,21 @@ diff -ur mpdecimal-4.0.0-orig/config.sub mpdecimal-4.0.0/config.sub
cpu=aarch64
;;

@@ -1736,7 +1736,7 @@
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* )
+ | fiwix* | mlibc* | cos* | mbr* | macabi )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1792,6 +1792,8 @@
os2-emx)
;;
*-eabi* | *-gnueabi*)
+ ;;
+ ios*-simulator | tvos*-simulator | watchos*-simulator)
+ ios*-simulator | tvos*-simulator | watchos*-simulator | ios*-macabi)
;;
none-coff* | none-elf*)
# None (no kernel, i.e. freestanding / bare metal),
23 changes: 16 additions & 7 deletions patch/xz.patch
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
diff -ru xz-5.4.7-orig/build-aux/config.sub xz-5.4.7/build-aux/config.sub
--- xz-5.4.7-orig/build-aux/config.sub 2024-05-29 23:13:51
+++ xz-5.4.7/build-aux/config.sub 2024-07-24 14:20:00
@@ -1127,7 +1127,7 @@
--- xz-5.6.4-orig/build-aux/config.sub 2025-01-23 09:58:05
+++ xz-5.6.4/build-aux/config.sub 2025-03-09 20:15:18
@@ -1194,7 +1194,7 @@
xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
Expand All @@ -10,12 +9,22 @@ diff -ru xz-5.4.7-orig/build-aux/config.sub xz-5.4.7/build-aux/config.sub
cpu=aarch64
;;

@@ -1865,6 +1865,8 @@
os2-emx-)
@@ -2149,7 +2149,8 @@
| xenix* \
| xray* \
| zephyr* \
- | zvmoe* )
+ | zvmoe* \
+ | macabi )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -2248,6 +2249,8 @@
rtmk-nova-)
;;
*-eabi*- | *-gnueabi*-)
+ ;;
+ ios*-simulator- | tvos*-simulator- | watchos*-simulator- )
+ ios*-simulator- | tvos*-simulator- | watchos*-simulator- | ios*-macabi-)
;;
none--*)
# None (no kernel, i.e. freestanding / bare metal),