Python - Py_Initialize unresolved during compilati

2019-04-08 04:53发布

问题:

I have statically compiled Python2.7 without any error. To test my build, I use the following snippet:

#include "Python.h"
int main()
{
   Py_Initialize();
}

And I am compiling it like this:

$ gcc -static -I/path/to/python/header -L/path/to/my/staticpythonlib \ 
 -lpython2.7 -ldl -l_all_other_needed_lib /tmp/my_previous_snippet.c -o myouput

However, an error occured. gcc claims the famous undefined reference.

test.c:(.text+0x1): Undefined reference to 'Py_Initialize'

Curiously I used gcc with the verbosity flag (I won't paste the result here) and the compiler says, it's using my libpython, but couldn't find the reference. So I listed the symbols of my static python2.7 library :

$ nm /path/to/pythonlib |grep Py_Initialize
frozenmain.o           U Py_Initialize
pythonrun.o  0000009e9 T Py_Initialize
pythonrun.o  000000052 T Py_Initialize_Ex
main.o                 U Py_Initialize

We can see, that Py_Initialize is correctly referenced in pythonrun.o. However i don't know how the compiler chose the correct object file.

My questions are :

  1. How can I be sure, that gcc uses the correct object file in my .a lib?
  2. Is there anything wrong on my compilation options?

Thanks for your help.

回答1:

The order matters! More specifically, the order in the arguments for gcc matters. More specifically, if a bar object uses a function bluh from library bleh, then the order -lbleh bar.o is problematic because it provides no reason to gcc look for the function bluh in bleh. On the other hand, when you use bar.o -lbleh then gcc knows you are referring to bluh and when it gets to handle -lbleh it tries to resolve the dependence. This is quickly mentioned at http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html. As a rule, always specifies libraries after your objects.

To reproduce your problem, create a file a1.c as in:

#include "Python.h"

int main()
{
    Py_Initialize();
    return 0;
}

Now compile with gcc -static -I/usr/include/python2.7 -L/usr/lib/python2.7/config/ -lpython2.7 -ldl -lm -lutil -lz -pthread -o a1 a1.c. This gives the undefined reference to Py_Initialize. Of course you have to change the paths to match your installation.

Now, instead, compile with gcc -static -I/usr/include/python2.7 -L/usr/lib/python2.7/config/ -o a1 a1.c -lpython2.7 -ldl -lm -lutil -lz -pthread and it works (ignoring the possible many warnings, which is a different matter).



回答2:

I am using python 2.7 and set the path of python installation directory in the environment variable. I also use boost 1.5.0

follow the steps to Compile the below code

#include <python2.7/Python.h>
int main()
{
Py_Initialize();

PyRun_SimpleString("print \"Hello, world!\"");

Py_Finalize();
return 0;
}

Run the command:-

g++ hello.cc -lpython2.7
./a.out