-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
gh-114099: Add configure/Makefile changes to support iOS builds. #115063
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
Conversation
|
My gut feeling says we want to keep the watchOS and tvOS changes outside for now1, if that's ok with you :) cc. @ned-deily, who might have opinions on this. There are some configure changes that might be split out into separate changes (introducing the Footnotes
|
We did have some discussions about this at the Brno sprint. After a quick look through, I don't have a strong feeling about it. But, assuming the end goal is to support all of the platforms (at some level) and since the work is already done in the PR, it might be best to bite the bullet now and get it all in, rather than making extra work later. Perhaps @ronaldoussoren has an opinion on this. |
Yep. I would still like to consider to keep tvOS/watchOS out for this PR, for the sake of the review (not a hard requirement from me though, so feel free to give this suggestion a thumbs down 😄) |
|
I'll take a closer look in the morning, but I think it might be possible to separate out:
The downside to this sort of split is that it won't necessarily be obvious why some of the refactoring from an early step is needed until later step lands. However, the individual patches will definitely be smaller, so maybe with some explanatory notes (and reference to this PR as a "full" version), it can work; and it would let the tvOS/watchOS portions be their own entity. Alternatively, I could just purge the watchOS and tvOS portions of this patch (and submit them separately). That will make this PR smaller; my counterargument would be that everywhere this PR adds tvOS/watchOS, it's essentially 2 near-identical clauses in the same case statement where iOS appears, which is context you lose (or is harder to see) is a separate PR. @ned-deily @erlend-aasland Do either of these sound worthwhile alternative approaches? |
Does this mean "the build won't complete", or "the build completes but the outputs can't be run"? And is the answer to these questions different between iOS, watchOS and tvOS? |
The build will complete, but it won't be usable/runnable. The situation will be the same on all three new platforms. Apologies for the ambiguity. |
Yes, I would tear this refactoring out and submit it as a separate PR, of course coupled with a message that it is a yak-shave in preparation for the larger PR. It would definitely make it easier to see the exact changes that are being done in configure.ac in the following PR(s).
IIUC, these two must be submitted together in order for the build to complete and be usable? |
The build will complete with just the first of these two, but won't be testable without the testbed project and makefile targets from the second. However, even then, there's a couple more patches needed before the test suite will start successfully. |
Sure, but those are not part of this PR anyway (at least not as far as I can see) :) |
|
Closing in favor of a more granular refactor. |
Part of the PEP 730 work to add iOS support.
Adds:
Apologies in advance for the large PR; this is by far the largest single patch needed for PEP 730. Unfortunately, all these changes are interrelated - the resources are used by the build, and the makefile references the testbed. I couldn't work out a way to make the patch smaller. By way of partial defence - once you remove the autogenerated files (such as
configure), and the new XCode project and stub binaries, the patch is a lot smaller 😅Why tvOS and watchOS?
PEP 730 only proposes adding Tier 3 support for iOS. The tvOS and watchOS portions of this patch are strictly optional. I've included those portions of the patch because they're mostly symmetrical with the iOS changes, and it saves me maintaining these patches externally. However, I'm definitely aware of the project-level optics of a
tvOSandwatchOSfolder appearing in the CPython repo. Unfortunately, the platforms are just different enough that I felt they needed their own standalone folders.If the existence of the tvOS and watchOS folders (and/or the references in the configure script) are an impediment to merging, I'll gladly remove them.
Differences between macOS and iOS Frameworks
iOS frameworks are slightly different to macOS frameworks.
Info.plistis slightly different.@rpath, rather than an absolute path, as the install path for the framework will be app-specific..dylibartefacts and headers; and the headers won't be copied into the final distribution binary. As a result, the standard library and support binaries cannot be distributed inside the framework - they must be distributed parallel to the Framework folder. To accomodate this, themake installtarget for iOS will generate a file structure like the following:--enable-frameworklocationbinincludesymlink to ->Python.framework/Headerslibpython3.XPython.frameworkHeadersPython(the dylib binary)Info.plistThe task of copying the standard library into an appropriate location in the final app bundle is left as a task for the developer using the framework.
Summary of changes
configurechangesRESSRCDIRvariable to allow sharing of macOS and iOS Makefile stepsINSTALLTARGETSvariable so that iOS framework builds don't install binaries, manfiles, etc.PYTHONFRAMEWORKINSTALLNAMEPREFIXvariable; this is used as the install name for the library, allowing iOS frameworks to specify an@rpath-based nameMACHDEPearlier in the configure process so thatac_sys_systemis available_PYTHON_HOST_PLATFORMevaluation so that it includes the OS, ABI and architecture (e.g.,ios-iphoneos-arm64orios-iphonesimulator-x86_64). This is used as thesysconfigidentifier,IOS_DEPLOYMENT_TARGETvariable, tracking the iOS minimum API version.SOABI_PLATFORMandPLATFORM_TRIPLET.SOABI_PLATFORMis used in binary module names, and includes the ABI, but not the OS or CPU architecture (e.g.,math.cpython-313-iphonesimulator.dylib).PLATFORM_TRIPLETis used as the multiarch value, and contains the ABI and architecture (e.g.,iphoneos-arm64)ac_cv_file__dev_ptmxandac_cv_file__dev_ptc, which are usually mandatory command line arguments for cross-platform builds. iOS is a reliable cross-build target, so we know these aren't available.PY_SUPPORT_TIER=3list.Makefilechanges-Wl,-single_moduleflag on macOSRESSRCDIR,INSTALLTARGETS, andPYTHONFRAMEWORKINSTALLNAMEPREFIXvariables.testiOStarget to build and run the XCode testbed project, and extract the test results.config.subchangesThe
config.subscript has been updated to the2024-01-01version; additional patches have been applied to support the-simulatorsuffix, and thearm64_32CPU architecture.The additional patches were submitted upstream to autoconf in August last year. The official 2024-01-01 update includes the portions of that patch that added support for tvOS and watchOS, but didn't include updates adding the
-simulatorsuffix or thearm64_32CPU architecture. Unfortunately, the autoconf submission process is a bit of a black hole - you email them patches and get no further correspondence, even when the patch is merged. I've re-submitted the suffix and arm64_32 architecture patches; in the meantime, they've been manually applied here.Support files
Adds folders to store iOS/tvOS/watchOS build resources and documentation.
Adds template plist files for iOS/tvOS/watchOS frameworks.
Adds stub binaries that wrap compiler tooling. Xcode doesn't expose explicit compilers for iOS/tvOS/watchOS; instead, it uses an
xcrunscript that resolves to a full compiler path (e.g.,xcrun --sdk iphoneos clangto get the clang for an iPhone device). However, using this script poses 2 problems:xcrunincludes paths that are then machine specific, resulting in asysconfigmodule that cannot be shared between usersCC/CPP/LD/ARdefinitions that include spaces. There is a lot of C ecosystem tooling (including distutils and setuptools) that assumes that you can split a command line at the first space to get the path to the compiler executable; this isn't the case when usingxcrun.So - to avoid these problems, the
Resources/binfolders for each platform includes shell script wrappers around the tools needed by configure, named using the scheme that autoconf expects by default. These scripts are relocatable, and will always resolve to the appropriate local system paths. By including these scripts in the "installed" bin folder, the contents of the sysconfig module becomes useful for end-users to compile their own modules.Other changes
python -m test. If the CPython test suite passes, the single XCTest passes; otherwise, the XCTest fails. The test suite is configured to run on an "iPhone SE (3rd gen)" simulator - this is a stable device identifier that isn't subject to annual device refresh cycles.