4.Building C and C++ Extensions¶
A C extension for CPython is a shared library (e.g. a.so file on Linux,.pyd on Windows), which exports aninitialization function.
To be importable, the shared library must be available onPYTHONPATH,and must be named after the module name, with an appropriate extension.When using distutils, the correct filename is generated automatically.
The initialization function has the signature:
It returns either a fully initialized module, or aPyModuleDefinstance. SeeInitializing C modules for details.
For modules with ASCII-only names, the function must be namedPyInit_<modulename>, with<modulename> replaced by the name of themodule. When usingMulti-phase initialization, non-ASCII module namesare allowed. In this case, the initialization function name isPyInitU_<modulename>, with<modulename> encoded using Python’spunycode encoding with hyphens replaced by underscores. In Python:
definitfunc_name(name):try:suffix=b'_'+name.encode('ascii')exceptUnicodeEncodeError:suffix=b'U_'+name.encode('punycode').replace(b'-',b'_')returnb'PyInit'+suffix
It is possible to export multiple modules from a single shared library bydefining multiple initialization functions. However, importing them requiresusing symbolic links or a custom importer, because by default only thefunction corresponding to the filename is found.See the“Multiple modules in one library” section inPEP 489 for details.
4.1.Building C and C++ Extensions with distutils¶
Extension modules can be built using distutils, which is included in Python.Since distutils also supports creation of binary packages, users don’tnecessarily need a compiler and distutils to install the extension.
A distutils package contains a driver script,setup.py. This is a plainPython file, which, in the most simple case, could look like this:
fromdistutils.coreimportsetup,Extensionmodule1=Extension('demo',sources=['demo.c'])setup(name='PackageName',version='1.0',description='This is a demo package',ext_modules=[module1])
With thissetup.py, and a filedemo.c, running
pythonsetup.pybuild
will compiledemo.c, and produce an extension module nameddemo inthebuild directory. Depending on the system, the module file will endup in a subdirectorybuild/lib.system, and may have a name likedemo.so ordemo.pyd.
In thesetup.py, all execution is performed by calling thesetupfunction. This takes a variable number of keyword arguments, of which theexample above uses only a subset. Specifically, the example specifiesmeta-information to build packages, and it specifies the contents of thepackage. Normally, a package will contain additional modules, like Pythonsource modules, documentation, subpackages, etc. Please refer to the distutilsdocumentation inDistributing Python Modules (Legacy version) to learn more about the features ofdistutils; this section explains building extension modules only.
It is common to pre-compute arguments tosetup(), to better structure thedriver script. In the example above, theext_modules argument tosetup() is a list of extension modules, each of which isan instance oftheExtension. In the example, the instancedefines an extension nameddemo which is build by compiling a single sourcefile,demo.c.
In many cases, building an extension is more complex, since additionalpreprocessor defines and libraries may be needed. This is demonstrated in theexample below.
fromdistutils.coreimportsetup,Extensionmodule1=Extension('demo',define_macros=[('MAJOR_VERSION','1'),('MINOR_VERSION','0')],include_dirs=['/usr/local/include'],libraries=['tcl83'],library_dirs=['/usr/local/lib'],sources=['demo.c'])setup(name='PackageName',version='1.0',description='This is a demo package',author='Martin v. Loewis',author_email='martin@v.loewis.de',url='https://docs.python.org/extending/building',long_description='''This is really just a demo package.''',ext_modules=[module1])
In this example,setup() is called with additionalmeta-information, whichis recommended when distribution packages have to be built. For the extensionitself, it specifies preprocessor defines, include directories, librarydirectories, and libraries. Depending on the compiler, distutils passes thisinformation in different ways to the compiler. For example, on Unix, this mayresult in the compilation commands
gcc-DNDEBUG-g-O3-Wall-Wstrict-prototypes-fPIC-DMAJOR_VERSION=1-DMINOR_VERSION=0-I/usr/local/include-I/usr/local/include/python2.2-cdemo.c-obuild/temp.linux-i686-2.2/demo.ogcc-sharedbuild/temp.linux-i686-2.2/demo.o-L/usr/local/lib-ltcl83-obuild/lib.linux-i686-2.2/demo.so
These lines are for demonstration purposes only; distutils users should trustthat distutils gets the invocations right.
4.2.Distributing your extension modules¶
When an extension has been successfully built, there are three ways to use it.
End-users will typically want to install the module, they do so by running
pythonsetup.pyinstall
Module maintainers should produce source packages; to do so, they run
pythonsetup.pysdist
In some cases, additional files need to be included in a source distribution;this is done through aMANIFEST.in file; seeSpecifying the files to distribute for details.
If the source distribution has been built successfully, maintainers can alsocreate binary distributions. Depending on the platform, one of the followingcommands can be used to do so.
pythonsetup.pybdist_rpmpythonsetup.pybdist_dumb