orocos-toolchain / rtt

Orocos Real-Time Toolkit
http://www.orocos.org
Other
72 stars 79 forks source link

Always build multi component libs and deprecate ORO_CREATE_COMPONENT_TYPE #308

Open meyerj opened 5 years ago

meyerj commented 5 years ago

This merge request is the result of debugging component loading to find the root cause of warnings like

0.202 [ Warning][ComponentLoader::import(path_list)] Component type name OCL::logging::Log4cxxAppender already used:  overriding.

in macOS deployments today, or in general if one component library is linked to another component library.

  1. https://github.com/orocos-toolchain/rtt/commit/88775dcfde50174f3b680232445054c1cdf6cacb deprecates the old-style single component library entry hooks and the ORO_CREATE_COMPONENT_TYPE() macro and simply forwards single-component library ORO_CREATE_COMPONENT(CLASS_NAME) macro calls to two new-style macro calls. Not sure why it has not been implemented like this from the beginning. I do not see a disadvantage and it is a first step towards eliminating extern C functions returning C++ types (https://github.com/orocos-toolchain/rtt/issues/125). As a side effect, if OCL was compiled with that patch, the entry hook symbols in the component library that is actually being loaded always override the same symbols of other libraries that it might link to.

  2. https://github.com/orocos-toolchain/rtt/commit/c12486c77e3c2458c5ff562026a43279c7fe0b39 fixes a long-lasting bug that caused bogus static library warnings when compiling rtt/deployment/ComponentLoader.cpp or any other non-component target that includes rtt/deployment/ComponentLoader.hpp.

  3. https://github.com/orocos-toolchain/rtt/commit/cbedc2f282323f592c79cee784bd27f1898ae925 (http://bugs.orocos.org/show_bug.cgi?id=1001) has been reverted in https://github.com/orocos-toolchain/rtt/commit/a6ccf00cef676d91d5d665baa16ec6ed1b6b0909. The patch caused type mismatch errors on macOS and many additional Component type name ... already used: overriding. errors, even for Linux. I don't have a context anymore why it was originally introduced (@smits, @psoetens).

    I assume that what was meant by "overriding of ComponentTypes" in the original commit message is actually "unloading the component library and reloading it into the process by calling ComponentLoader::reloadInProcess() or ComponentLoader::reloadLibrary()" (and not overriding a registered component type name by loading another library with the same component type defined). In that rare case RTLD_LOCAL might be required according to the man page of dlopen:

    If the object's reference count drops to zero and no symbols in this object are required by other objects, then the object is unloaded after first calling any destructors defined for the object. (Symbols in this object might be required in another object because this object was opened with the RTLD_GLOBAL flag and one of its symbols satisfied a relocation in another object.)

    However, not adding RTLD_LOCAL explicitly leaves the default implementation defined, which is RTLD_LOCAL on Linux, but RTLD_GLOBAL on macOS (dlopen). And adding RTLD_LOCAL breaks the Orocos type system on macOS, because the singleton TypeInfoRepository might not be a singleton anymore depending on how it is used.

    In my understanding it is still possible to reload a component library, but there is no guarantee that the library actually has been reloaded if other component or plugin libraries have been loaded afterwards (which might still use symbols defined in the library to be unloaded).

    The current (old) behavior is inconsistent with PluginLoader (PluginLoader.cpp:661), but service and typekit plugins are not supposed to be unloaded again until the end of the process.

Note: This patch requires another patch in OCL to get rid of the deprecation warnings.