Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling Python 3 extension module on Mac

I'm trying to write a Python extension module in C. I'm running macOS Catalina and have a Homebrew installation of Python 3 (with default installation settings). When I try to compile the following file:

#include <Python/Python.h>

static PyObject* world(PyObject* self, PyObject* args)
{
    printf("Hello world!\n");
    Py_RETURN_NONE;
}

static PyMethodDef methods[] = {
    {"world", world, METH_VARARGS, "Prints \"Hello world!\""},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT,
    "name for the module",
    "docstring for the module",
    -1,
    methods
};

PyMODINIT_FUNC PyInit_hello(void)
{
    return PyModule_Create(&module);
}

by running gcc hello.c in my terminal, I get the following messages:

hello.c:15:5: error: use of undeclared identifier
      'PyModuleDef_HEAD_INIT'
    PyModuleDef_HEAD_INIT,
    ^
hello.c:14:27: error: variable has incomplete type
      'struct PyModuleDef'
static struct PyModuleDef module = {
                          ^
hello.c:14:15: note: forward declaration of 'struct PyModuleDef'
static struct PyModuleDef module = {
              ^
hello.c:24:12: warning: implicit declaration of function
      'PyModule_Create' is invalid in C99
      [-Wimplicit-function-declaration]
    return PyModule_Create(&module);
           ^
1 warning and 2 errors generated.

Is there a way to fix this? I've tried playing around with the -L and -I flags to no avail. I think this might be happening because it’s using the header for Python 2 rather than Python 3.

like image 204
user76284 Avatar asked Sep 14 '25 00:09

user76284


1 Answers

Use distutils

create setup.py. e.g.

from distutils.core import setup, Extension

def main():
    setup(name="hello",
            version="1.0.0",
            description="desc",
            author="<your name>",
            author_email="[email protected]",
            ext_modules=[Extension("hello",["hello.c"])])

if __name__ == "__main__":
    main()

in c file change include to:

#include <Python.h>

Assuming your c file name is hello.c and setup.py is placed in the same directory:

python3 setup.py install

In your case, verify whether it is "python3" or "python". This should build your module and install it, you should be able to see the compiler and linker commands

like image 185
Icarus3 Avatar answered Sep 15 '25 14:09

Icarus3