|
| 1 | +========================== |
| 2 | +Building Extension Modules |
| 3 | +========================== |
| 4 | + |
| 5 | +Setuptools can build C/C++ extension modules. The keyword argument |
| 6 | +``ext_modules`` of ``setup()`` should be a list of instances of the |
| 7 | +:class:`setuptools.Extension` class. |
| 8 | + |
| 9 | + |
| 10 | +For example, let's consider a simple project with only one extension module:: |
| 11 | + |
| 12 | + <project_folder> |
| 13 | + ├── pyproject.toml |
| 14 | + └── foo.c |
| 15 | + |
| 16 | +and all project metadata configuration in the ``pyproject.toml`` file: |
| 17 | + |
| 18 | +.. code-block:: toml |
| 19 | +
|
| 20 | + # pyproject.toml |
| 21 | + [build-system] |
| 22 | + requires = ["setuptools"] |
| 23 | + build-backend = "setuptools.build_meta" |
| 24 | +
|
| 25 | + [project] |
| 26 | + name = "mylib-foo" # as it would appear on PyPI |
| 27 | + version = "0.42" |
| 28 | +
|
| 29 | +To instruct setuptools to compile the ``foo.c`` file into the extension module |
| 30 | +``mylib.foo``, we need to add a ``setup.py`` file similar to the following: |
| 31 | + |
| 32 | +.. code-block:: python |
| 33 | +
|
| 34 | + from setuptools import Extension, setup |
| 35 | +
|
| 36 | + setup( |
| 37 | + ext_modules=[ |
| 38 | + Extension( |
| 39 | + name="mylib.foo", # as it would be imported |
| 40 | + # may include packages/namespaces separated by `.` |
| 41 | +
|
| 42 | + sources=["foo.c"], # all sources are compiled into a single binary file |
| 43 | + ), |
| 44 | + ] |
| 45 | + ) |
| 46 | +
|
| 47 | +.. seealso:: |
| 48 | + You can find more information on the `Python docs about C/C++ extensions`_. |
| 49 | + Alternatively, you might also be interested in learn about `Cython`_. |
| 50 | + |
| 51 | + If you plan to distribute a package that uses extensions across multiple |
| 52 | + platforms, :pypi:`cibuildwheel` can also be helpful. |
| 53 | + |
| 54 | + |
| 55 | +Compiler and linker options |
| 56 | +=========================== |
| 57 | + |
| 58 | +The command ``build_ext`` builds C/C++ extension modules. It creates |
| 59 | +a command line for running the compiler and linker by combining |
| 60 | +compiler and linker options from various sources: |
| 61 | + |
| 62 | +.. Reference: `test_customize_compiler` in distutils/tests/test_sysconfig.py |
| 63 | +
|
| 64 | +* the ``sysconfig`` variables ``CC``, ``CXX``, ``CCSHARED``, |
| 65 | + ``LDSHARED``, and ``CFLAGS``, |
| 66 | +* the environment variables ``CC``, ``CPP``, |
| 67 | + ``CXX``, ``LDSHARED`` and ``LDFLAGS``, |
| 68 | + ``CFLAGS``, ``CPPFLAGS``, ``LDFLAGS``, |
| 69 | +* the ``Extension`` attributes ``include_dirs``, |
| 70 | + ``library_dirs``, ``extra_compile_args``, ``extra_link_args``, |
| 71 | + ``runtime_library_dirs``. |
| 72 | + |
| 73 | +.. Ignoring AR, ARFLAGS, RANLIB here because they are used by the (obsolete?) build_clib, not build_ext. |
| 74 | +
|
| 75 | +The resulting command line is then processed by the compiler and linker. |
| 76 | +According to the GCC manual sections on `directory options`_ and |
| 77 | +`environment variables`_, the C/C++ compiler searches for files named in |
| 78 | +``#include <file>`` directives in the following order: |
| 79 | + |
| 80 | +* first, in directories given by ``-I`` options (in left-to-right order), |
| 81 | +* then, in directories given by the environment variable ``CPATH`` (in left-to-right order), |
| 82 | +* then, in directories given by ``-isystem`` options (in left-to-right order), |
| 83 | +* then, in directories given by the environment variable ``C_INCLUDE_PATH`` (for C) and ``CPLUS_INCLUDE_PATH`` (for C++), |
| 84 | +* then, in standard system directories, |
| 85 | +* finally, in directories given by ``-idirafter`` options (in left-to-right order). |
| 86 | + |
| 87 | +The linker searches for libraries in the following order: |
| 88 | + |
| 89 | +* first, in directories given by ``-L`` options (in left-to-right order), |
| 90 | +* then, in directories given by the environment variable ``LIBRARY_PATH`` (in left-to-right order). |
| 91 | + |
| 92 | +.. important:: |
| 93 | + All files used to compile your extension need to be available on the system |
| 94 | + when building the package, so please make sure to include some documentation |
| 95 | + on how developers interested in building your package from source |
| 96 | + can obtain operating system level dependencies |
| 97 | + (e.g. compilers and external binary libraries/artifacts). |
| 98 | + |
| 99 | + You will also need to make sure that all auxiliary files that are contained |
| 100 | + inside your :term:`project` (e.g. C headers authored by you or your team) |
| 101 | + are configured to be included in your :term:`sdist <Source Distribution (or "sdist")>`. |
| 102 | + Please have a look on our section on :ref:`Controlling files in the distribution`. |
| 103 | + |
| 104 | + |
| 105 | +---- |
| 106 | + |
| 107 | +API Reference |
| 108 | +------------- |
| 109 | + |
| 110 | +.. autoclass:: setuptools.Extension |
| 111 | + |
| 112 | + |
| 113 | +.. _Python docs about C/C++ extensions: https://docs.python.org/3/extending/extending.html |
| 114 | +.. _Cython: https://cython.readthedocs.io/en/stable/index.html |
| 115 | +.. _directory options: https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html |
| 116 | +.. _environment variables: https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html> |
0 commit comments