Skip to content

Commit 43f9ae2

Browse files
committed
plugins: allow static plugins to be loaded dynamically
Change-Id: I9fc37d4ef87534cbc159d72e734ea6bda35985ca
1 parent 6f7c631 commit 43f9ae2

File tree

7 files changed

+128
-19
lines changed

7 files changed

+128
-19
lines changed

Applications/ParaView/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ endif()
9090

9191
if(NOT BUILD_SHARED_LIBS)
9292
target_link_libraries(paraview
93-
${PARAVIEW_PLUGINLIST})
93+
vtkPVStaticPluginsInit)
9494
endif(NOT BUILD_SHARED_LIBS)
9595

9696

CMake/ParaViewPluginsMacros.cmake

+54-9
Original file line numberDiff line numberDiff line change
@@ -231,31 +231,76 @@ macro(pv_process_plugins root_src root_build)
231231
DESTINATION "${PV_INSTALL_PLUGIN_DIR}"
232232
COMPONENT Runtime)
233233

234-
# write the static plugins init file.
235-
_write_static_plugins_init_file(
236-
${CMAKE_CURRENT_BINARY_DIR}/pvStaticPluginsInit.h
237-
${PARAVIEW_PLUGINLIST})
234+
if (NOT BUILD_SHARED_LIBS)
235+
# write the static plugins init file.
236+
_write_static_plugins_init_file(
237+
${CMAKE_CURRENT_BINARY_DIR}/pvStaticPluginsInit.h
238+
${CMAKE_CURRENT_BINARY_DIR}/pvStaticPluginsInit.cxx
239+
${PARAVIEW_PLUGINLIST})
240+
241+
vtk_module_dep_includes(vtkPVClientServerCoreCore)
242+
include_directories(${vtkPVClientServerCoreCore_INCLUDE_DIRS} ${vtkPVClientServerCoreCore_DEPENDS_INCLUDE_DIRS})
243+
add_library(vtkPVStaticPluginsInit
244+
${CMAKE_CURRENT_BINARY_DIR}/pvStaticPluginsInit.cxx)
245+
target_link_libraries(vtkPVStaticPluginsInit
246+
LINK_PRIVATE ${PARAVIEW_PLUGINLIST})
247+
endif ()
238248
endmacro()
239249

240250
#------------------------------------------------------------------------------
241251
# Internal function used to generate a header file initializing all plugins that
242252
# can be used by executables to link against the plugins when building
243253
# statically.
244-
function(_write_static_plugins_init_file filename)
245-
set(plugins_init_function "#include \"vtkPVPlugin.h\"\n\n")
254+
function(_write_static_plugins_init_file header source)
255+
file(WRITE "${header}" "void paraview_static_plugins_init();\n")
256+
257+
set(plugins_init_function "#include \"vtkPVPlugin.h\"\n")
258+
set(plugins_init_function "${plugins_init_function}#include \"vtkPVPluginLoader.h\"\n\n")
259+
set(plugins_init_function "${plugins_init_function}#include \"vtkPVPluginTracker.h\"\n\n")
260+
set(plugins_init_function "${plugins_init_function}#include <string>\n\n")
246261

247262
# write PV_PLUGIN_IMPORT_INIT calls
248263
foreach(plugin_name ${ARGN})
249264
set(plugins_init_function "${plugins_init_function}PV_PLUGIN_IMPORT_INIT(${plugin_name});\n")
250265
endforeach()
251266
set(plugins_init_function "${plugins_init_function}\n")
252267

