@@ -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
8787Begin 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.
94110This will ensure that your build tool works, so that you can make
95111and 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.
133138This 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