panda3d / interrogate

Python binding generator for Panda3D
Other
4 stars 1 forks source link

interrogate(_module?) to allow specifying a user-defined init function #3

Open CFSworks opened 6 years ago

CFSworks commented 6 years ago

This is needed for e.g. making sure panda3d/core.so calls init_libpanda to ensure pnmimagetypes is initialized.

Currently it's only needed in non-metalib builds where the platform linker only links libraries where at least one symbol is used, such as with Travis CI's version of GCC. For now, I'm silencing test errors with -Wl,--no-as-needed (see 601a82d).

rdb commented 6 years ago

I agree, I have found myself wishing for such a feature in the past as well. Could you remind me why exactly the static initializers don't work when making a non-metalib build, though?

I can think several ways to implement such a feature:

  1. We can permit a CPPExpression to be added as an init invocation in an .N file, using a line like (eg.) oninit call_my_func()
  2. We could extend C++ syntax to add a special keyword or attribute to any function to mark it as needing to be invoked at init time
  3. We could add a command-line flag to interrogate_module to specify a function to be called on init (probably my least favourite option)
CFSworks commented 6 years ago

When doing a metalib build, the static initializers for pnmimagetypes are pulled into libpanda, which is the only library that offers other symbols needed by the interrogate-generated modules. The linker has no choice but to pull in that library and have the initializers run at load.

With a non-metalib build, pnmimagetypes resides in its own shared object, and some platforms (e.g. Linux distros whose linkers have --as-needed on by default) try to be smart and only pull in libraries if at least one symbol is imported from them. libpanda calls the pnmimagetypes init function for this reason. However, the interrogate modules depend on symbols from the underlying component libraries now, and not libpanda, so the linker skips both libpanda and pnmimagetypes.

I was thinking a command line flag, so it could be used directly from the buildsystem. I don't think the other options would work here as pnmimagetypes isn't interrogated, and neither is libpanda.

On Tue, Sep 4, 2018, 12:17 rdb notifications@github.com wrote:

I agree, I have found myself wishing for such a feature in the past as well. Could you remind me why exactly the static initializers don't work when making a non-metalib build, though?

I can think several ways to implement such a feature:

  1. We can permit a CPPExpression to be added as an init invocation in an .N file, using a line like (eg.) oninit call_my_func()
  2. We could extend C++ syntax to add a special keyword or attribute to any function to mark it as needing to be invoked at init time
  3. We could add a command-line flag to interrogate_module to specify a function to be called on init (probably my least favourite option)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/panda3d/interrogate/issues/3, or mute the thread https://github.com/notifications/unsubscribe-auth/AAqxYMt7D3DhdiAzEHtSCLZmTqq2dgAUks5uXsO1gaJpZM4WYGcs .

rdb commented 6 years ago

Another option, mirroring other parts of Panda, is to consider libp3pnmimagetypes a plug-in and have it loaded via a Config.prc variable (ie. we would have load-image-type similar to load-file-type, load-audio-type, load-video-type. See LoaderFileTypeRegistry and MovieTypeRegistry.) This would allow us to separate out plug-ins that use external libraries (such as OpenEXR) in the future and also make it possible for people to provide their own plug-ins.

Either way, I'd still be OK with having something like what you describe.

CFSworks commented 6 years ago

The modular approach gets a +1 from me.

I have only a slight concern that we might be patching up the example and ignoring the more general problem. For example, --as-needed still prevents linking against libpanda.so at all when doing a non-metalib build, and the only way to change that would be to force Interrogate to make a call to init_libpanda(). (The bigger question, of course, is "Do we care?" since this doesn't actually prevent anything from working. We might only want to address this if we're concerned with future-proofing, i.e. if we want the ABI to be consistent even when we split apart component libs and we want to make sure libpanda is dynamically linked so it can pull in the newly-formed component lib.)