268+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_load(const char* name);\n\n")
269+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_search(const char* name);\n\n")
270+
set(plugins_init_function "${plugins_init_function}void paraview_static_plugins_init()\n{\n")
271+
set(plugins_init_function "${plugins_init_function} vtkPVPluginLoader::SetStaticPluginLoadFunction(paraview_static_plugins_load);\n")
272+
set(plugins_init_function "${plugins_init_function} vtkPVPluginTracker::SetStaticPluginSearchFunction(paraview_static_plugins_search);\n")
273+
set(plugins_init_function "${plugins_init_function}}\n\n")
274+
275+
# write callback functions
276+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_func(const char* name, bool load);\n\n")
277+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_load(const char* name)\n{\n")
278+
set(plugins_init_function "${plugins_init_function} return paraview_static_plugins_func(name, true);\n")
279+
set(plugins_init_function "${plugins_init_function}}\n\n")
280+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_search(const char* name)\n{\n")
281+
set(plugins_init_function "${plugins_init_function} return paraview_static_plugins_func(name, false);\n")
282+
set(plugins_init_function "${plugins_init_function}}\n\n")
283+
253284
# write PV_PLUGIN_IMPORT calls
254-
set(plugins_init_function "${plugins_init_function}inline void paraview_static_plugins_init()\n{\n")
285+
set(plugins_init_function "${plugins_init_function}static bool paraview_static_plugins_func(const char* name, bool load)\n{\n")
286+
set(plugins_init_function "${plugins_init_function} std::string sname = name;\n\n")
255287
foreach(plugin_name ${ARGN})
256-
set(plugins_init_function "${plugins_init_function} PV_PLUGIN_IMPORT(${plugin_name});\n")
288+
set(plugins_init_function "${plugins_init_function} if (sname == \"${plugin_name}\")\n")
289+
set(plugins_init_function "${plugins_init_function} {\n")
290+
set(plugins_init_function "${plugins_init_function} if (load)\n")
291+
set(plugins_init_function "${plugins_init_function} {\n")
292+
set(plugins_init_function "${plugins_init_function} static bool loaded = false;\n")
293+
set(plugins_init_function "${plugins_init_function} if (!loaded)\n")
294+
set(plugins_init_function "${plugins_init_function} {\n")
295+
set(plugins_init_function "${plugins_init_function} PV_PLUGIN_IMPORT(${plugin_name});\n")
296+
set(plugins_init_function "${plugins_init_function} loaded = true;\n")
297+
set(plugins_init_function "${plugins_init_function} }\n")
298+
set(plugins_init_function "${plugins_init_function} }\n")
299+
set(plugins_init_function "${plugins_init_function} return true;\n")
300+
set(plugins_init_function "${plugins_init_function} }\n")
257301
endforeach()
302+
set(plugins_init_function "${plugins_init_function} return false;\n")
258303
set(plugins_init_function "${plugins_init_function}}\n")
259304

260-
file(WRITE "${filename}" "${plugins_init_function}")
305+
file(WRITE "${source}" "${plugins_init_function}")
261306
endfunction()

CommandLineExecutables/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ include_directories(${vtkPVServerManagerApplication_DEPENDS_INCLUDE_DIRS}
129129

130130
set(STATIC_LINK_PLUGINS)
131131
if (NOT BUILD_SHARED_LIBS)
132-
set(STATIC_LINK_PLUGINS ${PARAVIEW_PLUGINLIST})
132+
set(STATIC_LINK_PLUGINS vtkPVStaticPluginsInit)
133133
endif()
134134

135135
foreach (name pvserver pvdataserver pvrenderserver)

ParaViewCore/ClientServerCore/Core/vtkPVPluginLoader.cxx

+34
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ vtkPVPluginLoaderCleanerInitializer::~vtkPVPluginLoaderCleanerInitializer()
198198
//=============================================================================
199199

200200

201+
vtkPluginLoadFunction vtkPVPluginLoader::StaticPluginLoadFunction = 0;
202+
201203
vtkStandardNewMacro(vtkPVPluginLoader);
202204
//-----------------------------------------------------------------------------
203205
vtkPVPluginLoader::vtkPVPluginLoader()
@@ -312,6 +314,7 @@ bool vtkPVPluginLoader::LoadPluginInternal(const char* file, bool no_errors)
312314
return false;
313315
}
314316

317+
#ifdef BUILD_SHARED_LIBS
315318
this->SetFileName(file);
316319
std::string defaultname = vtksys::SystemTools::GetFilenameWithoutExtension(file);
317320
this->SetPluginName(defaultname.c_str());
@@ -461,11 +464,33 @@ bool vtkPVPluginLoader::LoadPluginInternal(const char* file, bool no_errors)
461464

462465
vtkPVPlugin* plugin = pv_plugin_query_instance();
463466
return this->LoadPlugin(file, plugin);
467+
#else
468+
if (StaticPluginLoadFunction &&
469+
StaticPluginLoadFunction(file))
470+
{
471+
this->Loaded = true;
472+
return true;
473+
}
474+
return false;
475+
#endif
464476
}
465477

466478
//-----------------------------------------------------------------------------
467479
bool vtkPVPluginLoader::LoadPlugin(const char* file, vtkPVPlugin* plugin)
468480
{
481+
#ifndef BUILD_SHARED_LIBS
482+
if (StaticPluginLoadFunction &&
483+
StaticPluginLoadFunction(plugin->GetPluginName()))
484+
{
485+
this->Loaded = true;
486+
return true;
487+
}
488+
else
489+
{
490+
this->SetErrorString("Failed to load static plugin.");
491+
}
492+
#endif
493+
469494
this->SetPluginName(plugin->GetPluginName());
470495
this->SetPluginVersion(plugin->GetPluginVersionString());
471496

@@ -536,3 +561,12 @@ void vtkPVPluginLoader::PrintSelf(ostream& os, vtkIndent indent)
536561
os << indent << "SearchPaths: " <<
537562
(this->SearchPaths ? this->SearchPaths : "(none)") << endl;
538563
}
564+
565+
//-----------------------------------------------------------------------------
566+
void vtkPVPluginLoader::SetStaticPluginLoadFunction(vtkPluginLoadFunction function)
567+
{
568+
if (!StaticPluginLoadFunction)
569+
{
570+
StaticPluginLoadFunction = function;
571+
}
572+
}

ParaViewCore/ClientServerCore/Core/vtkPVPluginLoader.h

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class vtkPVPlugin;
3232
class vtkStringArray;
3333
class vtkPVPlugin;
3434

35+
typedef bool (*vtkPluginLoadFunction)(const char*);
36+
3537
class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginLoader : public vtkObject
3638
{
3739
public:
@@ -90,6 +92,10 @@ class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginLoader : public vtkObject
9092
// Returns the status of most recent LoadPlugin call.
9193
vtkGetMacro(Loaded, bool);
9294

95+
// Description:
96+
// Sets the function used to load static plugins.
97+
static void SetStaticPluginLoadFunction(vtkPluginLoadFunction function);
98+
9399
protected:
94100
vtkPVPluginLoader();
95101
~vtkPVPluginLoader();
@@ -117,6 +123,8 @@ class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginLoader : public vtkObject
117123
private:
118124
vtkPVPluginLoader(const vtkPVPluginLoader&); // Not implemented.
119125
void operator=(const vtkPVPluginLoader&); // Not implemented.
126+
127+
static vtkPluginLoadFunction StaticPluginLoadFunction;
120128
};
121129

122130
//BTX

ParaViewCore/ClientServerCore/Core/vtkPVPluginTracker.cxx

+22-8
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ namespace
6767
}
6868
};
6969

