@@ -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 ``Apple/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,87 +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
220+ set -e
221+ source $PROJECT_DIR /Python.xcframework/build/build_utils.sh
222+ install_python Python.xcframework app
232223
233- Note that the name of the simulator "slice" in the XCframework may be
234- different, depending the CPU architectures your `` XCFramework `` supports .
224+ If you have placed your XCframework somewhere other than the root of your
225+ project, modify the path to the first argument .
235226
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
243-
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-
268- cp " $CODESIGNING_FOLDER_PATH /dylib-Info-template.plist" " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
269- plutil -replace CFBundleExecutable -string " $FULL_MODULE_NAME " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
270- plutil -replace CFBundleIdentifier -string " $FRAMEWORK_BUNDLE_ID " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /Info.plist"
271- fi
272-
273- echo " Installing binary for $FRAMEWORK_FOLDER /$FULL_MODULE_NAME "
274- mv " $FULL_EXT " " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /$FULL_MODULE_NAME "
275- # Create a placeholder .fwork file where the .so was
276- echo " $FRAMEWORK_FOLDER /$FULL_MODULE_NAME " > ${FULL_EXT% .so} .fwork
277- # Create a back reference to the .so file location in the framework
278- echo " ${RELATIVE_EXT% .so} .fwork" > " $CODESIGNING_FOLDER_PATH /$FRAMEWORK_FOLDER /$FULL_MODULE_NAME .origin"
279- }
280-
281- PYTHON_VER=$( ls -1 " $CODESIGNING_FOLDER_PATH /python/lib" )
282- echo " Install Python $PYTHON_VER standard library extension modules..."
283- find " $CODESIGNING_FOLDER_PATH /python/lib/$PYTHON_VER /lib-dynload" -name " *.so" | while read FULL_EXT; do
284- install_dylib python/lib/$PYTHON_VER /lib-dynload/ " $FULL_EXT "
285- done
286-
287- # Clean up dylib template
288- rm -f " $CODESIGNING_FOLDER_PATH /dylib-Info-template.plist"
289-
290- echo " Signing frameworks as $EXPANDED_CODE_SIGN_IDENTITY_NAME ($EXPANDED_CODE_SIGN_IDENTITY )..."
291- 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 " {}" \;
292-
293- 10. Add Objective C code to initialize and use a Python interpreter in embedded
294- 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:
295229
296230 * UTF-8 mode (:c:member: `PyPreConfig.utf8_mode `) is *enabled *;
297231 * Buffered stdio (:c:member: `PyConfig.buffered_stdio `) is *disabled *;
@@ -310,22 +244,19 @@ To add Python to an iOS Xcode project:
310244 Your app's bundle location can be determined using ``[[NSBundle mainBundle]
311245 resourcePath] ``.
312246
313- Steps 8, 9 and 10 of these instructions assume that you have a single folder of
247+ Steps 7 and 8 of these instructions assume that you have a single folder of
314248pure Python application code, named ``app ``. If you have third-party binary
315249modules in your app, some additional steps will be required:
316250
317251* You need to ensure that any folders containing third-party binaries are
318- either associated with the app target, or copied in as part of step 8. Step 8
319- should also purge any binaries that are not appropriate for the platform a
320- specific build is targeting (i.e., delete any device binaries if you're
321- building an app targeting the simulator).
322-
323- * Any folders that contain third-party binaries must be processed into
324- framework form by step 9. The invocation of ``install_dylib `` that processes
325- the ``lib-dynload `` folder can be copied and adapted for this purpose.
326-
327- * If you're using a separate folder for third-party packages, ensure that folder
328- is included as part of the :envvar: `PYTHONPATH ` configuration in step 10.
252+ either associated with the app target, or are 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).
256+
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.
329260
330261* If any of the folders that contain third-party packages will contain ``.pth ``
331262 files, you should add that folder as a *site directory * (using
0 commit comments