File indexing completed on 2025-01-18 09:14:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cstdlib>
0015 #include <fstream>
0016 #include <iostream>
0017 #include <list>
0018 #include <memory>
0019 #include <set>
0020 #include <string>
0021
0022 #include <dlfcn.h>
0023 #include <getopt.h>
0024
0025 #define GAUDI_PLUGIN_SERVICE_V2
0026 #include <Gaudi/PluginService.h>
0027 #include <Gaudi/PluginServiceV1.h>
0028
0029 void help( std::string argv0 ) {
0030 std::cout << "Usage: " << argv0
0031 << " [option] library1 [library2 ...]\n"
0032 "\n list the component factories present in the given libraries\n\n"
0033 "Options:\n\n"
0034 " -h, --help show this help message and exit\n"
0035 " -o OUTPUT, --output OUTPUT\n"
0036 " write the list of factories on the file OUTPUT, use - for\n"
0037 " standard output (default)\n"
0038 << std::endl;
0039 }
0040
0041 void usage( std::string argv0 ) {
0042 std::cout << "Usage: " << argv0
0043 << " [option] library1 [library2 ...]\n"
0044 "Try `"
0045 << argv0 << " -h' for more information.\n"
0046 << std::endl;
0047 }
0048
0049 int main( int argc, char* argv[] ) {
0050 auto& reg2 = Gaudi::PluginService::v2::Details::Registry::instance();
0051 auto& reg1 = Gaudi::PluginService::v1::Details::Registry::instance();
0052
0053 using key_type = Gaudi::PluginService::v2::Details::Registry::KeyType;
0054
0055
0056 std::map<key_type, std::string> loaded;
0057
0058 for ( const auto& name : reg2.loadedFactoryNames() ) loaded.emplace( name, "<preloaded>" );
0059 for ( const auto& name : reg1.loadedFactoryNames() ) loaded.emplace( name, "<preloaded>" );
0060
0061
0062 std::list<char*> libs;
0063 std::string output_opt( "-" );
0064 {
0065 std::string argv0( argv[0] );
0066 {
0067 auto i = argv0.rfind( '/' );
0068 if ( i != std::string::npos ) argv0 = argv0.substr( i + 1 );
0069 }
0070
0071 int i = 1;
0072 while ( i < argc ) {
0073 const std::string arg( argv[i] );
0074 if ( arg == "-o" || arg == "--output" ) {
0075 if ( ++i < argc ) {
0076 output_opt = argv[i];
0077 } else {
0078 std::cerr << "ERROR: missing argument for option " << arg << std::endl;
0079 std::cerr << "See `" << argv0 << " -h' for more details." << std::endl;
0080 return EXIT_FAILURE;
0081 }
0082 } else if ( arg == "-h" || arg == "--help" ) {
0083 help( argv0 );
0084 return EXIT_SUCCESS;
0085 } else {
0086 libs.push_back( argv[i] );
0087 }
0088 ++i;
0089 }
0090 if ( libs.empty() ) {
0091 usage( std::move(argv0) );
0092 return EXIT_FAILURE;
0093 }
0094 }
0095
0096
0097 std::unique_ptr<std::ostream> output_file;
0098 if ( output_opt != "-" ) { output_file.reset( new std::ofstream{output_opt} ); }
0099 std::ostream& output = ( output_file ? *output_file : std::cout );
0100
0101 auto dump_from = [&output, &loaded]( auto& reg, const char* lib, const char* prefix ) {
0102 for ( const auto& factoryName : reg.loadedFactoryNames() ) {
0103 auto f = loaded.find( factoryName );
0104 if ( f == loaded.end() ) {
0105 output << prefix << "::" << lib << ":" << factoryName << std::endl;
0106 loaded.emplace( factoryName, lib );
0107 } else
0108 std::cerr << "WARNING: factory '" << factoryName << "' already found in " << f->second << std::endl;
0109 }
0110 };
0111
0112
0113 for ( const char* aLib : libs ) {
0114 if ( dlopen( aLib, RTLD_LAZY | RTLD_LOCAL ) ) {
0115 dump_from( reg2, aLib, "v2" );
0116 dump_from( reg1, aLib, "v1" );
0117 } else {
0118 std::cerr << "ERROR: failed to load " << aLib << ": " << dlerror() << std::endl;
0119 return EXIT_FAILURE;
0120 }
0121 }
0122 return EXIT_SUCCESS;
0123 }