70-
std::string vtkLocatePlugin(const char* plugin, bool add_extensions)
70+
std::string vtkLocatePlugin(const char* plugin, bool add_extensions, vtkPluginSearchFunction searchFunction)
7171
{
7272
// Make sure we can get the options before going further
7373
if(vtkProcessModule::GetProcessModule() == NULL)
@@ -76,6 +76,14 @@ namespace
7676
}
7777

7878
bool debug_plugin = vtksys::SystemTools::GetEnv("PV_PLUGIN_DEBUG") != NULL;
79+
#ifndef BUILD_SHARED_LIBS
80+
vtkPVPluginTrackerDebugMacro("Looking for static plugin \'" << plugin << "\'");
81+
if (searchFunction && searchFunction(plugin))
82+
{
83+
vtkPVPluginTrackerDebugMacro("Found static plugin \'" << plugin << "\'");
84+
return plugin;
85+
}
86+
#endif
7987
vtkPVOptions* options = vtkProcessModule::GetProcessModule()->GetOptions();
8088
std::string app_dir = options->GetApplicationPath();
8189
app_dir = vtksys::SystemTools::GetProgramPath(app_dir.c_str());
@@ -171,6 +179,8 @@ class vtkPVPluginTracker::vtkPluginsList :
171179
}
172180
};
173181

