Python embedding

2019-04-29 23:48发布

问题:

I would like to have a single big binary which embeds Python interpreter and a small script - I'm totally new to this whole static linking, configure & make and GCC et al. Please, could someone describe to me the basic steps in building such executable?

I'm on MacOS 10.6, I downloaded Python 3.3 beta. Then, I created "test.c":

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print('Today is', ctime(time()))\n");
  Py_Finalize();
  return 0;
}

Now, in a folder, I have both "Python-3.3.0b1" folder and "test.c" file.

I typed:

gcc -I ./Python-3.3.0b1 -o test test.c

but I got lots of "include" error.

But I'm not even sure if this is the right way to proceed..? Should I first somehow build just Python and then "link" it with "test.c"?

Btw., if Python gets released do they use the same procedure of "./configure" and "make"? Do they use some special options or am I able to build very similar (the same) Python executable as the one provided from python.org?

Also, I tried this "./configure" and "make" and it made a folder called "build/lib.macosx-10.6-x86_64-3.3" with lots of *.so files (?) but there is nothing called "python" or similar...?

回答1:

The problem is that gcc doesn't know enough about your Python installation and isn't linking all the headers properly. You need to get that information from distutils and try and figure out how to get that information into gcc. This is explained better in the Linking Requirements of the Embedding section of the Python documentation.

But there's an easier way. There is a script called pymkfile.py that will create a make file that includes all the information you need. See Section 4 of this tutorial.

From Section 4, a very similar example to what you're trying to do:

The simplest method of embedding Python code is to use the PyRun_SimpleString() function. This function sends a single line of code to the interpreter. Because the interpreter is persistent, it's like typing the individual lines in an interactive Python session, which means that you can execute new lines to the interpreter by calling PyRun_SimpleString with each line of code. For example, the following code runs a simple Python program to split and reassemble a string:

#include <Python.h>
int main()
{
printf("String execution\n");
Py_Initialize();
PyRun_SimpleString("import string");
PyRun_SimpleString("words = string.split('rod jane freddy')");
PyRun_SimpleString("print string.join(words,', ')");
Py_Finalize();
return 0;
}

You can see that the basic structure is simple. You have the initialize and finalize steps, and embedded between are the calls to the Python interpreter. To compile the program, copy the code and save it to a file called pystring.c. First, use the script to build a suitable Makefile:

$ pymkfile.py pystring > Makefile

Now, run make to actually build the code. After the final application has been created, run the application to see the results:

$ ./pystring

String execution
rod, jane, freddy

You've just executed a simple bit of Python code by using a C wrapper. You could use the same basic technique to perform many different tasks that use Python embedded in an application. The only obvious limitation is that, in essence, the two components are separate. There's no communication between the embedded Python interpreter and the host C application.

So, you gave the interpreter some code and it executed and printed it out; note how you didn't have to take the output from the interpreter, then print it: The interpreter sent the information directly to the standard output.



回答2:

Have you considered using py2app? If you are only interested in shipping a script and not writing C code, it could fit your needs better.

http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html



回答3:

Also, I tried this "./configure" and "make" and it made a folder called "build/lib.macosx-10.6-x86_64-3.3" with lots of *.so files (?) but there is nothing called "python" or similar...?

The .so files are object files. The python executable is only produced AFTER you call make install, so the three steps:

./configure
make
make install

That last step usually involves sudo

Make sure that you are not replacing your system Python. Not a good idea.

If you are on OS X, the usual method is to link with the OS X Python system framework. This 'looks' like embedded Python, but you are linking to the existing system Python. The system Python link target is libpython.dylib in /usr/lib

If you are not adverse to using Xcode, just Google 'embedded Python OS X' and find a good tutorial.

I used THIS tutorial first time I did it.



标签: python gcc embed