Libraries compiling


I’m trying to compile an extension to Panda3D in C++ and I’m using the very useful interrogate module.
But does anyone know in what order things get compiled?
Is it: first the interrogate call, then compile, then link? or something different?

Or, does someone just have a single makepanda build log (for linux) for me? Then I can check how Makepanda does it.

Since the output of interrogate is C++ code, it follows that the order must be: interrogate, then compile, then link.

But you might do well to study the output of a build process anyway, to get the command-line options right.


Thank you David for your quick reply.

I read in some other threads [1][2] that i should also call interrogate_module and genpycode. Well, I did that, and got the following: (btw. my extension is called pgmm)

pgmm/$  interrogate -DCPPPARSER -D__STDC__=1 -D__cplusplus -D__i386__ -D__const=const -S/usr/include/panda3d/parser-inc -S/usr/include/ -I/usr/share/panda3d/thirdparty/win-python/include/ -I/usr/share/panda3d/thirdparty/linux-libs-a/nspr/include/ -I/usr/share/panda3d/thirdparty/linux-libs-a/ffmpeg/include/ -oc pgmm_igate.cxx -od -fnames -string -refcount -assert -python-native -I/usr/include/panda3d/ -module libpgmm -library libpgmm pgmm.h

Now I get a nice _igate file with some wrappers, and I get function names like:
“static PyObject *Dtool_PGMM_generate_gmm_8”

pgmm/$ interrogate_module -oc pgmm_module.cxx  -module libpgmm -library libpgmm -python

6 python function wrappers exported.

6 is correct, because I have 6 PUBLISHED functions in my PGMM class.
I get a _module file now, but I can’t see the wrapper functions anymore. I get stuff like:
" PyObject *Dtool_6V2gwcrc(PyObject *self, PyObject *args);"
and more.

pgmm/$ sudo genpycode -s -e ./ libpgmm >>out.txt
Traceback (most recent call last):
  File "<string>", line 1, in ?
  File "debtmp/usr/share/panda3d/direct/src/ffi/", line 94, in ?
  File "debtmp/usr/share/panda3d/direct/src/ffi/", line 291, in run
  File "debtmp/usr/share/panda3d/direct/src/ffi/", line 253, in generateNativeWrappers
  File "<string>", line 1, in ?
ImportError: No module named libpgmm

What did I do wrong? Or don’t I need genpycode at all?

You don’t actually need genPyCode these days; you can just “import pgmm” and your functions will be in there. But you do need to compile and link your source code and your two generated files together, and produce the importable module (or pgmm.dll on Windows).


David, thanks very much again for your quick and helpful reply.

I stuffed all the files into the linker, meaning pgmm.cxx, pgmm_igate.cxx, pgmm_module.cxx, copied the .so file over to /usr/lib/python2.4/site-packages/, and did “import libpgmm”, but now I got this error:

$ python
Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02) 
[GCC 4.1.2 20060928 (prerelease)] NOT on windows, so don't worry
>>> import libpgmm
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ImportError: /usr/lib/python2.4/site-packages/ undefined symbol: Dtool_6V2gwcrc

But that is defined in pgmm_igate.cxx:
" PyObject *Dtool_6V2gwcrc(PyObject *self, PyObject *args);"
And I’m pretty sure I compiled and linked it correctly, without any errors/warnings.

I think the problem is that you have mismatched names between your module file and the igate file. I think you should use ‘-python-native’ instead of ‘-python’ on the interrogate_module command line.


David, you’re the man! Thanks a million times!!!

Now I can use my own C++ modules in Panda3D :slight_smile:

As for the build-log from makepanda — why not try running makepanda yourself? On all the operating systems for which I provide an RPM or DEB, it compiles out-of-the-box.

The only tricky bit is that you need to do a few apt-get’s before you try compiling. You need libpng-dev, libjpeg-dev, libtiff-dev, libssl-dev, zlib-dev, libfreetype6-dev, python24-dev, and … uh… maybe one other. I always remember when I see the error message that says something like “tiff.h — file not found.”

Thanks Josh. Yes, I’ve thought of compiling Panda3D myself again, but I don’t really have the time right now of recompiling the entire stuff when I just need to know 2 commands. But I got it now.

Oh, I have another question, if you dont mind;

I noticed that Panda3D uses .I files for the inline functions. I also did that in my code, cuz i thought that it has special meaning for interrogate. But is this true? Does it really matter where I put my inline functions and have to put them in the .I file? Or can I also put them in the header file or the cxx file?

You can’t put inline function bodies in the .cxx file, since they have to be visible to any code that uses them. Most people put them in the .h file.

In the Panda code, we have adopted the convention of putting inline function bodies in .I files strictly as an organizational convenience. We feel that this cleanly separates the interface (the .h file) from the implementation (the .I and .cxx files). There is no need for you to observe the same convention if you feel differently.


Right. But since I compile my program as static library, and I want to use my lib in other C++ programs as well, I have to ship the uncompiled .I file together with the .h file and the .so file to the user (he/she needs the .h file to include, right, that means also the .I file), that means everyone can see the source and edit the .I file?
Wouldn’t it be better to make the functions non-inline then, and put them in the .cxx file? What do you think? Or are inline-functions required by interrogate or so?

This is the nature of C++ development. If you ship your code as a compiled object, you must ship the inline function definitions as source, and everyone will be able to read them. That’s what an inline function is–after all, the compiler has to be able to read it in order to inline it.

If that makes you nervous for some reason, the only way to avoid it is to make the methods non-inline. You can do that freely; there is no technical reason to make any of your methods inline, other than the performance benefits of inline methods.

But I don’t know why you should try to hide your code from people you are distributing it to. If anyone really wants to see what it is doing, they can always disassemble it anyway.