182+
vtkPluginSearchFunction vtkPVPluginTracker::StaticPluginSearchFunction = 0;
183+
174184
vtkStandardNewMacro(vtkPVPluginTracker);
175185
//----------------------------------------------------------------------------
176186
vtkPVPluginTracker::vtkPVPluginTracker()
@@ -198,11 +208,10 @@ vtkPVPluginTracker* vtkPVPluginTracker::GetInstance()
198208
bool debug_plugin = vtksys::SystemTools::GetEnv("PV_PLUGIN_DEBUG") != NULL;
199209
vtkPVPluginTrackerDebugMacro("Locate and load distributed plugin list.");
200210

201-
#ifdef BUILD_SHARED_LIBS
202211
// Locate ".plugins" file and process it.
203212
// This will setup the distributed-list of plugins. Also it will load any
204213
// auto-load plugins.
205-
std::string _plugins = vtkLocatePlugin(".plugins", false);
214+
std::string _plugins = vtkLocatePlugin(".plugins", false, StaticPluginSearchFunction);
206215
if (!_plugins.empty())
207216
{
208217
mgr->LoadPluginConfigurationXML(_plugins.c_str());
@@ -212,10 +221,6 @@ vtkPVPluginTracker* vtkPVPluginTracker::GetInstance()
212221
vtkPVPluginTrackerDebugMacro(
213222
"Could not find .plugins file for distributed plugins");
214223
}
215-
#else
216-
vtkPVPluginTrackerDebugMacro(
217-
"Static build. Skipping .plugins processing.");
218-
#endif
219224
}
220225

221226
return Instance;
@@ -305,7 +310,7 @@ void vtkPVPluginTracker::LoadPluginConfigurationXML(vtkPVXMLElement* root)
305310
}
306311
else
307312
{
308-
plugin_filename = vtkLocatePlugin(name.c_str(), true);
313+
plugin_filename = vtkLocatePlugin(name.c_str(), true, StaticPluginSearchFunction);
309314
}
310315
if (plugin_filename.empty())
311316
{
@@ -493,3 +498,12 @@ bool vtkPVPluginTracker::GetPluginAutoLoad(unsigned int index)
493498
}
494499
return (*this->PluginsList)[index].AutoLoad;
495500
}
501+
502+
//-----------------------------------------------------------------------------
503+
void vtkPVPluginTracker::SetStaticPluginSearchFunction(vtkPluginSearchFunction function)
504+
{
505+
if (!StaticPluginSearchFunction)
506+
{
507+
StaticPluginSearchFunction = function;
508+
}
509+
}

ParaViewCore/ClientServerCore/Core/vtkPVPluginTracker.h

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
class vtkPVPlugin;
3232
class vtkPVXMLElement;
3333

34+
typedef bool (*vtkPluginSearchFunction)(const char*);
35+
3436
class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginTracker : public vtkObject
3537
{
3638
public:
@@ -97,6 +99,10 @@ class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginTracker : public vtkObject
9799
bool GetPluginLoaded(unsigned int index);
98100
bool GetPluginAutoLoad(unsigned int index);
99101

102+
// Description:
103+
// Sets the function used to load static plugins.
104+
static void SetStaticPluginSearchFunction(vtkPluginSearchFunction function);
105+
100106
//BTX
101107
protected:
102108
vtkPVPluginTracker();
@@ -108,6 +114,8 @@ class VTKPVCLIENTSERVERCORECORE_EXPORT vtkPVPluginTracker : public vtkObject
108114

109115
class vtkPluginsList;
110116
vtkPluginsList* PluginsList;
117+
118+
static vtkPluginSearchFunction StaticPluginSearchFunction;
111119
//ETX
112120
};
113121

0 commit comments

Comments
 (0)