@@ -170,7 +170,7 @@ helpful.
170170To add Python to an iOS Xcode project:
171171
1721721. Build or obtain a Python ``XCFramework ``. See the instructions in
173- :source: `iOS/README.rst ` (in the CPython source distribution) for details on
173+ :source: `Apple/ iOS/README.md ` (in the CPython source distribution) for details on
174174 how to build a Python ``XCFramework ``. At a minimum, you will need a build
175175 that supports ``arm64-apple-ios ``, plus one of either
176176 ``arm64-apple-ios-simulator `` or ``x86_64-apple-ios-simulator ``.
@@ -180,22 +180,19 @@ To add Python to an iOS Xcode project:
180180 of your project; however, you can use any other location that you want by
181181 adjusting paths as needed.
182182
183- 3. Drag the ``iOS/Resources/dylib-Info-template.plist `` file into your project,
184- and ensure it is associated with the app target.
185-
186- 4. Add your application code as a folder in your Xcode project. In the
183+ 3. Add your application code as a folder in your Xcode project. In the
187184 following instructions, we'll assume that your user code is in a folder
188185 named ``app `` in the root of your project; you can use any other location by
189186 adjusting paths as needed. Ensure that this folder is associated with your
190187 app target.
191188
192- 5 . Select the app target by selecting the root node of your Xcode project, then
189+ 4 . Select the app target by selecting the root node of your Xcode project, then
193190 the target name in the sidebar that appears.
194191
195- 6 . In the "General" settings, under "Frameworks, Libraries and Embedded
192+ 5 . In the "General" settings, under "Frameworks, Libraries and Embedded
196193 Content", add ``Python.xcframework ``, with "Embed & Sign" selected.
197194
198- 7 . In the "Build Settings" tab, modify the following:
195+ 6 . In the "Build Settings" tab, modify the following:
199196
200197 - Build Options
201198
@@ -211,86 +208,24 @@ To add Python to an iOS Xcode project:
211208
212209 * Quoted Include In Framework Header: No
213210
214- 8. Add a build step that copies the Python standard library into your app. In
215- the "Build Phases" tab, add a new "Run Script" build step *before * the
216- "Embed Frameworks" step, but *after * the "Copy Bundle Resources" step. Name
217- the step "Install Target Specific Python Standard Library", disable the
218- "Based on dependency analysis" checkbox, and set the script content to:
211+ 7. Add a build step that processes the Python standard library, and your own
212+ Python binary dependencies. In the "Build Phases" tab, add a new "Run
213+ Script" build step *before * the "Embed Frameworks" step, but *after * the
214+ "Copy Bundle Resources" step. Name the step "Process Python libraries",
215+ disable the "Based on dependency analysis" checkbox, and set the script
216+ content to:
219217
220218 ..code-block ::bash
221219
222- set -e
223-
224- mkdir -p" $CODESIGNING_FOLDER_PATH /python/lib"
225- if [" $EFFECTIVE_PLATFORM_NAME " = " -iphonesimulator" ]; then
226- echo " Installing Python modules for iOS Simulator"
227- rsync -au --delete" $PROJECT_DIR /Python.xcframework/ios-arm64_x86_64-simulator/lib/" " $CODESIGNING_FOLDER_PATH /python/lib/"
228- else
229- echo " Installing Python modules for iOS Device"
230- rsync -au --delete" $PROJECT_DIR /Python.xcframework/ios-arm64/lib/" " $CODESIGNING_FOLDER_PATH /python/lib/"
231- fi
232-
233- Note that the name of the simulator "slice" in the XCframework may be
234- different, depending the CPU architectures your ``XCFramework `` supports.
220+ set -e
221+ source $PROJECT_DIR /Python.xcframework/build/build_utils.sh
222+ install_python Python.xcframework app
235223
236- 9. Add a second build step that processes the binary extension modules in the
237- standard library into "Framework" format. Add a "Run Script" build step
238- *directly after * the one you added in step 8, named "Prepare Python Binary
239- Modules". It should also have "Based on dependency analysis" unchecked, with
240- the following script content:
241-
242- ..code-block ::bash
224+ If you have placed your XCframework somewhere other than the root of your
225+ project, modify the path to the first argument.
243226
244- set -e
245-
246- install_dylib () {
247- INSTALL_BASE=$1
248- FULL_EXT=$2
249-
250- # The name of the extension file
251- EXT=$( basename" $FULL_EXT " )
252- # The location of the extension file, relative to the bundle
253- RELATIVE_EXT=${FULL_EXT# $CODESIGNING_FOLDER_PATH / }
254- # The path to the extension file, relative to the install base
255- PYTHON_EXT=${RELATIVE_EXT/ $INSTALL_BASE / }
256- # The full dotted name of the extension module, constructed from the file path.
257- FULL_MODULE_NAME=$( echo$PYTHON_EXT | cut -d" ." -f 1| tr" /" " ." ) ;
258- # A bundle identifier; not actually used, but required by Xcode framework packaging
259- FRAMEWORK_BUNDLE_ID=$( echo$PRODUCT_BUNDLE_IDENTIFIER .$FULL_MODULE_NAME | tr" _" " -" )
260- # The name of the framework folder.
261- FRAMEWORK_FOLDER=" Frameworks/$FULL_MODULE_NAME .framework"
262-
263- # If the framework folder doesn't exist, create it.
264- if [! -d " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER " ]; then
265- echo " Creating framework for$RELATIVE_EXT "
266- mkdir -p" $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER "
267- cp" $CODESIGNING_FOLDER_PATH /dylib-Info-template.plist" " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
268- plutil -replace CFBundleExecutable -string" $FULL_MODULE_NAME " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
269- plutil -replace CFBundleIdentifier -string" $FRAMEWORK_BUNDLE_ID " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
270- fi
271-
272- echo " Installing binary for$FRAMEWORK_FOLDER /$FULL_MODULE_NAME "
273- mv" $FULL_EXT " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /$FULL_MODULE_NAME "
274- # Create a placeholder .fwork file where the .so was
275- echo " $FRAMEWORK_FOLDER /$FULL_MODULE_NAME " > ${FULL_EXT% .so} .fwork
276- # Create a back reference to the .so file location in the framework
277- echo " ${RELATIVE_EXT% .so} .fwork" > " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /$FULL_MODULE_NAME .origin"
278- }
279-
280- PYTHON_VER=$( ls -1" $CODESIGNING_FOLDER_PATH /python/lib" )
281- echo " Install Python$PYTHON_VER standard library extension modules..."
282- find" $CODESIGNING_FOLDER_PATH /python/lib/$PYTHON_VER /lib-dynload" -name" *.so" | while read FULL_EXT; do
283- install_dylib python/lib/$PYTHON_VER /lib-dynload/" $FULL_EXT "
284- done
285-
286- # Clean up dylib template
287- rm -f" $CODESIGNING_FOLDER_PATH /dylib-Info-template.plist"
288-
289- echo " Signing frameworks as$EXPANDED_CODE_SIGN_IDENTITY_NAME ($EXPANDED_CODE_SIGN_IDENTITY )..."
290- find" $CODESIGNING_FOLDER_PATH /Frameworks" -name" *.framework" -exec /usr/bin/codesign --force --sign" $EXPANDED_CODE_SIGN_IDENTITY " ${OTHER_CODE_SIGN_FLAGS:- } -o runtime --timestamp=none --preserve-metadata=identifier,entitlements,flags --generate-entitlement-der" {}" \;
291-
292- 10. Add Objective C code to initialize and use a Python interpreter in embedded
293- mode. You should ensure that:
227+ 8. Add Objective C code to initialize and use a Python interpreter in embedded
228+ mode. You should ensure that:
294229
295230 * UTF-8 mode (:c:member: `PyPreConfig.utf8_mode `) is *enabled *;
296231 * Buffered stdio (:c:member: `PyConfig.buffered_stdio `) is *disabled *;
@@ -309,22 +244,19 @@ To add Python to an iOS Xcode project:
309244 Your app's bundle location can be determined using ``[[NSBundle mainBundle]
310245 resourcePath] ``.
311246
312- Steps8, 9 and10 of these instructions assume that you have a single folder of
247+ Steps7 and8 of these instructions assume that you have a single folder of
313248pure Python application code, named ``app ``. If you have third-party binary
314249modules in your app, some additional steps will be required:
315250
316251* You need to ensure that any folders containing third-party binaries are
317- either associated with the app target, orcopied in as part of step 8. Step 8
318- should also purge any binaries that are not appropriate for the platform a
319- specific build is targeting (i.e., delete any device binaries if you're
320- building an app targeting the simulator).
252+ either associated with the app target, orare explicitly copied as part of
253+ step 7. Step 7 should also purge any binaries that are not appropriate for
254+ the platform a specific build is targeting (i.e., delete any device binaries
255+ if you're building an app targeting the simulator).
321256
322- * Any folders that contain third-party binaries must be processed into
323- framework form by step 9. The invocation of ``install_dylib `` that processes
324- the ``lib-dynload `` folder can be copied and adapted for this purpose.
325-
326- * If you're using a separate folder for third-party packages, ensure that folder
327- is included as part of the:envvar: `PYTHONPATH ` configuration in step 10.
257+ * If you're using a separate folder for third-party packages, ensure that
258+ folder is added to the end of the call to ``install_python `` in step 7, and
259+ as part of the:envvar: `PYTHONPATH ` configuration in step 8.
328260
329261* If any of the folders that contain third-party packages will contain ``.pth ``
330262 files, you should add that folder as a *site directory * (using
@@ -334,25 +266,30 @@ modules in your app, some additional steps will be required:
334266Testing a Python package
335267------------------------
336268
337- The CPython source tree contains:source: `a testbed project <iOS/testbed> ` that
269+ The CPython source tree contains:source: `a testbed project <Apple/ iOS/testbed> ` that
338270is used to run the CPython test suite on the iOS simulator. This testbed can also
339271be used as a testbed project for running your Python library's test suite on iOS.
340272
341- After building or obtaining an iOS XCFramework (See:source: `iOS/README.rst `
342- for details), create a clone of the Python iOS testbed project by running:
273+ After building or obtaining an iOS XCFramework (see:source: `Apple/iOS/README.md `
274+ for details), create a clone of the Python iOS testbed project. If you used the
275+ ``Apple `` build script to build the XCframework, you can run:
276+
277+ ..code-block ::bash
278+
279+ $ python cross-build/iOS/testbed clone --app< path/to/module1> --app< path/to/module2> app-testbed
280+
281+ Or, if you've sourced your own XCframework, by running:
343282
344283..code-block ::bash
345284
346- $ pythoniOS /testbed clone --framework< path/to/Python.xcframework> --app< path/to/module1> --app< path/to/module2> app-testbed
285+ $ pythonApple /testbed clone --platform iOS --framework< path/to/Python.xcframework> --app< path/to/module1> --app< path/to/module2> app-testbed
347286
348- You will need to modify the ``iOS/testbed `` reference to point to that
349- directory in the CPython source tree; any folders specified with the ``--app ``
350- flag will be copied into the cloned testbed project. The resulting testbed will
351- be created in the ``app-testbed `` folder. In this example, the ``module1 `` and
352- ``module2 `` would be importable modules at runtime. If your project has
353- additional dependencies, they can be installed into the
354- ``app-testbed/iOSTestbed/app_packages `` folder (using ``pip install --target
355- app-testbed/iOSTestbed/app_packages `` or similar).
287+ Any folders specified with the ``--app `` flag will be copied into the cloned
288+ testbed project. The resulting testbed will be created in the ``app-testbed ``
289+ folder. In this example, the ``module1 `` and ``module2 `` would be importable
290+ modules at runtime. If your project has additional dependencies, they can be
291+ installed into the ``app-testbed/Testbed/app_packages `` folder (using ``pip
292+ install --target app-testbed/Testbed/app_packages `` or similar).
356293
357294You can then use the ``app-testbed `` folder to run the test suite for your app,
358295For example, if ``module1.tests `` was the entry point to your test suite, you
@@ -381,7 +318,7 @@ tab. Modify the "Arguments Passed On Launch" value to change the testing
381318arguments.
382319
383320The test plan also disables parallel testing, and specifies the use of the
384- ``iOSTestbed .lldbinit `` file for providing configuration of the debugger. The
321+ ``Testbed .lldbinit `` file for providing configuration of the debugger. The
385322default debugger configuration disables automatic breakpoints on the
386323``SIGINT ``, ``SIGUSR1 ``, ``SIGUSR2 ``, and ``SIGXFSZ `` signals.
387324