Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Py_Initialize unresolved during compilation

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.

like image 548
johnydepp99 Avatar asked Dec 08 '12 22:12

johnydepp99


2 Answers

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).

like image 197
mmgp Avatar answered Sep 21 '22 09:09

mmgp


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
like image 21
Pradip Das Avatar answered Sep 22 '22 09:09

Pradip Das