Skip to content

Commit 276d8cd

Browse files
committed
tart with the headers
1 parent 2902a8b commit 276d8cd

File tree

1 file changed

+48
-67
lines changed

1 file changed

+48
-67
lines changed

Doc/extending/first-extension-module.rst

Lines changed: 48 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,39 @@ We want this function to be callable from Python as follows:
8181
both Unix and Windows.
8282

8383

84-
Warming up your build tool
85-
==========================
84+
Start with the headers
85+
======================
8686

8787
Begin by creating a file named :file:`spammodule.c`. [#why-spammodule]_
8888

89-
Now, while the file is empty, we'll compile it.
89+
We'll start by including two headers: :file:`Python.h` to pull in
90+
all declarations of the Python C API, and :file:`stdlib.h` for the
91+
:c:func:`system` function. [#stdlib-h]_
9092

91-
Choose a build tool such as Setuptools or Meson, and follow its instructions
92-
to compile and install the empty :file:`spammodule.c` as a C extension module.
93+
Add the following lines to :file:`spammodule.c`:
94+
95+
.. literalinclude:: ../includes/capi-extension/spammodule-01.c
96+
:start-at: <Python.h>
97+
:end-at: <stdlib.h>
9398

99+
Be sure to put :file:`stdlib.h`, and any other standard library includes,
100+
*after* :file:`Python.h`.
101+
On some systems, Python may define some pre-processor definitions
102+
that affect the standard headers.
103+
104+
105+
Warming up your build tool
106+
==========================
107+
108+
With only the includes in place, your extension won't do anything.
109+
Still, it's a good time to try compiling and importing it.
94110
This will ensure that your build tool works, so that you can make
95111
and test incremental changes as you follow the rest of the text.
96112

113+
Choose a build tool such as Setuptools or Meson [#compile-directly]_, and
114+
follow its instructions to compile and install :file:`spammodule.c`
115+
as a C extension module.
116+
97117
.. note:: Workaround for missing ``PyInit``
98118

99119
If your build tool output complains about missing ``PyInit_spam``,
@@ -113,23 +133,8 @@ and test incremental changes as you follow the rest of the text.
113133
``SystemError: initialization of spam failed without raising an exception``
114134
instead of an :py:exc:`ImportError` in the next step.
115135

116-
.. note::
117-
118-
Using a third-party build tool is heavily recommended, as it will take
119-
care of various details of your platform and Python installation,
120-
of naming the resulting extension, and, later, of distributing your work.
121-
122-
If you don't want to use a tool, you can try to run your compiler directly.
123-
The following command should work for many flavors of Linux, and generate
124-
a ``spam.so`` file that you need to put in a directory
125-
on :py:attr:`sys.path`:
126-
127-
.. code-block:: sh
128-
129-
gcc --shared spammodule.c -o spam.so
130-
131-
When your extension is compiled and installed, start Python and try to import
132-
your extension.
136+
When your extension is compiled and installed, start Python and try to
137+
import it.
133138
This should fail with the following exception:
134139

135140
.. code-block:: pycon
@@ -140,51 +145,6 @@ This should fail with the following exception:
140145
ImportError: dynamic module does not define module export function (PyModExport_spam or PyInit_spam)
141146
142147
143-
Including the Header
144-
====================
145-
146-
Now, add the first line to your file: include :file:`Python.h` to pull in
147-
all declarations of the Python C API:
148-
149-
.. literalinclude:: ../includes/capi-extension/spammodule-01.c
150-
:start-at: <Python.h>
151-
:end-at: <Python.h>
152-
153-
Next, include the header for the :c:func:`system` function:
154-
155-
.. literalinclude:: ../includes/capi-extension/spammodule-01.c
156-
:start-at: <stdlib.h>
157-
:end-at: <stdlib.h>
158-
159-
Be sure to put this, and any other standard library includes, *after*
160-
:file:`Python.h`.
161-
On some systems, Python may define some pre-processor definitions
162-
that affect the standard headers.
163-
164-
.. note::
165-
166-
This include is technically not necessary: :file:`Python.h` includes
167-
``stdlib`` and :ref:`several other standard headers <capi-system-includes>`
168-
for its own use.
169-
However, it is good practice to explicitly include what you need.
170-
171-
With the includes in place, compile and import the extension again.
172-
You should get the same exception as with the empty file.
173-
174-
.. note::
175-
176-
Third-party build tools should handle pointing the compiler to
177-
the CPython headers and libraries, and setting appropriate options.
178-
179-
If you are running the compiler directly, you will need to do this yourself.
180-
If your installation of Python comes with a corresponding ``python-config``
181-
command, you can run something like:
182-
183-
.. code-block:: shell
184-
185-
gcc --shared $(python-config --cflags --ldflags) spammodule.c -o spam.so
186-
187-
188148
Module export hook
189149
==================
190150

@@ -565,6 +525,27 @@ Here is the entire source file, for your convenience:
565525
named ``spam``,
566526
projects where Python isn't the primary language might use ``py_spam.c``,
567527
and so on.
528+
.. [#stdlib-h] Including :file:`stdlib.h` is technically not necessary,
529+
since :file:`Python.h` includes it and
530+
:ref:`several other standard headers <capi-system-includes>` for its own use
531+
or for backwards compatibility.
532+
However, it is good practice to explicitly include what you need.
533+
.. [#compile-directly] Using a third-party build tool is heavily recommended,
534+
as it will take
535+
care of various details of your platform and Python installation,
536+
of naming the resulting extension, and, later, of distributing your work.
537+
538+
If you don't want to use a tool, you can try to run your compiler directly.
539+
The following command should work on Linux systems that include a
540+
correctly configured ``python-config`` command that corresponds to the
541+
CPython interpreter you use.
542+
It should generate a ``spam.so`` file that you need to put in a directory
543+
on :py:attr:`sys.path`.
544+
545+
.. code-block:: sh
546+
547+
gcc --shared $(python-config --cflags --ldflags) spammodule.c -o spam.so
548+
568549
.. [#why-pymethoddef] The :c:type:`!PyMethodDef` structure is also used
569550
to create methods of classes, so there's no separate
570551
":c:type:`!PyFunctionDef`".

0 commit comments

Comments
 (0)