Embedding Python in C, linking fails with undefined reference to `Py_Initialize'

前端 未结 5 1407
陌清茗
陌清茗 2021-02-14 02:21

I am trying to compile the example from the docs https://docs.python.org/2.7/extending/embedding.html and my code looks exactly like the one under 5.1:

#include          


        
相关标签:
5条回答
  • 2021-02-14 02:54

    Libraries have to come after the object files when you are linking, so do:

    gcc  embedpy.o $(/usr/bin/python2.7-config --ldflags)
    
    0 讨论(0)
  • 2021-02-14 02:59

    I replicated the same problem on Lubuntu14.04 32bit virtual machine running on Win7 machine.

    I did the following things to replicate the problem in the first place where the C++ code is written in Eclipse C/C++ IDE. Defined a C++ Eclipse project titled "test". The source file contains the following C++ code which is the same as mentioned above by Miguellissimo.

    C++ Code ::

    #include "python2.7/Python.h"
    
    int main(int argc, char *argv[]) {
    
        Py_Initialize();
        PyRun_SimpleString("print \"Hello, world!\"");
    
        Py_Finalize();
        return 0;
    }
    

    Errors ::

    test.o: In function main': /home/ros/workspace/test/src/test.cpp:15: undefined reference toPy_Initialize' /home/ros/workspace/test/src/test.cpp:17: undefined reference to PyRun_SimpleStringFlags' /home/ros/workspace/test/src/test.cpp:18: undefined reference toPy_Finalize' collect2: error: ld returned 1 exit status

    The output of the following commands was the same as mentioned before by Miguellissimo,

    ros@rosPC:~/workspace/test/src$ python2.7-config --cflags
    
    -I/usr/include/python2.7 -I/usr/include/i386-linux-gnu/python2.7  -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
    
    ros@rosPC:~/workspace/test/src$ python2.7-config --ldflags
    
    -L/usr/lib/python2.7/config-i386-linux-gnu -L/usr/lib -lpthread -ldl  -lutil -lm  -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
    

    Project Properties of C++ Eclipse Project titled "test"::

    Inside, I had the following C++ Build Settings

    GCC C++ Compiler

    Command: g++
    
    All options: -I/opt/ros/indigo/include -O0 -g3 -Wall -c -fmessage-length=0
    
    Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Includes
        include paths: /opt/ros/indigo/include
    

    GCC C Compiler

    Command: gcc
    
    All options: -I/opt/ros/indigo/include -I/usr/lib/python2.7/config-i386-linux-gnu -O0 -g3 -Wall -c -fmessage-length=0
    
    Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Includes
        include paths: /opt/ros/indigo/include
                       /usr/lib/python2.7/config-i386-linux-gnu
    

    GCC C++ Linker

    Command: g++
    
    All options: Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Libraries:
    
        Libraries(-I): 
    
        Library search path(-L): 
    

    Solution::

    Specified the following C++ Build Settings in the Project Properties of C++ Eclipse Project "test"

    GCC C++ Compiler

    Command: g++
    
    All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
    
    Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Includes
        include paths: /opt/ros/indigo/include
                       /usr/include/python2.7
    

    GCC C Compiler

    Command: gcc
    
    All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
    
    Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Includes
        include paths: /opt/ros/indigo/include
                       /usr/include/python2.7
    

    GCC C++ Linker

    Command: g++
    
    All options: -L/usr/lib/python2.7/config-i386-linux-gnu
    
    Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
    
    Libraries:
    
        Libraries(-I): python2.7
    
        Library search path(-L): /usr/lib/python2.7/config-i386-linux-gnu
    

    Result :: Linker errors which resulted previously from the compilation of C++ Eclipse project doesn't occur anymore.

    0 讨论(0)
  • 2021-02-14 03:03

    Got the same error on WSL, Ubuntu 18.04, Python3.8, g++ 7.5. Thanks to Ciro Santilli comment, adding --embed option to python3.8-config solved unresolved symbols problem, but after that I got the following error:

    g++ `python3.8-config --cflags --embed` -o cpython.out cpython.cpp `python3.8-config --ldflags --embed`
    lto1: fatal error: bytecode stream in file ‘/home/rpovelik/installed/miniconda3/envs/cython/lib/python3.8/config-3.8-x86_64-linux-gnu/libpython3.8.a’ generated with LTO version 6.0 instead of the expected 6.2
    compilation terminated.
    lto-wrapper: fatal error: g++ returned 1 exit status
    compilation terminated.
    /usr/bin/ld: error: lto-wrapper failed
    collect2: error: ld returned 1 exit status
    

    I suppose some people are going to face the same issue so I inspected the similar symptoms here where conda people said something like "don't use default compilers - g++ - because it could cause compatibility issues - use conda specific compilers".

    By the way, adding -fno-lto solved my problem with system-wide g++ 7.5. Possibly you can try to change version of the compiler.

    0 讨论(0)
  • 2021-02-14 03:06

    The accepted answer uses system's default library location.

    If you are within an anaconda environment, library location may not be found. I tend to give locations more explicitly during linking, like:

    gcc embedpy.o -L$(python-config --prefix)/lib $(python-config --ldflags)
    

    This will not work outside anaconda environment in 64-bit library, in which case:

    gcc embedpy.o -L$(python-config --prefix)/lib64 $(python-config --ldflags)
    
    0 讨论(0)
  • 2021-02-14 03:12

    Also add --embed to python3-config

    On Ubuntu 20.04, Python 3.8, I also needed to pass --embed to python3-config as in:

    gcc -std=c99 -ggdb3 -O0 -pedantic-errors -Wall -Wextra \
      -fpie $(python3-config --cflags --embed) -o 'eval.out' \
      'eval.c' $(python3-config --embed --ldflags)
    

    otherwise -lpython3.8 is not added which leads to missing definitions.

    This is my test program:

    eval.c

    #define PY_SSIZE_T_CLEAN
    #include <Python.h>
    
    int main(int argc, char *argv[]) {
        (void)argc;
        wchar_t *program = Py_DecodeLocale(argv[0], NULL);
        if (program == NULL) {
            fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
            exit(1);
        }
        Py_SetProgramName(program);
        Py_Initialize();
        PyRun_SimpleString(argv[1]);
        if (Py_FinalizeEx() < 0) {
            exit(120);
        }
        PyMem_RawFree(program);
        return 0;
    }
    

    test run:

    ./eval.out 'print(2 ** 3)'
    
    0 讨论(0)
提交回复
热议问题