33 #include <boost/algorithm/string.hpp>
34 #include <boost/filesystem.hpp>
35 #include <boost/functional/hash.hpp>
45 #define snprintf _snprintf
46 #define pclose _pclose
48 #define PATH_MAX MAX_PATH
49 #if defined(__MINGW32__)
56 #include <sys/types.h>
75 #if PY_VERSION_HEX < 0x03000000
76 #undef PyBytes_AsString
77 #undef PyUnicode_AsUTF8
78 #undef PyUnicode_FromString
79 #define PyBytes_AsString PyString_AsString
80 #define PyUnicode_AsUTF8 PyString_AsString
81 #define PyUnicode_FromString PyString_FromString
89 namespace fs = boost::filesystem;
122 static const std::string
g_ros_os =
"osx";
125 static const std::string
g_ros_os =
"win32";
135 : std::runtime_error(what)
162 const std::string& path,
163 const std::string& manifest_path,
164 const std::string& manifest_name) :
170 manifest_(true, tinyxml2::COLLAPSE_WHITESPACE),
183 tinyxml2::XMLElement* el = root->FirstChildElement(
"name");
185 name_ = el->GetText();
187 std::string tagname_license =
"license";
188 for(el = root->FirstChildElement(tagname_license.c_str()); el; el = el->NextSiblingElement(tagname_license.c_str()))
193 for(el = root->FirstChildElement(
"export"); el; el = el->NextSiblingElement(
"export"))
195 if(el->FirstChildElement(
"metapackage"))
225 size_t start_num_pkgs) :
242 const std::string& cache_prefix,
243 const std::string& name,
244 const std::string& tag) :
245 manifest_name_(manifest_name),
246 cache_prefix_(cache_prefix),
260 for(boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.begin();
274 log(
"Warning", msg, append_errno);
280 log(
"Error", msg, append_errno);
286 char* rpp = getenv(
"ROS_PACKAGE_PATH");
292 const char *path_delim =
";";
294 const char *path_delim = ":";
297 std::vector<std::string> rpp_strings;
298 boost::split(rpp_strings, rpp,
299 boost::is_any_of(path_delim),
300 boost::token_compress_on);
301 for(std::vector<std::string>::const_iterator it = rpp_strings.begin();
302 it != rpp_strings.end();
322 if(!fs::is_directory(path))
325 catch(fs::filesystem_error& e)
327 logWarn(std::string(
"error while looking at ") + path +
": " + e.what());
333 for(fs::directory_iterator dit = fs::directory_iterator(path);
334 dit != fs::directory_iterator();
337 if(!fs::is_regular_file(dit->path()))
348 catch(fs::filesystem_error& e)
352 if(e.code().value() != EACCES)
354 logWarn(std::string(
"error while crawling ") + path +
": " + e.what() +
"; " + e.code().message());
387 std::vector<DirectoryCrawlRecord*> dummy;
388 boost::unordered_set<std::string> dummy2;
389 for(std::vector<std::string>::const_iterator p =
search_paths_.begin();
408 for(fs::path path = fs::current_path();
410 path = path.parent_path())
414 #if !defined(BOOST_FILESYSTEM_VERSION) || (BOOST_FILESYSTEM_VERSION == 2)
415 name = fs::path(path).filename();
418 name = fs::path(path).filename().string();
426 catch(fs::filesystem_error& e)
450 std::set<std::string>& packages)
453 boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.find(name);
456 std::vector<std::string> search_paths;
457 search_paths.push_back(it->second->path_);
458 rp2.
crawl(search_paths,
true);
459 std::set<std::pair<std::string, std::string> > names_paths;
460 rp2.
list(names_paths);
461 for(std::set<std::pair<std::string, std::string> >::const_iterator iit = names_paths.begin();
462 iit != names_paths.end();
464 packages.insert(iit->first);
469 logError(std::string(
"stack ") + name +
" not found");
480 for(boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.begin();
484 std::vector<std::string> search_paths;
485 search_paths.push_back(it->second->path_);
486 rp2.
crawl(search_paths,
true);
487 std::set<std::pair<std::string, std::string> > names_paths;
488 rp2.
list(names_paths);
489 for(std::set<std::pair<std::string, std::string> >::const_iterator iit = names_paths.begin();
490 iit != names_paths.end();
493 if(iit->first == name)
496 path = it->second->path_;
502 logError(std::string(
"stack containing package ") + name +
" not found");
509 for(boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.begin();
513 std::pair<std::string, std::string> item;
514 item.first = it->first;
515 item.second = it->second->path_;
523 dups.resize(
dups_.size());
525 for(boost::unordered_map<std::string, std::vector<std::string> >::const_iterator it =
dups_.begin();
538 for(boost::unordered_map<std::string, std::vector<std::string> >::const_iterator it =
dups_.begin();
542 dups[it->first].resize(it->second.size());
544 for(std::vector<std::string>::const_iterator jt = it->second.begin();
545 jt != it->second.end();
548 dups[it->first][j] = *jt;
556 std::vector<std::string>& deps)
558 std::vector<Stackage*> stackages;
573 for(std::vector<Stackage*>::const_iterator it = stackages.begin();
574 it != stackages.end();
576 deps.push_back((*it)->name_);
582 std::vector<std::string>& deps)
584 std::vector<Stackage*> stackages;
586 for(std::vector<Stackage*>::const_iterator it = stackages.begin();
587 it != stackages.end();
589 deps.push_back((*it)->name_);
595 std::vector<std::string>& deps)
604 std::vector<Stackage*> deps_vec;
605 boost::unordered_set<Stackage*> deps_hash;
606 std::vector<std::string> indented_deps;
608 for(std::vector<std::string>::const_iterator it = indented_deps.begin();
609 it != indented_deps.end();
623 const std::string& to,
634 std::list<std::list<Stackage*> > acc_list;
644 output.append(std::string(
"Dependency chains from ") +
645 from +
" to " + to +
":\n");
646 for(std::list<std::list<Stackage*> >::const_iterator it = acc_list.begin();
647 it != acc_list.end();
651 for(std::list<Stackage*>::const_iterator iit = it->begin();
655 if(iit != it->begin())
656 output.append(
"-> ");
657 output.append((*iit)->name_ +
" ");
666 std::vector<std::string>& manifests)
675 std::vector<Stackage*> deps_vec;
677 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
678 it != deps_vec.end();
680 manifests.push_back((*it)->manifest_path_);
692 std::set<std::string>& rosdeps)
701 std::vector<Stackage*> deps_vec;
703 deps_vec.push_back(stackage);
706 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
707 it != deps_vec.end();
742 for(tinyxml2::XMLElement* ele = root->FirstChildElement(tag_name);
744 ele = ele->NextSiblingElement(tag_name))
751 rosdeps.insert(std::string(
"name: ") + att_str);
756 const char* dep_pkgname = ele->GetText();
759 rosdeps.insert(std::string(
"name: ") + dep_pkgname);
767 std::vector<std::string>& vcs)
776 std::vector<Stackage*> deps_vec;
778 deps_vec.push_back(stackage);
781 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
782 it != deps_vec.end();
794 result.append(
"type: ");
795 result.append(att_str);
799 result.append(
"\turl: ");
800 result.append(att_str);
802 vcs.push_back(result);
816 const std::string& attrib,
bool deps_only,
817 std::vector<std::pair<std::string, bool> >& flags)
823 static bool init_py =
false;
824 static PyObject* pName;
825 static PyObject* pModule;
826 static PyObject* pDict;
827 static PyObject* pFunc;
833 std::vector<Stackage*> deps_vec;
835 deps_vec.push_back(stackage);
837 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
838 it != deps_vec.end();
841 if(!(*it)->is_wet_package_)
843 std::vector<std::string> dry_flags;
848 for(std::vector<std::string>::const_iterator it = dry_flags.begin(); it != dry_flags.end(); ++it)
850 flags.push_back(std::pair<std::string, bool>(*it,
false));
856 PyGILState_STATE gstate = PyGILState_Ensure();
862 pModule = PyImport_Import(pName);
866 PyGILState_Release(gstate);
867 std::string errmsg =
"could not find python module 'rosdep2.rospack'. is rosdep up-to-date (at least 0.10.4)?";
870 pDict = PyModule_GetDict(pModule);
871 pFunc = PyDict_GetItemString(pDict,
"call_pkg_config");
874 if(!PyCallable_Check(pFunc))
877 PyGILState_Release(gstate);
878 std::string errmsg =
"could not find python function 'rosdep2.rospack.call_pkg_config'. is rosdep up-to-date (at least 0.10.7)?";
882 PyObject* pArgs = PyTuple_New(2);
884 PyTuple_SetItem(pArgs, 0, pOpt);
886 PyTuple_SetItem(pArgs, 1, pPkg);
887 PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
893 PyGILState_Release(gstate);
894 std::string errmsg =
"could not call python function 'rosdep2.rospack.call_pkg_config'";
897 if(pValue == Py_None)
900 std::string errmsg =
"python function 'rosdep2.rospack.call_pkg_config' could not call 'pkg-config " + type +
" " + (*it)->name_ +
"' without errors";
904 flags.push_back(std::pair<std::string, bool>(
PyBytes_AsString(pValue),
true));
914 PyGILState_Release(gstate);
929 static bool init_py =
false;
930 static PyObject* pName;
931 static PyObject* pModule;
932 static PyObject* pFunc;
935 PyGILState_STATE gstate = PyGILState_Ensure();
941 pModule = PyImport_Import(pName);
945 PyGILState_Release(gstate);
946 std::string errmsg =
"could not find python module 'catkin_pkg.rospack'. is catkin_pkg up-to-date (at least 0.1.8)?";
949 PyObject* pDict = PyModule_GetDict(pModule);
950 pFunc = PyDict_GetItemString(pDict,
"reorder_paths");
953 if(!PyCallable_Check(pFunc))
956 PyGILState_Release(gstate);
957 std::string errmsg =
"could not find python function 'catkin_pkg.rospack.reorder_paths'. is catkin_pkg up-to-date (at least 0.1.8)?";
962 PyObject* pArgs = PyTuple_New(1);
964 PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
970 PyGILState_Release(gstate);
971 std::string errmsg =
"could not call python function 'catkin_pkg.rospack.reorder_paths'";
985 PyGILState_Release(gstate);
992 const std::string& attrib,
bool deps_only,
993 std::vector<std::string>& flags)
1002 std::vector<Stackage*> deps_vec;
1004 deps_vec.push_back(stackage);
1006 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
1007 it != deps_vec.end();
1026 const std::string& attrib,
1027 std::vector<std::string>& flags)
1034 bool os_match =
false;
1035 const char *best_match = NULL;
1036 for(tinyxml2::XMLElement* ele2 = ele->FirstChildElement(lang.c_str());
1038 ele2 = ele2->NextSiblingElement(lang.c_str()))
1041 if ((os_str = ele2->Attribute(
"os")))
1043 if(
g_ros_os == std::string(os_str))
1046 logWarn(std::string(
"ignoring duplicate ") + lang +
" tag with os=" + os_str +
" in export block");
1049 best_match = ele2->Attribute(attrib.c_str());
1057 best_match = ele2->Attribute(attrib.c_str());
1059 logWarn(std::string(
"ignoring duplicate ") + lang +
" tag in export block");
1065 std::string expanded_str;
1068 flags.push_back(expanded_str);
1074 if((lang ==
"cpp") && (attrib ==
"cflags"))
1080 msg_gen /= fs::path(
"cpp") /
"include";
1081 flags.push_back(std::string(
"-I" + msg_gen.string()));
1085 srv_gen /= fs::path(
"cpp") /
"include";
1086 flags.push_back(std::string(
"-I" + srv_gen.string()));
1094 const std::string& top,
1095 std::vector<std::string>& flags)
1098 std::vector<Stackage*> stackages;
1099 bool result =
depsOnDetail(name,
true, stackages,
true);
1101 boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.find(name);
1105 stackages.push_back(it->second);
1111 std::vector<Stackage*> top_deps;
1113 boost::unordered_set<Stackage*> top_deps_set;
1114 for(std::vector<Stackage*>::iterator it = top_deps.begin();
1115 it != top_deps.end();
1117 top_deps_set.insert(*it);
1118 std::vector<Stackage*>::iterator it = stackages.begin();
1119 while(it != stackages.end())
1121 if((*it)->name_ != top &&
1122 (top_deps_set.find(*it) == top_deps_set.end()))
1123 it = stackages.erase(it);
1129 for(std::vector<Stackage*>::const_iterator it = stackages.begin();
1130 it != stackages.end();
1138 for(tinyxml2::XMLElement* ele2 = ele->FirstChildElement(name.c_str());
1140 ele2 = ele2->NextSiblingElement(name.c_str()))
1142 const char *att_str;
1143 if((att_str = ele2->Attribute(attrib.c_str())))
1145 std::string expanded_str;
1151 flags.push_back((*it)->name_ +
" " + expanded_str);
1161 std::vector<std::string>& gens)
1170 std::vector<Stackage*> deps_vec;
1172 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
1173 it != deps_vec.end();
1176 fs::path msg_gen = fs::path((*it)->path_) /
1179 fs::path srv_gen = fs::path((*it)->path_) /
1182 if(fs::is_regular_file(msg_gen))
1183 gens.push_back(msg_gen.string());
1184 if(fs::is_regular_file(srv_gen))
1185 gens.push_back(srv_gen.string());
1202 const std::string& msg,
1207 fprintf(stderr,
"[%s] %s: %s",
1208 name_.c_str(), level.c_str(), msg.c_str());
1210 fprintf(stderr,
": %s", strerror(errno));
1211 fprintf(stderr,
"\n");
1234 std::vector<Stackage*>& deps)
1240 logError(std::string(
"no such package ") + name);
1248 std::vector<Stackage*> deps_vec;
1250 for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
1251 it != deps_vec.end();
1253 deps.push_back(*it);
1266 std::list<std::list<Stackage*> >& acc_list)
1269 for(std::vector<Stackage*>::const_iterator it = from->
deps_.begin();
1270 it != from->
deps_.end();
1273 if((*it)->name_ == to->
name_)
1275 std::list<Stackage*> acc;
1276 acc.push_back(from);
1278 acc_list.push_back(acc);
1282 std::list<std::list<Stackage*> > l;
1284 for(std::list<std::list<Stackage*> >::iterator iit = l.begin();
1288 iit->push_front(from);
1289 acc_list.push_back(*iit);
1298 std::vector<Stackage*>& deps,
bool ignore_missing)
1304 logError(std::string(
"no such package ") + name);
1309 for(boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.begin();
1314 std::vector<Stackage*> deps_vec;
1316 for(std::vector<Stackage*>::const_iterator iit = deps_vec.begin();
1317 iit != deps_vec.end();
1320 if((*iit)->name_ == name)
1322 deps.push_back(it->second);
1340 std::vector<std::string>& dirs)
1343 std::vector<DirectoryCrawlRecord*> dcrs;
1344 boost::unordered_set<std::string> dcrs_hash;
1345 for(std::vector<std::string>::const_iterator p = search_path.begin();
1346 p != search_path.end();
1355 snprintf(buf,
sizeof(buf),
"%.6f", total);
1356 dirs.push_back(std::string(
"Full tree crawl took ") + buf +
" seconds.");
1357 dirs.push_back(
"Directories marked with (*) contain no manifest. You may");
1358 dirs.push_back(
"want to delete these directories.");
1359 dirs.push_back(
"To get just of list of directories without manifests,");
1360 dirs.push_back(
"re-run the profile with --zombie-only");
1361 dirs.push_back(
"-------------------------------------------------------------");
1364 std::reverse(dcrs.begin(), dcrs.end());
1366 for(std::vector<DirectoryCrawlRecord*>::const_iterator it = dcrs.begin();
1374 if(length < 0 || i < length)
1375 dirs.push_back((*it)->path_);
1382 snprintf(buf,
sizeof(buf),
"%.6f", (*it)->crawl_time_);
1383 if(length < 0 || i < length)
1384 dirs.push_back(std::string(buf) +
" " +
1385 ((*it)->zombie_ ?
"* " :
" ") +
1399 #if !defined(BOOST_FILESYSTEM_VERSION) || (BOOST_FILESYSTEM_VERSION == 2)
1400 std::string name = fs::path(path).filename();
1403 std::string name = fs::path(path).filename().string();
1409 if(fs::is_regular_file(dry_manifest_path))
1413 else if(fs::is_regular_file(wet_manifest_path))
1439 std::vector<std::string> dups;
1455 bool collect_profile_data,
1456 std::vector<DirectoryCrawlRecord*>& profile_data,
1457 boost::unordered_set<std::string>& profile_hash)
1460 throw Exception(
"maximum depth exceeded during crawl");
1464 if(!fs::is_directory(path))
1467 catch(fs::filesystem_error& e)
1469 logWarn(std::string(
"error while looking at ") + path +
": " + e.what());
1476 if(fs::is_regular_file(catkin_ignore))
1479 catch(fs::filesystem_error& e)
1481 logWarn(std::string(
"error while looking for ") + catkin_ignore.string() +
": " + e.what());
1493 if(fs::is_regular_file(nosubdirs))
1496 catch(fs::filesystem_error& e)
1498 logWarn(std::string(
"error while looking for ") + nosubdirs.string() +
": " + e.what());
1507 if(fs::is_regular_file(rospack_manifest))
1510 catch(fs::filesystem_error& e)
1512 logWarn(std::string(
"error while looking for ") + rospack_manifest.string() +
": " + e.what());
1516 if(collect_profile_data)
1518 if(profile_hash.find(path) == profile_hash.end())
1523 profile_data.push_back(dcr);
1524 profile_hash.insert(path);
1530 for(fs::directory_iterator dit = fs::directory_iterator(path);
1531 dit != fs::directory_iterator();
1534 if(fs::is_directory(dit->path()))
1536 #if !defined(BOOST_FILESYSTEM_VERSION) || (BOOST_FILESYSTEM_VERSION == 2)
1537 std::string name = dit->path().filename();
1540 std::string name = dit->path().filename().string();
1543 if(name.size() == 0 || name[0] ==
'.')
1547 collect_profile_data, profile_data, profile_hash);
1551 catch(fs::filesystem_error& e)
1555 if(e.code().value() != EACCES)
1557 logWarn(std::string(
"error while crawling ") + path +
": " + e.what());
1561 if(collect_profile_data && dcr != NULL)
1580 std::string errmsg = std::string(
"error parsing manifest of package ") +
1600 if(!ignore_errors && !
quiet_)
1624 tinyxml2::XMLElement* root;
1628 const char* dep_pkgname;
1629 for(tinyxml2::XMLElement *dep_ele = root->FirstChildElement(depend_tag.c_str());
1631 dep_ele = dep_ele->NextSiblingElement(depend_tag.c_str()))
1635 dep_pkgname = dep_ele->Attribute(
tag_.c_str());
1639 dep_pkgname = dep_ele->GetText();
1644 if(!ignore_errors && !
quiet_)
1646 std::string errmsg = std::string(
"bad depend syntax (no 'package/stack' attribute) in manifest ") + stackage->
name_ +
" at " + stackage->
manifest_path_;
1650 else if(dep_pkgname == stackage->
name_)
1653 if(!ignore_errors && !
quiet_)
1669 stackage->
deps_.push_back(dep);
1673 std::string errmsg =
get_manifest_type() +
" '" + stackage->
name_ +
"' depends on non-existent package '" + dep_pkgname +
"' and rosdep claims that it is not a system dependency. Check the ROS_PACKAGE_PATH or try calling 'rosdep update'";
1680 if (std::find(stackage->
deps_.begin(), stackage->
deps_.end(), dep) == stackage->
deps_.end())
1682 stackage->
deps_.push_back(dep);
1683 result &=
computeDeps(dep, ignore_errors, ignore_missing);
1693 static bool initialized =
false;
1704 static std::map<std::string, bool> cache;
1705 if(cache.find(pkgname) != cache.end())
1707 return cache.find(pkgname)->second;
1711 PyGILState_STATE gstate = PyGILState_Ensure();
1713 static PyObject* pModule = 0;
1714 static PyObject* pDict = 0;
1718 pModule = PyImport_Import(pName);
1723 PyGILState_Release(gstate);
1724 std::string errmsg =
"could not find python module 'rosdep2.rospack'. is rosdep up-to-date (at least 0.10.4)?";
1727 pDict = PyModule_GetDict(pModule);
1730 static PyObject* pView = 0;
1733 PyObject* pFunc = PyDict_GetItemString(pDict,
"init_rospack_interface");
1734 if(!PyCallable_Check(pFunc))
1737 PyGILState_Release(gstate);
1738 std::string errmsg =
"could not find python function 'rosdep2.rospack.init_rospack_interface'. is rosdep up-to-date (at least 0.10.4)?";
1741 pView = PyObject_CallObject(pFunc, NULL);
1745 PyGILState_Release(gstate);
1746 std::string errmsg =
"could not call python function 'rosdep2.rospack.init_rospack_interface'";
1750 static bool rospack_view_not_empty =
false;
1751 if(!rospack_view_not_empty)
1753 PyObject* pFunc = PyDict_GetItemString(pDict,
"is_view_empty");
1754 if(!PyCallable_Check(pFunc))
1757 PyGILState_Release(gstate);
1758 std::string errmsg =
"could not find python function 'rosdep2.rospack.is_view_empty'. is rosdep up-to-date (at least 0.10.8)?";
1761 PyObject* pArgs = PyTuple_New(1);
1762 PyTuple_SetItem(pArgs, 0, pView);
1763 PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
1766 if(PyObject_IsTrue(pValue))
1769 PyGILState_Release(gstate);
1770 std::string errmsg =
"the rosdep view is empty: call 'sudo rosdep init' and 'rosdep update'";
1773 rospack_view_not_empty =
true;
1776 PyObject* pFunc = PyDict_GetItemString(pDict,
"is_system_dependency");
1777 if(!PyCallable_Check(pFunc))
1780 PyGILState_Release(gstate);
1781 std::string errmsg =
"could not call python function 'rosdep2.rospack.is_system_dependency'. is rosdep up-to-date (at least 0.10.4)?";
1785 PyObject* pArgs = PyTuple_New(2);
1786 PyTuple_SetItem(pArgs, 0, pView);
1788 PyTuple_SetItem(pArgs, 1, pDep);
1789 PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
1793 bool value = PyObject_IsTrue(pValue);
1803 PyGILState_Release(gstate);
1805 cache[pkgname] = value;
1813 std::vector<Stackage*>& deps,
1814 bool no_recursion_on_wet)
1816 boost::unordered_set<Stackage*> deps_hash;
1817 std::vector<std::string> indented_deps;
1819 deps_hash,
deps,
false, indented_deps, no_recursion_on_wet);
1825 boost::unordered_set<Stackage*>& deps_hash,
1826 std::vector<Stackage*>& deps,
1827 bool get_indented_deps,
1828 std::vector<std::string>& indented_deps,
1829 bool no_recursion_on_wet,
1830 std::vector<std::string>& dep_chain)
1839 for(std::vector<Stackage*>::const_iterator it = stackage->
deps_.begin();
1840 it != stackage->
deps_.end();
1842 deps.push_back(*it);
1848 for(std::vector<std::string>::const_iterator it = dep_chain.begin();
1849 it != dep_chain.end();
1852 std::vector<std::string>::const_iterator begin = dep_chain.begin();
1853 std::vector<std::string>::const_iterator cycle_begin = std::find(begin, it, *it);
1854 if(cycle_begin != it) {
1856 for(std::vector<std::string>::const_iterator jt = cycle_begin; jt != it; ++jt) {
1857 if(jt != cycle_begin) cycle +=
", ";
1863 throw Exception(std::string(
"maximum dependency depth exceeded (likely circular dependency") + cycle +
")");
1866 for(std::vector<Stackage*>::const_iterator it = stackage->
deps_.begin();
1867 it != stackage->
deps_.end();
1870 if(get_indented_deps)
1872 std::string indented_dep;
1873 for(
int i=0; i<depth; i++)
1874 indented_dep.append(
" ");
1875 indented_dep.append((*it)->name_);
1876 indented_deps.push_back(indented_dep);
1879 bool first = (deps_hash.find(*it) == deps_hash.end());
1882 deps_hash.insert(*it);
1886 deps.push_back(*it);
1888 if(!(*it)->is_wet_package_ || !no_recursion_on_wet)
1893 dep_chain.push_back((*it)->name_);
1895 get_indented_deps, indented_deps,
1896 no_recursion_on_wet, dep_chain);
1897 dep_chain.pop_back();
1902 deps.push_back(*it);
1911 boost::unordered_set<Stackage*>& deps_hash,
1912 std::vector<Stackage*>& deps,
1913 bool get_indented_deps,
1914 std::vector<std::string>& indented_deps,
1915 bool no_recursion_on_wet)
1917 std::vector<std::string> dep_chain;
1918 dep_chain.push_back(stackage->
name_);
1925 no_recursion_on_wet,
1932 fs::path cache_path;
1934 char* ros_home = getenv(
"ROS_HOME");
1936 cache_path = ros_home;
1943 char* home_drive = getenv(
"HOMEDRIVE");
1944 char* home_path = getenv(
"HOMEPATH");
1945 if(home_drive && home_path)
1946 cache_path = fs::path(home_drive) / fs::path(home_path) / fs::path(
DOTROS_NAME);
1949 struct passwd* passwd_ent;
1951 if((passwd_ent = getpwuid(geteuid())))
1952 home_path = passwd_ent->pw_dir;
1954 home_path = getenv(
"HOME");
1956 cache_path = fs::path(home_path) / fs::path(
DOTROS_NAME);
1963 if(!fs::is_directory(cache_path))
1965 fs::create_directory(cache_path);
1968 catch(fs::filesystem_error& e)
1970 logWarn(std::string(
"cannot create rospack cache directory ") +
1971 cache_path.string() +
": " + e.what());
1974 return cache_path.string();
1981 char* rpp = getenv(
"ROS_PACKAGE_PATH");
1983 boost::hash<std::string> hash_func;
1984 value = hash_func(rpp);
1987 snprintf(buffer, 21,
"%020lu", value);
2000 char linebuf[30000];
2003 if (!fgets(linebuf,
sizeof(linebuf), cache))
2005 if (linebuf[0] ==
'#')
2007 char* newline_pos = strchr(linebuf,
'\n');
2027 if(!cache_path.size())
2029 logWarn(
"no location available to write cache file. Try setting ROS_HOME or HOME.");
2033 size_t len = cache_path.size() + 1;
2034 char *tmp_cache_dir =
new char[len];
2035 strncpy(tmp_cache_dir, cache_path.c_str(), len);
2036 #if defined(_MSC_VER)
2038 char tmp_cache_path[PATH_MAX];
2039 char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
2040 _splitpath_s(tmp_cache_dir, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME,
2042 char full_dir[_MAX_DRIVE + _MAX_DIR];
2043 _makepath_s(full_dir, _MAX_DRIVE + _MAX_DIR, drive, dir, NULL, NULL);
2044 snprintf(tmp_cache_path,
sizeof(tmp_cache_path),
"%s\\.rospack_cache.XXXXXX", full_dir);
2045 #elif defined(__MINGW32__)
2046 char tmp_cache_path[PATH_MAX];
2047 char* temp_name = tempnam(dirname(tmp_cache_dir),
".rospack_cache.");
2048 snprintf(tmp_cache_path,
sizeof(tmp_cache_path), temp_name);
2051 char *temp_dirname = dirname(tmp_cache_dir);
2052 len = strlen(temp_dirname) + 22 + 1;
2053 char *tmp_cache_path =
new char[len];
2054 snprintf(tmp_cache_path, len,
"%s/.rospack_cache.XXXXXX", temp_dirname);
2056 #if defined(__MINGW32__)
2059 int fd = open(tmp_cache_path, O_RDWR | O_EXCL | _O_CREAT, 0644);
2062 logWarn(std::string(
"unable to create temporary cache file ") +
2063 tmp_cache_path,
true);
2067 FILE *cache = fdopen(fd,
"w");
2068 #elif defined(WIN32)
2069 if (_mktemp_s(tmp_cache_path, PATH_MAX) != 0)
2072 "[rospack] Unable to generate temporary cache file name: %u",
2077 FILE *cache = fopen(tmp_cache_path,
"w");
2079 mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
2080 int fd = mkstemp(tmp_cache_path);
2084 fprintf(stderr,
"[rospack] Unable to create temporary cache file %s: %s\n",
2085 tmp_cache_path, strerror(errno));
2089 FILE *cache = fdopen(fd,
"w");
2093 fprintf(stderr,
"[rospack] Unable open cache file %s: %s\n",
2094 tmp_cache_path, strerror(errno));
2098 char *rpp = getenv(
"ROS_PACKAGE_PATH");
2099 fprintf(cache,
"#ROS_PACKAGE_PATH=%s\n", (rpp ? rpp :
""));
2100 for(boost::unordered_map<std::string, Stackage*>::const_iterator it =
stackages_.begin();
2103 fprintf(cache,
"%s\n", it->second->path_.c_str());
2105 if(fs::exists(cache_path))
2106 remove(cache_path.c_str());
2107 if(rename(tmp_cache_path, cache_path.c_str()) < 0)
2109 fprintf(stderr,
"[rospack] Error: failed to rename cache file %s to %s: %s\n",
2110 tmp_cache_path, cache_path.c_str(), strerror(errno));
2114 delete[] tmp_cache_dir;
2115 #if !defined(_MSC_VER) && !defined(__MINGW32__)
2116 delete[] tmp_cache_path;
2127 const char *user_cache_time_str = getenv(
"ROS_CACHE_TIMEOUT");
2128 if(user_cache_time_str)
2129 cache_max_age = atof(user_cache_time_str);
2130 if(cache_max_age == 0.0)
2134 FILE* cache = fopen(cache_path.c_str(),
"r");
2139 if(fstat(fileno(cache), &s) == -1)
2145 double dt = difftime(time(NULL), s.st_mtime);
2148 if ((cache_max_age > 0.0) && (dt > cache_max_age))
2155 char linebuf[30000];
2156 bool ros_package_path_ok =
false;
2157 const char* ros_package_path = getenv(
"ROS_PACKAGE_PATH");
2160 if(!fgets(linebuf,
sizeof(linebuf), cache))
2162 linebuf[strlen(linebuf)-1] = 0;
2163 if (linebuf[0] ==
'#')
2165 if(!strncmp(
"#ROS_PACKAGE_PATH=", linebuf, 18))
2167 if(!ros_package_path)
2169 if(!strlen(linebuf+18))
2170 ros_package_path_ok =
true;
2172 else if(!strcmp(linebuf+18, ros_package_path))
2173 ros_package_path_ok =
true;
2179 if(ros_package_path_ok)
2183 fseek(cache, 0, SEEK_SET);
2195 const std::string& instring,
2196 std::string& outstring)
2198 outstring = instring;
2200 i != std::string::npos;
2210 if (outstring.find_first_of(
"$`") == std::string::npos)
2225 std::string cmd = std::string(
"ret=\"") + outstring +
"\" && echo $ret";
2228 std::string token(
"\n");
2229 for (std::string::size_type s = cmd.find(token);
2230 s != std::string::npos;
2231 s = cmd.find(token, s))
2232 cmd.replace(s,token.length(),std::string(
" "));
2235 if(!(p = popen(cmd.c_str(),
"r")))
2237 std::string errmsg =
2238 std::string(
"failed to execute backquote expression ") +
2247 memset(buf,0,
sizeof(buf));
2252 while(fgets(buf + strlen(buf),
sizeof(buf)-strlen(buf)-1,p));
2253 }
while(ferror(p) && errno == EINTR);
2257 std::string errmsg =
2258 std::string(
"got non-zero exit status from executing backquote expression ") +
2266 buf[strlen(buf)-1] =
'\0';
2289 return "USAGE: rospack <command> [options] [package]\n"
2290 " Allowed commands:\n"
2292 " cflags-only-I [--deps-only] [package]\n"
2293 " cflags-only-other [--deps-only] [package]\n"
2294 " depends [package] (alias: deps)\n"
2295 " depends-indent [package] (alias: deps-indent)\n"
2296 " depends-manifests [package] (alias: deps-manifests)\n"
2297 " depends-msgsrv [package] (alias: deps-msgsrv)\n"
2298 " depends-on [package]\n"
2299 " depends-on1 [package]\n"
2300 " depends-why --target=<target> [package] (alias: deps-why)\n"
2301 " depends1 [package] (alias: deps1)\n"
2302 " export [--deps-only] --lang=<lang> --attrib=<attrib> [package]\n"
2305 " libs-only-L [--deps-only] [package]\n"
2306 " libs-only-l [--deps-only] [package]\n"
2307 " libs-only-other [--deps-only] [package]\n"
2309 " list-duplicates\n"
2311 " plugins --attrib=<attrib> [--top=<toppkg>] [package]\n"
2312 " profile [--length=<length>] [--zombie-only]\n"
2313 " rosdep [package] (alias: rosdeps)\n"
2314 " rosdep0 [package] (alias: rosdeps0)\n"
2318 " -q Quiets error reports.\n\n"
2319 " If [package] is omitted, the current working directory\n"
2320 " is used (if it contains a package.xml or manifest.xml).\n\n";
2342 return "USAGE: rosstack [options] <command> [stack]\n"
2343 " Allowed commands:\n"
2346 " contents [stack]\n"
2349 " depends [stack] (alias: deps)\n"
2350 " depends-manifests [stack] (alias: deps-manifests)\n"
2351 " depends1 [stack] (alias: deps1)\n"
2352 " depends-indent [stack] (alias: deps-indent)\n"
2353 " depends-why --target=<target> [stack] (alias: deps-why)\n"
2354 " depends-on [stack]\n"
2355 " depends-on1 [stack]\n"
2356 " contains [package]\n"
2357 " contains-path [package]\n"
2358 " profile [--length=<length>] \n\n"
2359 " If [stack] is omitted, the current working directory\n"
2360 " is used (if it contains a stack.xml).\n\n";
2368 tinyxml2::XMLElement*
2371 tinyxml2::XMLElement* ele = stackage->
manifest_.RootElement();
2374 std::string errmsg = std::string(
"error parsing manifest of package ") +
2385 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
2386 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
2388 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
2391 unsigned __int64 tmpres = 0;
2393 GetSystemTimeAsFileTime(&ft);
2394 tmpres |= ft.dwHighDateTime;
2396 tmpres |= ft.dwLowDateTime;
2398 tmpres -= DELTA_EPOCH_IN_MICROSECS;
2399 return static_cast<double>(tmpres) / 1e6;
2402 gettimeofday(&tod, NULL);
2403 return tod.tv_sec + 1e-6 * tod.tv_usec;