wiki:Dev/PluginsPathes

Plugins & Pathes

  1. General
  2. Windows
  3. Linux
  4. Helper Functions
    1. Windows
    2. Linux
    3. MacOS X
    4. Other Systems

To simplify the addition of pieces/extensions OpenSG 2 will use a larger number of libraries and be more oriented towards plugins. This opens up a can of worms in regard to being able to find those plugins with minimal user involvement and how to structure the installation file hierarchy in general.

General

Some basic rules apply independent of the involved operating system.

Plugins can explicitly be loaded during the osgInit() call by setting the OPENSG_PLUGIN_PATH and optionally the OPENSG_PLUGIN_PATTERN variables. OPENSG_PLUGIN_PATH is a list of directories (separated by ";" or ":", depending on what the actual operating system is) that are searched for dynamic or shared libraries. If OPENSG_PLUGIN_PATTERN is set, only libraries matching the (regular expression) pattern are loaded. Setting OPENSG_PLUGIN_LOAD_ALL overwrites OPENSG_PLUGIN_PATTERN and loads all plugins found in OPENSG_PLUGIN_PATH.

Plugins are loaded only and expected to initialize as well as register themselves with the rest of the system.

In addition to the explicitly loaded plugins there are plugins loaded implicitly. Those are expected to be located in a directory called OpenSGPlugins relative to where the OSGBase library is found (see below). Implicit plugins can either be loaded at startup like the explicit ones (if OPENSG_PLUGIN_LOAD_ALL is set) or on demand.

Plugins are only loaded once, i.e. if there are multiple plugins with the same name only the first one found will be loaded. They have to be explicitly unloaded for the same plugin to be loaded again.

Windows

The default way of doing things on Windows is put every library in WINDOWS/system32 (or equivalent). This needs Administrator rights, and seems like a bad idea in general. Therefore OpenSG doesn't do that. Instead, the installation directory (normally 'C:\Program Files\OpenSG') has a lib subdirectory which has all the available libs, and the plugins are in the 'OpenSGPlugins' subdirectory of this directory. This installation dir is added to the user's PATH environment variable on installation. The path to the main installation directory is also added to the environment, in the 'OPENSG' variable (this simplifies integration of include paths into e.g. Visual Studio). The default versions are optimized (e.g. 'OSGBase.dll'), the debug-versions have an appended 'D' (e.g. 'OSGBaseD.dll').

Wouldn't it make sense to add version number to these, similar to what boost can do? I.e. OSGBase-1.6-d.dll, etc? This avoids versioning problems and several apps can also co-exists. You are doing that on *nix-anyway, from what I can see. :) Similarly, plugins are dependent on a specific version, so they ought to be handled as such. Subdirs in the plugin directory? marcusl

Plugins are searched in the following places in the following order:

  1. From the 'OPENSG_PLUGIN_PATH' and 'OPENSG_PLUGIN_PATTERN' specs
  1. From the 'OpenSGPlugins' directory relative to the 'OSGBase.dll' location

Note that libs explicitly linked into the executable are first searched in the executable's directory and then in the 'PATH' environment variable. The above order only applies to plugins loaded by osgInit.

Linux

On Linux the standards are not quite clear for libraries like this one. The http://www.freestandards.org/en/LSB LSB mentions '/usr/local' for system-administrator installed libraris, and '/opt' for applications in general. Given that OpenSG is not really an application (although it comes with some examples), '/usr/local' seems to be the right place. To allow parallel installation of multiple versions all directories are versioned.

I would actually go for /opt because /usr/local seems not a place that should be distributed in a cluster. jspringer

This gives the following structure:

  • /usr/local/
  • include/
  • OpenSG-${version}
  • OpenSG -> OpenSG-${version}
  • ${lib}/
  • OpenSG-${version}
  • dbg/
  • libOSGBase.so
  • ...
  • opt/
  • libOSGBase.so
  • ...
  • libOSGBase.so -> opt/libOSGBase.so
  • ...
  • OpenSGPlugins-dbg/
  • libOSGFancyPlug.so
  • ...
  • OpenSGPlugins-opt/
  • libOSGFancyPlug.so
  • ...
  • OpenSGPlugins -> OpenSGPlugins-opt
  • libOSGBase.so -> OpenSG-${version}/libOSGBase.so
  • OpenSGPlugins -> OpenSG-${version}/OpenSGPlugins
  • ...
  • bin/
  • osgSceneViewer
  • ...
  • share/
  • OpenSG-${version}

This keeps all the libs for a version in one directory and discourages mixing plugins and libs from different versions (which is probably a bad idea anyway).

Helper Functions

One of the core problems for doing this is to find the plugins. The envvar and the predefined pathes help, but the best way is to use a pluding dir that's relative to the used libraries, as that automatically picks up the plugins for that lib.

But there is no well-defined way to find the absolute path of a library, it is very system-dependent. We should probably put that in a BaseFunction?, other apps might have a use for it, too.

Here are some ways of doing it:

Windows

You can put this code into a shared library and it returns the absolute path of that shared library.

#include <string>

std::string getSharedLibraryFileName()

{

    char tmppath[2048];

    tmppath[0] = 0;

    ::GetModuleFileName(::GetModuleHandle("OSGBase"), (LPTSTR) tmppath, sizeof(tmppath));

    return tmppath;

}

Linux

Get the absolute path of an executable.

#include <string>

#include <unistd.h>

std::string getExecutableFileName()

{

    char exepath[2048];

    exepath[0] = 0;

    readlink("/proc/self/exe", exepath, sizeof(exepath));

    return exepath;

}

Get the absolute path of a shared library.

Ok. I tested this on my 64bit Linux machine and it didn't work as expected. I used it in several .so's and it returned for those different .so's the same path! But since we only need this once for the OSGBase library, I think it should work.

#define _GNU_SOURCE

#include <dlfcn.h>

#include <string>

std::string getSharedLibraryFileName()

{

    Dl_info info;

    info.dli_fname = 0;

    if (0 != dladdr((const void *) &getSharedLibraryFileName, &info))

    {

        if (info.dli_fname)

            return info.dli_fname; 

    }

    return "";

}

MacOS X

To be found out.

Other Systems

Not sure if possible.

Last modified 7 years ago Last modified on 01/17/10 01:11:44