42 #include <boost/filesystem.hpp> 43 #include <boost/version.hpp> 69 static const std::string
SO_EXT(
".dylib");
73 static const std::string
SO_EXT(
".dll");
80 static const std::string
SO_EXT(
".so");
109 if (!ext.empty() && (
'.' == ext[0]))
111 std::istringstream iss;
114 iss.str(ext.substr((
size_t)1));
115 iss >> std::dec >> std::noskipws >> i;
116 isExtensionVersion = !iss.fail() && iss.eof();
145 bool isLoadable =
false;
147 #if defined(__APPLE__) 149 #if BOOST_VERSION >= 104600 150 ext = filename.extension().string();
152 ext = filename.extension();
155 if (0 == ext.compare(
SO_EXT))
160 path name = filename.stem();
161 path ext = name.extension();
175 (filename.extension() ==
SO_EXT) &&
176 !filename.stem().empty();
185 static vector<string> splitPaths(
string const& str)
187 vector<string> paths;
190 string::size_type lastPos = str.find_first_not_of(
delimiters, 0);
192 string::size_type pos = str.find_first_of(
delimiters, lastPos);
194 while (string::npos != pos || string::npos != lastPos)
197 if ( !str.substr(lastPos, pos - lastPos).empty() )
198 paths.push_back(str.substr(lastPos, pos - lastPos));
200 lastPos = str.find_first_not_of(
delimiters, pos);
205 paths.push_back(
".");
209 static void removeDuplicates(
string& path_list)
211 vector<string> paths;
216 paths = splitPaths( path_list );
219 for(vector<string>::const_iterator it = paths.begin(); it != paths.end(); ++it)
231 result = result.substr(0, result.size() - 1);
233 path_list.swap(result);
242 static string makeShortFilename(
string const& str) {
244 if (str.substr(0,3) ==
"lib")
253 static RTT_UNUSED
bool hasEnding(
string const &fullString,
string const &ending)
255 if (fullString.length() > ending.length()) {
256 return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
274 char* paths = getenv(
"RTT_COMPONENT_PATH");
275 string component_paths;
277 component_paths = paths;
279 if ( !default_comp_path.empty() )
281 removeDuplicates( component_paths );
282 log(
Info) <<
"RTT_COMPONENT_PATH was set to: " << paths <<
" . Searching in: "<< component_paths<<
endlog();
284 component_paths = default_comp_path;
285 removeDuplicates( component_paths );
286 log(
Info) <<
"No RTT_COMPONENT_PATH set. Using default: " << component_paths <<
endlog();
295 void unloadComponents()
321 if (path_list.empty() ) {
322 log(
Error) <<
"import paths: No paths were given for loading ( path_list = '' )."<<
endlog();
327 vector<string> paths;
328 paths = splitPaths( path_list );
330 bool all_good =
true, found =
false;
332 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
338 log(
Info) <<
"Importing directory " << p.string() <<
" ..."<<
endlog();
339 for (directory_iterator itr(p); itr != directory_iterator(); ++itr)
341 log(
Debug) <<
"Scanning file " << itr->path().string() <<
" ...";
345 #if BOOST_VERSION >= 104600 346 libname = itr->path().filename().string();
348 libname = itr->path().filename();
350 if(!isCompatibleComponent(libname))
357 all_good = loadInProcess( itr->path().string(), makeShortFilename(libname ),
true) && all_good;
360 if (!is_regular_file(itr->status()))
366 log(
Debug) <<
"Looking for plugins or typekits in directory " << p.string() <<
" ..."<<
endlog();
370 }
catch (std::exception& e) {
381 throw std::runtime_error(
"Some found plugins could not be loaded !");
394 #if BOOST_VERSION >= 104600 395 return loadInProcess(arg.string(), makeShortFilename( arg.filename().string() ),
true);
397 return loadInProcess(arg.string(), makeShortFilename( arg.filename() ),
true);
402 if ( arg.is_complete() ) {
404 bool ret =
import(package);
406 if ( arg.parent_path().leaf() != OROCOS_TARGET_NAME )
407 ret =
import( (arg / OROCOS_TARGET_NAME).string() ) || ret;
412 log(
Error) <<
"Could not import absolute path '"<<
package << "': nothing found."<<endlog();
416 if ( isImported(package) ) {
417 log(
Info) <<
"Component package '"<<
package <<"' already imported." <<endlog();
422 return importInstalledPackage(package, path_list);
427 RTT::Logger::In in(
"ComponentLoader::importInstalledPackage(package, path_list)");
431 vector<string> tryouts;
432 if (path_list.empty())
437 bool path_found =
false;
441 vector<string> vpaths;
442 vpaths = splitPaths(paths);
447 if (is_directory( p )) {
451 if ( p.is_complete() ) {
458 for(vector<string>::iterator it = vpaths.begin(); !path_found && it != vpaths.end(); ++it) {
462 if (is_directory( p )) {
466 tryouts.push_back( p.string() );
468 p = p / OROCOS_TARGET_NAME / package;
470 if (is_directory( p )) {
474 tryouts.push_back( p.string() );
477 paths.erase( paths.size() - 1 );
481 if (
import(paths) ) {
482 loadedPackages.push_back( package );
485 log(
Error) <<
"Failed to import components, types or plugins from package or directory '"<<
package <<"' found in:"<< endlog();
490 log(
Error) <<
"No such package or directory found in search path: " <<
package << ". Search path is: " << trypaths << endlog();
491 log(
Error) <<
"Directories searched include the following: " <<
endlog();
492 for(vector<string>::iterator it=tryouts.begin(); it != tryouts.end(); ++it)
501 #if BOOST_VERSION >= 104600 502 if (is_regular_file( arg ) && reloadInProcess( arg.string(), makeShortFilename( arg.filename().string() ) ) )
504 if (is_regular_file( arg ) && reloadInProcess( arg.string(), makeShortFilename( arg.filename() ) ) )
515 #if BOOST_VERSION >= 104600 516 if (is_regular_file( arg ) && loadInProcess( arg.string(), makeShortFilename( arg.filename().string() ),
true ) )
518 if (is_regular_file( arg ) && loadInProcess( arg.string(), makeShortFilename( arg.filename() ),
true ) )
522 if ( arg.is_complete() )
526 vector<string> paths = splitPaths( component_path );
527 vector<string> tryouts( paths.size() * 4 );
529 path dir = arg.parent_path();
530 #if BOOST_VERSION >= 104600 531 string file = arg.filename().string();
533 string file = arg.filename();
536 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
539 tryouts.push_back( p.string() );
540 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
543 tryouts.push_back( p.string() );
544 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
547 tryouts.push_back( p.string() );
548 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
551 tryouts.push_back( p.string() );
552 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
555 log(
Debug) <<
"No such library found in path: " << name <<
". Tried:"<<
endlog();
556 for(vector<string>::iterator it=tryouts.begin(); it != tryouts.end(); ++it)
565 if (find(loadedPackages.begin(), loadedPackages.end(), type_name) != loadedPackages.end())
583 std::vector<LoadedLib>::iterator lib = loadedLibs.begin();
584 while (lib != loadedLibs.end()) {
586 if ( lib->filename == file) {
587 log(
Info) <<
"Component library "<< lib->filename <<
" already loaded... " ;
589 bool can_unload =
true;
590 CompList::iterator cit;
591 for( std::vector<std::string>::iterator ctype = lib->components_type.begin(); ctype != lib->components_type.end() && can_unload; ++ctype) {
592 for ( cit = comps.begin(); cit != comps.end(); ++cit) {
593 if( (*ctype) == cit->second.type ) {
595 log(
Info) <<
"can NOT reload library because of the instance " << cit->second.type <<
"::"<<cit->first <<
endlog();
604 std::vector<LoadedLib>::iterator lib_un = lib;
605 loadedLibs.erase(lib_un);
606 return loadInProcess(file, libname,
true);
613 log(
Error) <<
"Can't reload Component library "<< file <<
" since it was not loaded or is not a component library." <<
endlog();
625 if(!isCompatibleComponent(file))
628 log(
Error) <<
"Could not load library '"<< p.string() <<
"': incompatible." <<
endlog();
636 log(
Error) <<
"Could not load library '"<< p.string() <<
"':"<<
endlog();
644 LoadedLib loading_lib(file, libname, handle);
649 vector<string> (*getcomponenttypes)(void) = 0;
651 getfactory = (
FactoryMap*(*)(void))(
dlsym(handle,
"getComponentFactoryMap") );
652 if ((error =
dlerror()) == NULL) {
654 fmap = (*getfactory)();
656 log(
Info) <<
"Loaded multi component library '"<< file <<
"'"<<
endlog();
657 getcomponenttypes = (vector<string>(*)(void))(
dlsym(handle,
"getComponentTypeNames"));
658 if ((error =
dlerror()) == NULL) {
660 vector<string> ctypes = getcomponenttypes();
661 for (vector<string>::iterator it = ctypes.begin(); it != ctypes.end(); ++it)
665 loadedLibs.push_back(loading_lib);
673 std::string(*tname)(void) = 0;
677 if (error) create_error = error;
678 tname = (std::string(*)(void))(
dlsym(handle,
"getComponentType") );
679 string gettype_error;
681 if (error) gettype_error = error;
682 if ( factory && tname ) {
683 std::string cname = (*tname)();
685 log(
Warning) <<
"Component type name "<<cname<<
" already used: overriding."<<
endlog();
688 log(
Info) <<
"Loaded component type '"<< cname <<
"'"<<
endlog();
690 loadedLibs.push_back(loading_lib);
694 if (success)
return true;
697 if (!create_error.empty())
699 if (!gettype_error.empty())
706 vector<string> names;
707 FactoryMap::iterator it;
709 names.push_back( it->first );
715 string ret = component_path;
723 component_path = newpath;
731 log(
Debug) <<
"Trying to create component "<< name <<
" of type "<< type <<
endlog();
737 log(
Error) <<
"Found empty factory for Component type "<<type<<
endlog();
745 log(
Error) <<
"Unable to create Orocos Component '"<<type<<
"': unknown component type." <<
endlog();
749 comps[name].type = type;
752 comps[name].instance = instance = (*factory)(name);
754 log(
Error) <<
"The constructor of component type "<<type<<
" threw an exception!"<<
endlog();
757 if ( instance == 0 ) {
758 log(
Error) <<
"Failed to load component with name "<<name<<
": refused to be created."<<
endlog();
766 CompList::iterator it = comps.begin();
767 for(; it != comps.end(); ++it ) {
768 if ( it->second.instance == tc)
break;
771 if ( it != comps.end() ) {
772 delete it->second.instance;
776 log(
Error) <<
"Refusing to unload a component I didn't load myself."<<
endlog();
782 vector<string> names( comps.size() );
783 for(map<string,ComponentData>::const_iterator it = comps.begin(); it != comps.end(); ++it)
784 names.push_back( it->first );
792 #if BOOST_VERSION >= 104600 793 string libname = p.filename().string();
795 string libname = p.filename();
static bool hasTypekit(const std::string &typekitname)
TaskContext *(* ComponentLoaderSignature)(std::string instance_name)
static const char default_delimiter(':')
void * dlsym(void *handle, const char *name)
bool loadInProcess(std::string filename, std::string shortname, bool log_error)
bool isImported(std::string type_name)
RTT::TaskContext * loadComponent(std::string const &name, std::string const &type)
void addFactory(std::string const &name, ComponentLoaderSignature factory)
static RTT_UNUSED bool hasEnding(string const &fullString, string const &ending)
static boost::shared_ptr< ComponentLoader > instance2
static RTT_UNUSED bool isExtensionVersion(const std::string &ext)
static RTT_HIDE FactoryMap & Instance()
static boost::shared_ptr< ComponentLoader > Instance()
std::map< std::string, ComponentLoaderSignature > FactoryMap
void * dlopen(const char *file, int mode)
char const * default_comp_path_build
static const std::string FULL_COMPONENT_SUFFIX(string("-")+string(OROCOS_TARGET_NAME)+SO_POSTFIX+SO_EXT)
std::vector< std::string > listComponents() const
static RTT_HIDE FactoryMap * Factories
std::string getComponentPath() const
bool loadLibrary(std::string const &path)
bool import(std::string const &path_list)
static const std::string SO_EXT(".so")
int dlclose(void *handle)
std::vector< std::string > listComponentTypes() const
bool reloadLibrary(std::string const &filepath)
void setComponentPath(std::string const &newpath)
static const std::string SO_POSTFIX("")
std::vector< std::string > components_type
bool unloadComponent(RTT::TaskContext *tc)
static boost::shared_ptr< PluginLoader > Instance()
bool importInstalledPackage(std::string const &package, std::string const &path_list)
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
static const std::string delimiters(":;")
bool reloadInProcess(std::string filename, std::string shortname)
static Logger::LogFunction endlog()
const FactoryMap & getFactories() const
static bool isLoadableLibrary(const path &filename)
bool isCompatibleComponent(std::string const &filepath)