Changes To Embedding Python Using Xcode 5.0
This document discusses some changes necessary to properly embed a Python interpreter using Xcode 5.0.
Not only can new Python extensions, written in C/C++/Objective-C, be accessed from Python, but a Python interpreter can also be embedded in a C/C++/Objective-C program, so that the program can run Python code and access Python modules, extensions, etc.
Embedding the Python Framework
The Python Documentation explains how to obtain the necessary compiler and linker flags (though in most cases, only the
-I, -L and
-l flags are really necessary). This works for most Unix-like operating systems, including OS X.
In particular on OS X, Python is packaged in a framework bundle, so that all the Python modules, extensions and header files are in one location. Multiple versions of Python can also be supported. This also means that compiling and linking can be simplified when accessed via a framework:
-Iflag to the complier with the path to the headers.
To link, we add a
-L/-lpair of options to link against the libpython2.x.dylib library.
As a framework:
Then we drag the Python.framework icon into the Xcode sidebar (or equivalently add Python.framework via Link Binary With Libraries in Build Phases).
Because Python is a framework, it also resides in the SDK, even though Python (or any scripting language) has difficulties being in two places. Due to both long-term and recent issues, it was decided to remove Python from the SDK. This doesn’t affect any regular users or software developers that don’t specify an SDKROOT (either via the SDKROOT environment variable, the -sdk option on some tools, or the -isysroot/-syslibroot options to the compiler/linker).
But if you are using an SDKROOT and/or Xcode (which enforces an SDKROOT), the framework shortcuts will no longer work, so you must go back to using the Unix-like settings:
2) Run (with the appropriate version number if not using 2.7) shown in Listing 1:
Listing 1 Getting compiler flags
% python2.7-config --cflags
-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE
-I option is duplicated). In Xcode, paste the path (without the leading
-I) into the Header Search Paths setting of the Search Paths section of the Build Settings. If not using Xcode, add the
-I option with the path to the compiler flags.
3) Remove the Python.framework icon from the Xcode sidebar, or if not using Xcode, remove “-framework Python” from the linker flags.
4) Run (with the appropriate version number if not using 2.7) shown in Listing 2:
Listing 2 Getting linker flags
% python2.7-config --ldflags
-L/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7
If using Xcode, open the path following the
-L option in the Finder, and drag the libpython2.7.dylib icon into the Xcode sidebar. Confirm the dialog box, and now Xcode is set to link against libpython2.7.dylib (by using the same
-l option settings as above).
If not using Xcode, add the
-L option (with path) and second
-l option from above to the linker flags.
Document Revision History
Fixed invalid '-' character in Listing 1.
New document that discusses how to embed the Python scripting language into your application.