Building Extension Modules#
Setuptools can build C/C++ extension modules. The keyword argument
setup() should be a list of instances of the
For example, let’s consider a simple project with only one extension module:
<project_folder> ├── pyproject.toml └── foo.c
and all project metadata configuration in the
# pyproject.toml [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] name = "mylib-foo" # as it would appear on PyPI version = "0.42"
To instruct setuptools to compile the
foo.c file into the extension module
mylib.foo, we need to add a
setup.py file similar to the following:
from setuptools import Extension, setup setup( ext_modules=[ Extension( name="mylib.foo", # as it would be imported # may include packages/namespaces separated by `.` sources=["foo.c"], # all sources are compiled into a single binary file ), ] )
If you plan to distribute a package that uses extensions across multiple platforms, cibuildwheel can also be helpful.
All files used to compile your extension need to be available on the system when building the package, so please make sure to include some documentation on how developers interested in building your package from source can obtain operating system level dependencies (e.g. compilers and external binary libraries/artifacts).
You will also need to make sure that all auxiliary files that are contained inside your project (e.g. C headers authored by you or your team) are configured to be included in your sdist. Please have a look on our section on Controlling files in the distribution.
Distributing Extensions compiled with Cython#
If Cython is present, then
setuptools will use it to build the
setuptools will try to find and compile the equivalent
.pyx). These files can be generated using the
cython command line tool.
You can ensure that Cython is always automatically installed into the build
environment by including it as a build dependency in
[build-system] requires = [..., "cython"]
Alternatively, you can include the
.c code that is pre-compiled by Cython
into your source distribution, alongside the original
.pyx files (this
might save a few seconds when building from an
To improve version compatibility, you probably also want to include current
.c files in your revision control system, and rebuild them whenever
you check changes in for the
.pyx source files.
This will ensure that people tracking your project will be able to build it
without installing Cython, and that there will be no variation due to small
differences in the generate C files.
Please checkout our docs on Controlling files in the distribution for
Extension API Reference#
- class setuptools.Extension(name, sources, *args, **kw)#
Describes a single extension module.
This means that all source files will be compiled into a single binary file
<module path>derived from
<suffix>defined by one of the values in
In the case
.pyxfiles are passed as
Cythonis not installed in the build environment,
setuptoolsmay also try to look for the equivalent
name (str) – the full name of the extension, including any packages – ie. not a filename or pathname, but Python dotted name
sources (list[str]) – list of source filenames, relative to the distribution root (where the setup script lives), in Unix form (slash-separated) for portability. Source files may be C, C++, SWIG (.i), platform-specific resource files, or whatever else is recognized by the “build_ext” command as source for a Python extension.
define_macros (list[tuple[str, str|None]]) – list of macros to define; each macro is defined using a 2-tuple: the first item corresponding to the name of the macro and the second item either a string with its value or None to define it without a particular value (equivalent of “#define FOO” in source or -DFOO on Unix C compiler command line)
extra_compile_args (list[str]) – any extra platform- and compiler-specific information to use when compiling the source files in ‘sources’. For platforms and compilers where “command line” makes sense, this is typically a list of command-line arguments, but for other platforms it could be anything.
extra_link_args (list[str]) – any extra platform- and compiler-specific information to use when linking object files together to create the extension (or to create a new static Python interpreter). Similar interpretation as for ‘extra_compile_args’.
export_symbols (list[str]) – list of symbols to be exported from a shared extension. Not used on all platforms, and not generally necessary for Python extensions, which typically export exactly one symbol: “init” + extension_name.
language (str) – extension language (i.e. “c”, “c++”, “objc”). Will be detected from the source extensions if not provided.
optional (bool) – specifies that a build failure in the extension should not abort the build process, but simply not install the failing extension.