'Python's C extension with more than one header

I have been updating a Python package developed in Python 2.7, so far so good until I got to the C extensions. My C (plib.c) file imports the classes below:

#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <xyz.h>

The corresponding init file was like this:

PyMODINIT_FUNC initplib(void)
{
  PyObject *plib_module;
  plib_module = Py_InitModule("xyz.plib", plib_methods);
  PyModule_AddStringConstant(plib_module, "plib_api_version", plib_api_version);
}

My setup.py looks like this:

plib = distutils.core.Extension('xyz.plib ',
                                sources = ['src/plib.c'],
                                include_dirs = incdirs,
                                library_dirs = libdirs,
                                libraries = libs,
                                extra_compile_args = ['-Wall', '-pedantic']
                                #,
                #'extra_link_args = ['-fPIC']
                                )

distutils.core.setup(name = 'xyz',
                     version = '0.1',
                     packages = ['xyz'],
                     ext_modules = [plib])

I can then call plib from my python file as import plib.

However, Python 3.X requires me to do something a bit different:

static struct PyModuleDef plib= {
    PyModuleDef_HEAD_INIT,
    "xyz.plib ", /* name of module */
    "",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    plib_methods
};


PyMODINIT_FUNC PyInit_initclib(void)
{
    return PyModule_Create(&plib);
}

I have tried different names with no success, I still not able to load the xyz.h header and therefore I get the error:

'unresolved external symbol'

Can anyone tell me what I'm doing wrong

EDIT a workable example

Calculating the kth prime number (Taken from somewhere else)

primeheader.h

extern int kthPrime(int n);

c_prime.c

#include <stdio.h>
#include "primeheader.h"

int isPrime(int n) {
  for (int i=2; i<n/2; i++) {
    if (n%i == 0)
      return 0;
  }
  return 1;
}

int kthPrime(int k) {
  int candidate = 2;
  while (k) {
    if (isPrime(candidate))
      k--;
    candidate++;
  }
  return candidate-1;
}

// Driver code
int main() {
  printf("%d\n", kthPrime(10000));
  return 0;
}

compile c_prime:

gcc -c c_prime.c

fastprime.c

#include <Python.h>
#include "primeheader.h"

// A static function which takes PyObjects arguments and returns a PyObject result
static PyObject* py_kthPrime(PyObject* self, PyObject* args) {
  int n;
  if (!PyArg_ParseTuple(args, "i", &n)) // Validate and parse the arguments received to function so that its usable by C
    return NULL;
  return Py_BuildValue("i", kthPrime(n)); // Get result from C, wrap it up with a PyObject and return it
}

// Define a collection of methods callable from our module
static PyMethodDef PyFastPrimeMethods[] = {
  {"kthPrime", py_kthPrime, METH_VARARGS, "Finds the kth prime number"}
};

// Module definition
static struct PyModuleDef fastprimemodule = {
  PyModuleDef_HEAD_INIT,
  "fastprime",
  "This module calculates the kth prime number",
  -1,
  PyFastPrimeMethods
};

// This method is called when you import your code in python. It instantiates the module and returns a reference to it
PyMODINIT_FUNC PyInit_fastprime(void) 
{ 
  return PyModule_Create(&fastprimemodule); 
} 

setup.py

from distutils.core import setup, Extension 
  
setup(name='fastprime', 
    ext_modules=[ 
            Extension('fastprime', 
                    ['fastprime.c'],
                    extra_objects=["c_prime.o"] # Relocatable compiled code of the c_prime to prevent recompiling each time
                    ) 
            ] 
)

Build module

python setup.py build

Errors

c_prime.o : error LNK2001: unresolved external symbol __main
c_prime.o : error LNK2001: unresolved external symbol printf


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source