26 #include "boost/tokenizer.hpp"
28 #include "boost/algorithm/string.hpp"
29 #include <boost/regex.hpp>
32 #include "TClassEdit.h"
35 #include "GaudiKernel/System.h"
37 namespace fs = std::filesystem;
40 typedef std::vector<std::string> Strings_t;
41 const std::string RootMap =
".rootmap";
42 const std::string Components =
".components";
43 const std::string PluginNs=
"__pf__";
46 const std::string SHLIB_PREFIX =
"lib";
47 const std::string SHLIB_SUFFIX =
".dll";
49 const std::string SHLIB_PREFIX =
"lib";
50 const std::string SHLIB_SUFFIX =
".so";
54 bool is_rootcint_dict(
const std::string& libname)
56 if (libname ==
"liblistDict.so")
return true;
57 if (libname ==
"libmapDict.so")
return true;
58 if (libname ==
"libmap2Dict.so")
return true;
59 if (libname ==
"libmultimapDict.so")
return true;
60 if (libname ==
"libsetDict.so")
return true;
61 if (libname ==
"libvectorDict.so")
return true;
62 if (libname ==
"libCore.so")
return true;
63 if (libname ==
"libMathCore.so")
return true;
65 static const std::string dll =
".dll";
70 return !libname.starts_with(SHLIB_PREFIX) &&
71 boost::regex_match(libname,
e);
80 std::string getlibname(
const std::string& libname)
82 std::string lib = libname;
83 if (!lib.starts_with(
"lib")) {
84 lib = std::string(
"lib") + lib;
86 if (!lib.ends_with(SHLIB_SUFFIX)) {
92 const std::set<std::string>&
95 static const std::set<std::string>
s = {
125 "unsigned long long",
138 const std::map<std::string, std::string>&
141 static const std::map<std::string, std::string>
s =
142 {{
"ElementLinkInt_p1",
"ElementLink_p1<unsigned int>"},
143 {
"basic_string<char>",
"string"},
144 {
"vector<basic_string<char> >",
"vector<string>"},
145 {
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
146 {
"IParticleContainer",
"DataVector<IParticle>"},
151 const std::map<std::string, std::string>&
154 static const std::map<std::string, std::string>
s =
155 {{
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
156 {
"IParticleContainer",
"DataVector<IParticle>"},
165 to_rootmap_name(
const std::string& type_name_)
167 std::string type_name = type_name_;
168 boost::algorithm::replace_all(type_name,
", ",
",");
170 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
175 if (s_cxx_aliases().
find(type_name) != s_cxx_aliases().
end()) {
176 return ::to_rootmap_name(s_cxx_aliases().
find(type_name)->
second);
183 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
184 type_name = TClassEdit::ShortType(type_name.c_str(),
185 TClassEdit::kDropDefaultAlloc|
186 TClassEdit::kDropStd);
188 boost::algorithm::replace_all(type_name,
"basic_string<char> >",
"string>");
189 boost::algorithm::replace_all(type_name,
"basic_string<char>",
"string");
197 to_rflx_name(
const std::string& type_name_)
199 std::string type_name = type_name_;
200 boost::algorithm::replace_all(type_name,
", ",
",");
202 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
207 if (s_cxx_typedefs().
find(type_name) != s_cxx_typedefs().
end()) {
208 return ::to_rflx_name(s_cxx_typedefs().
find(type_name)->
second);
214 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
215 type_name = TClassEdit::ShortType(type_name.c_str(),
216 TClassEdit::kDropDefaultAlloc);
219 boost::algorithm::replace_all(type_name,
221 "std::basic_string<char> >");
222 boost::algorithm::replace_all(type_name,
224 "std::basic_string<char>");
265 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
268 const std::string
n = ::to_rootmap_name(type_name);
283 return std::string();
296 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer_t;
297 typedef std::vector<fs::path> Paths_t;
299 std::set<std::string> dsofiles;
301 std::string dsopath = System::getEnv(
"LD_LIBRARY_PATH");
302 std::string rootsys = System::getEnv(
"ROOTSYS");
304 Tokenizer_t tok(dsopath, boost::char_separator<char>(
":"));
310 if (itr->starts_with(rootsys)) {
317 Paths_t dir_content {fs::directory_iterator(
p),
318 fs::directory_iterator()};
319 std::sort(dir_content.begin(),
322 ipath_end = dir_content.end();
327 bool is_components =
false;
328 if (dsomap.extension() == Components)
329 is_components =
true;
330 else if (dsomap.extension() != RootMap)
336 dsofiles.insert(dsomap.c_str());
337 std::ifstream
f(dsomap.c_str());
343 std::getline(
f,
line);
351 else if (
line.compare (0, 8,
"Library.")==0) {
354 boost::is_any_of(
" "),
355 boost::token_compress_on);
357 std::cerr <<
"DsoDb:: **error** could not parse "
358 << dsomap <<
":" << line_nbr
360 <<
"DsoDb:: (some) reflex-dicts may fail to be autoloaded"
365 if (::is_rootcint_dict(libname)) {
369 libname = ::getlibname(libname);
370 boost::algorithm::replace_all(dso_key,
"Library.",
"");
371 boost::algorithm::replace_all(dso_key,
":",
"");
376 else if (
line[0] ==
'[') {
377 libname =
line.substr (1,
line.size()-2);
379 if (::is_rootcint_dict(libname)) {
383 if (!libname.empty())
384 lastlib = ::getlibname (libname);
388 else if (
line.compare(0, 8,
"# --End ")==0) {
393 else if (
line.compare(0, 6,
"class ")==0) {
399 else if (is_components &&
line.compare(0, 3,
"lib") ==0) {
400 std::string::size_type
pos =
line.find (
':');
401 if (
pos == std::string::npos)
continue;
406 if (dso_key.compare(0, 6,
"_PERS_")==0 ||
407 dso_key.compare(0, 7,
"_TRANS_")==0)
410 if (libname.find (
"AthenaPoolPoolCnv") != std::string::npos)
414 if (libname.empty() || dso_key.empty())
continue;
416 const std::string fullpath_libname =
to_string(dsomap.parent_path() /
fs::path(libname));
421 if (dso_key.starts_with(PluginNs) || is_components) {
426 if (
db->find(dso_key) ==
db->end()) {
427 db->insert(std::make_pair(dso_key, Strings_t()));
429 (*db)[dso_key].push_back(fullpath_libname);
443 std::vector<std::string>
448 const std::string libname = ::getlibname(
to_string(
p.filename()));
449 std::set<std::string> caps;
454 for (DsoMap_t::const_iterator
idb =
db->begin(), iend=
db->end();
457 for (Libs_t::const_iterator ilib =
idb->second.begin(),
458 ilibend =
idb->second.end();
462 if (
to_string(lib.filename()) == libname) {
463 caps.insert(
idb->first);
469 return std::vector<std::string>(caps.begin(), caps.end());
478 std::vector<std::string> caps = this->
capabilities(libname);
484 for (DsoMap_t::const_iterator
485 idb = dup_db.begin(),
486 idbend = dup_db.end();
489 if (
std::find(caps.begin(), caps.end(),
idb->first) != caps.end()) {
490 for (Libs_t::const_iterator
491 ilib =
idb->second.begin(),
492 ilibend=
idb->second.end();
498 dups[
idb->first].push_back(*ilib);
530 std::set<std::string>
libs;
535 for (DsoMap_t::const_iterator
idb =
db.begin(), iend=
db.end();
538 for (Libs_t::const_iterator
539 ilib =
idb->second.begin(),
540 ilibend=
idb->second.end();
565 for (DsoMap_t::const_iterator
idb =
d.begin(), idbend=
d.end();
572 std::set<std::string> baselibs;
573 for (Libs_t::const_iterator
574 ilib =
idb->second.begin(),
575 ilibend=
idb->second.end();
579 if (baselibs.find(baselib) == baselibs.end()) {
580 libs.push_back(*ilib);
581 baselibs.insert(baselib);
596 for (DsoMap_t::const_iterator
idb =
db.begin(), iend =
db.end();
599 if (
idb->second.size() == 1) {
606 std::unordered_set<std::string> baselibs;
607 for (Libs_t::const_iterator
608 ilib =
idb->second.begin(),
609 ilend=
idb->second.end();
616 libs.push_back(*ilib);
620 if (
libs.size() > 1) {
630 const std::string rootmap_name = ::to_rootmap_name(type_name);
631 const std::string rflx_name = ::to_rflx_name(type_name);
639 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
643 if (!this->has_type(rootmap_name)) {
644 #ifdef ATH_DSODB_VERBOSE
645 std::cerr <<
"DsoDb **error**: no such type [" << rootmap_name <<
"]"
646 <<
" in rootmap files\n";
650 DsoMap_t::const_iterator
idb = m_db.find(rootmap_name);
651 if (
idb == m_db.end()) {
653 idb = m_pf.find(rootmap_name);
654 if (
idb == m_pf.end()) {
658 const Libs_t&
libs =
idb->second;
660 #ifdef ATH_DSODB_VERBOSE
661 std::cerr <<
"DsoDb **error**: no library hosting [" << type_name <<
"]\n";
666 System::ImageHandle handle;
669 if (libname.starts_with(SHLIB_PREFIX)) {
670 libname = libname.substr(SHLIB_PREFIX.size(), std::string::npos);
672 if (libname.ends_with(SHLIB_SUFFIX)) {
673 libname.resize(libname.size() - SHLIB_SUFFIX.size());
676 unsigned long err = System::loadDynamicLib( libname, &handle );
678 std::cerr <<
"DsoDb **error**: could not load library ["
679 <<
libs[0] <<
"] (" << System::getLastErrorString()