-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathPluginHelper.cpp
More file actions
153 lines (116 loc) · 5.73 KB
/
Copy pathPluginHelper.cpp
File metadata and controls
153 lines (116 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "PluginHelper.hpp"
#include <rtt/types/TypekitPlugin.hpp>
#include <boost/filesystem.hpp>
#include <boost/tokenizer.hpp>
#include <rtt/plugin/PluginLoader.hpp>
#include <base/Time.hpp>
#include "PkgConfigHelper.hpp"
#include <iostream>
#define xstr(s) str(s)
#define str(s) #s
using namespace orocos_cpp;
/**
* Cache for the needed typekits.
*/
std::map<std::string, std::vector<std::string> > PluginHelper::componentToTypeKitsMap;
std::vector< std::string > PluginHelper::getNeededTypekits(const std::string& componentName)
{
auto it = componentToTypeKitsMap.find(componentName);
if(it != componentToTypeKitsMap.end())
return it->second;
//first we load the typekit
std::vector<std::string> pkgConfigFields;
pkgConfigFields.push_back("typekits");
std::vector<std::string> pkgConfigValues;
if(!PkgConfigHelper::parsePkgConfig(componentName + std::string("-tasks-") + xstr(OROCOS_TARGET) + std::string(".pc"), pkgConfigFields, pkgConfigValues))
throw std::runtime_error("Could not load pkgConfig file for typekit for component " + componentName);
boost::char_separator<char> sep(" ");
boost::tokenizer<boost::char_separator<char> > typekits(pkgConfigValues[0], sep);
std::vector< std::string > ret;
for(const std::string &tk: typekits)
{
ret.push_back(tk);
}
componentToTypeKitsMap.insert(std::make_pair(componentName, ret));
return ret;
}
void PluginHelper::loadAllPluginsInDir(const std::string& path)
{
base::Time start = base::Time::now();
boost::filesystem::path pluginDir(path);
int cnt = 0;
boost::shared_ptr<RTT::plugin::PluginLoader> loader = RTT::plugin::PluginLoader::Instance();
boost::filesystem::directory_iterator end_it; // default construction yields past-the-end
for (boost::filesystem::directory_iterator it( pluginDir );
it != end_it; it++ )
{
if(boost::filesystem::is_regular_file(*it))
{
// std::cout << "Found library " << *it << std::endl;
loader->loadLibrary(it->path().string());
cnt++;
}
}
base::Time end = base::Time::now();
std::cout << "Loaded " << cnt << " typekits in " << (end - start).toSeconds() << " Seconds " << std::endl;
}
bool PluginHelper::loadTypekitAndTransports(const std::string& componentName)
{
//already loaded, we can just exit
if(RTT::types::TypekitRepository::hasTypekit(componentName))
return true;
std::vector<std::string> knownTransports;
knownTransports.push_back("corba");
knownTransports.push_back("mqueue");
knownTransports.push_back("typelib");
//first we load the typekit
std::vector<std::string> pkgConfigFields;
pkgConfigFields.push_back("prefix");
pkgConfigFields.push_back("libdir");
std::vector<std::string> pkgConfigValues;
RTT::plugin::PluginLoader &loader(*RTT::plugin::PluginLoader::Instance());
if(componentName == "rtt-types" || componentName == "orocos" )
{
//special case, rtt does not follow the convention below
if(!PkgConfigHelper::parsePkgConfig("orocos-rtt-" xstr(OROCOS_TARGET) ".pc", pkgConfigFields, pkgConfigValues))
throw std::runtime_error("Could not load pkgConfig file for typekit for component " + componentName);
if(!loader.loadTypekits(pkgConfigValues[0] + "/lib/orocos/gnulinux/"))
throw std::runtime_error("Error, failed to load rtt basis typekits");
if(!loader.loadPlugins(pkgConfigValues[0] + "/lib/orocos/gnulinux/"))
throw std::runtime_error("Error, failed to load rtt basis plugins");
return true;
}
if(!PkgConfigHelper::parsePkgConfig(componentName + std::string("-typekit-") + xstr(OROCOS_TARGET) + std::string(".pc"), pkgConfigFields, pkgConfigValues))
throw std::runtime_error("Could not load pkgConfig file for typekit for component " + componentName);
std::string libDir = pkgConfigValues[1];
if(!PkgConfigHelper::solveString(libDir, "${prefix}", pkgConfigValues[0]))
throw std::runtime_error("Internal Error while parsing pkgConfig file");
if(!loader.loadLibrary(libDir + "/lib" + componentName + "-typekit-" xstr(OROCOS_TARGET) ".so"))
throw std::runtime_error("Error, could not load typekit for component " + componentName);
for(const std::string &transport: knownTransports)
{
if(!PkgConfigHelper::parsePkgConfig(componentName + "-typekit-" xstr(OROCOS_TARGET) ".pc", pkgConfigFields, pkgConfigValues))
throw std::runtime_error("Could not load pkgConfig file for transport " + transport + " for component " + componentName);
std::string libDir = pkgConfigValues[1];
if(!PkgConfigHelper::solveString(libDir, "${prefix}", pkgConfigValues[0]))
throw std::runtime_error("Internal Error while parsing pkgConfig file");
RTT::plugin::PluginLoader &loader(*RTT::plugin::PluginLoader::Instance());
if(!loader.loadLibrary(libDir + "/lib" + componentName + "-transport-" + transport + "-" xstr(OROCOS_TARGET) ".so"))
throw std::runtime_error("Error, could not load transport " + transport + " for component " + componentName);
}
return true;
}
//This method loads all typkits required for a task model.
bool PluginHelper::loadAllTypekitsForModel(const std::string &modelName){
std::string componentName = modelName.substr(0, modelName.find_first_of(':'));
std::vector<std::string> neededTks = PluginHelper::getNeededTypekits(componentName);
bool retVal = false;
for(const std::string &tk: neededTks)
{
if(RTT::types::TypekitRepository::hasTypekit(tk))
continue;
retVal = true;
PluginHelper::loadTypekitAndTransports(tk);
}
return retVal;
}