0

I'm working on a Python 2.7 project and I'm attempting to write a c++ extension to speed up our implementation of the D* lite algorithm. Never played with python C API, I'm struggling a lot in setting up my environment. To check whether I can access the C API, I wrote this simple snippet, but unfortunately I cannot manage to get it compiled properly.

Here's the snippet, aka dstar_lite.cpp

#include <Python.h>
#include "numpy/arrayobject.h"

int main(int argc, char *argv[]) {
    if (PyErr_Occurred()) {
        printf("Error\n");
        return -1; // Or some suitable return value to indicate failure.
    }
    return 0;
}

My IDE is visual studio code, and these are my c_cpp_properties.json and my tasks.json configuration files:

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "/usr/include/python2.7/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

tasks.json

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ build active file",
            "command": "/usr/bin/gcc",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "-I/usr/include/python2.7",
                "-I/usr/include/x86_64-linux-gnu/python2.7",
                "-fno-strict-aliasing",
                "-Wdate-time",
                "-D_FORTIFY_SOURCE=2",
                "-fdebug-prefix-map=/build/python2.7-QDqKfA/python2.7-2.7.18=.",
                "-fstack-protector-strong",
                "-Wformat",
                "-Werror=format-security",
                "-DNDEBUG",
                "-fwrapv",
                "-Wstrict-prototypes",
                "-L/usr/lib/python2.7/config-x86_64-linux-gnu",
                "-L/usr/lib",
                "-lpython2.7",
                "-lpthread",
                "-ldl",
                "-lutil",
                "-lm",
                "-Xlinker",
                "-export-dynamic",
                "-Wl,-O1",
                "-Wl,-Bsymbolic-functions",
                "-fPIC",
                "-fno-common",
                "-O2",
                "-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION",
                "-ggdb",
                "-Wall",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

Here, includes, cflags and ldflags are taken by running the following commands, as suggested in several other threads here in StackOverflow:

python2-config --includes
> -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7
python2-config --cflags
> -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7  -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-QDqKfA/python2.7-2.7.18=. -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
python2-config --ldflags
> -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpython2.7 -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

The error I get should be related to the linking process, to the best of my knowledge. I'm gonna share the complete log trace:

Starting build...
/usr/bin/gcc -fdiagnostics-color=always -g -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -fdebug-prefix-map=/build/python2.7-QDqKfA/python2.7-2.7.18=. -fstack-protector-strong -Wformat -Werror=format-security -DNDEBUG -fwrapv -Wstrict-prototypes -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -L/usr/lib/python2.7/dist-packages/numpy/core/lib -lpython2.7 -lpthread -ldl -lutil -lm -lnpymath -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -fPIC -fno-common -O2 -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -ggdb -Wall /home/david/git/AI4A_project/planning/dstar/dstar_lite.cpp -o /home/david/git/AI4A_project/planning/dstar/dstar_lite
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
In file included from /usr/include/python2.7/numpy/ndarrayobject.h:21,
                 from /usr/include/python2.7/numpy/arrayobject.h:4,
                 from /home/david/git/AI4A_project/planning/dstar/dstar_lite.cpp:63:
/usr/include/python2.7/numpy/__multiarray_api.h:1463:1: warning: ‘int _import_array()’ defined but not used [-Wunused-function]
 1463 | _import_array(void)
      | ^~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccJwaN2x.o: in function `main':
/home/david/git/AI4A_project/planning/dstar/dstar_lite.cpp:67: undefined reference to `PyErr_Occurred'
collect2: error: ld returned 1 exit status

Build finished with error(s).
dc_Bita98
  • 851
  • 2
  • 17
  • 35
  • In which header file is `PyErr_Occurred` defined? – kiner_shah Jan 19 '22 at 10:44
  • `/usr/include/python2.7/pyerrors.h` – dc_Bita98 Jan 19 '22 at 10:46
  • So is this header file included in some other file like `Python.h` or do you need to include it explicitly (you can try this BTW)? – kiner_shah Jan 19 '22 at 10:48
  • `pyerrors.h` is included in `Python.h`. Also, explicitly including pyerrors.h in my file doesn't change anything – dc_Bita98 Jan 19 '22 at 10:55
  • Then the issue is that your Python library is not linked properly to the project. – kiner_shah Jan 19 '22 at 10:56
  • [I moved all the linker options after the source file argument](https://stackoverflow.com/questions/30040373/reference-undefined-to-functions-in-python-dev-header) in the gcc cli command and the compilation works fine. But now I get a ***segmentation fault*** error as soon as I attempt to execute any python-releated instruction such as `PyErr_Occurred()` – dc_Bita98 Jan 19 '22 at 11:18
  • Try using a debugger like GDB to see where the program crashes. – kiner_shah Jan 19 '22 at 11:21
  • BTW I am confused really why would you require to move source files after linker options. Why are you are using `gcc` executable to compile a C++ source file? Shouldn't you use `g++`? – kiner_shah Jan 19 '22 at 11:23
  • 1
    The segmentation fault is because you have not called `Py_Initialize()`. You cannot use most of the Python C API until you do that – DavidW Jan 19 '22 at 11:27
  • I'm not very expert about compilers...I was using gcc simply because I saw it employed by most tutorials. Anyway, also with g++ I must specify linker options after source file. I suppose it does make sense: to link something, that has to be created by the compiler before – dc_Bita98 Jan 19 '22 at 11:29
  • @DavidW exactly thanks. So it's time for me to keep diving into the docs – dc_Bita98 Jan 19 '22 at 11:31
  • 1
    The linker fails, because cpp on the command line comes after libraries. It should be the other way around. See a similar post for a more detailed explanation: https://stackoverflow.com/a/48836737/5769463 – ead Jan 19 '22 at 12:11

0 Answers0