rospack_cmdline.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008, Willow Garage, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "rospack/rospack.h"
29 #include "utils.h"
30 #include "rospack_cmdline.h"
31 
32 #include <boost/program_options.hpp>
33 #include <boost/algorithm/string.hpp>
34 #include <algorithm>
35 #include <iostream>
36 #include <stdlib.h>
37 #include <stdio.h>
38 
39 namespace po = boost::program_options;
40 
41 namespace rospack
42 {
43 
44 bool parse_args(int argc, char** argv,
46  po::variables_map& vm);
47 
48 bool
49 rospack_run(int argc, char** argv, rospack::Rosstackage& rp, std::string& output)
50 {
51  po::variables_map vm;
52 
53  if(!parse_args(argc, argv, rp, vm))
54  return false;
55 
56  bool quiet = (vm.count("quiet")==1);
57  rp.setQuiet(quiet);
58 
59  std::string command;
60  std::string package;
61  bool package_given = false;
62  bool deps_only = false;
63  std::string lang;
64  std::string attrib;
65  std::string top;
66  std::string target;
67  bool zombie_only = false;
68  std::string length_str;
69  int length;
70  if(vm.count("command"))
71  command = vm["command"].as<std::string>();
72 
73  if(vm.count("-h") && command.empty())
74  command = "help";
75 
76  if(!command.size())
77  {
78  rp.logError( std::string("no command given. Try '") + rp.getName() + " help'");
79  return true;
80  }
81  // For some commands, we force a crawl. Definitely anything that does a
82  // depends-on calculation.
83  bool force = false;
84  if((command == "profile") ||
85  (command == "depends-on") ||
86  (command == "depends-on1") ||
87  (command == "langs") ||
88  (command == "list-duplicates"))
89  force = true;
90 
91  if(vm.count("package"))
92  {
93  package = vm["package"].as<std::string>();
94  package_given = true;
95  }
96  else
97  {
98  // try to determine package from directory context
99  rp.inStackage(package);
100  }
101  if(vm.count("deps-only"))
102  deps_only = true;
103  if(vm.count("lang"))
104  lang = vm["lang"].as<std::string>();
105  if(vm.count("attrib"))
106  attrib = vm["attrib"].as<std::string>();
107  if(vm.count("top"))
108  top = vm["top"].as<std::string>();
109  if(vm.count("target"))
110  target = vm["target"].as<std::string>();
111  if(vm.count("zombie-only"))
112  zombie_only = true;
113  if(vm.count("length"))
114  {
115  length_str = vm["length"].as<std::string>();
116  length = atoi(length_str.c_str());
117  }
118  else
119  {
120  if(zombie_only)
121  length = -1;
122  else
123  length = 20;
124  }
125 
126  // COMMAND: help
127  if(command == "help" || vm.count("help"))
128  {
129  if(package_given || (command != "help" && vm.count("help"))) {
130  if (command == "help") {
131  command = vm["package"].as<std::string>();
132  }
133  output.append("Usage: rospack ");
134  output.append(command);
135  if(command == "help")
136  output.append("[command]\n\nPrint help message.");
137  else if(command == "find")
138  output.append("\n\nPrint absolute path to the package");
139  else if(command == "list")
140  output.append("\n\nPrint newline-separated list <package-name> <package-dir> for all packages.");
141  else if(command == "list-names")
142  output.append("\n\nPrint newline-separated list of packages names for all packages.");
143  else if(command == "list-duplicates")
144  output.append("\n\nPrint newline-separated list of names of packages that are found more than once during the search.");
145  else if(command == "langs")
146  output.append("\n\nPrint space-separated list of available language-specific client libraries.");
147  else if(command == "depends" || command == "deps")
148  output.append("[package]\n\nPrint newline-separated, ordered list of all dependencies of the package.");
149  else if(command == "depends1" || command == "deps1")
150  output.append("[package]\n\nPrint newline-separated, ordered list of immediate dependencies of the package.");
151  else if(command == "depends-manifest" || command == "deps-manifest")
152  output.append("[package]\n\nPrint space-separated, ordered list of manifest.xml files for all dependencies of the package. Used internally by rosbuild.");
153  else if(command == "depends-indent" || command == "deps-indent")
154  output.append("[package]\n\nPrint newline-separated, indented list of the entire dependency chain for the package.");
155  else if(command == "depends-why" || command == "deps-why")
156  output.append("--target=TARGET [package]\n\nPrint newline-separated presentation of all dependency chains from the package to TARGET. ");
157  else if(command == "depends-msgsrv" || command == "deps-msgsrv")
158  output.append("[package]\n\nPrint space-separated list of message-generation marker files for all dependencies of the package. Used internally by rosbuild.");
159  else if(command == "rosdep" || command == "rosdeps")
160  output.append("[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of the package and all of its dependencies.");
161  else if(command == "rosdep0" || command == "rosdeps0")
162  output.append("[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of just the package itself.");
163  else if(command == "vcs")
164  output.append("[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of the package and all of its dependencies.");
165  else if(command == "vcs0")
166  output.append("[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of just the package itself.");
167  else if(command == "depends-on")
168  output.append("[package]\n\nPrint newline-separated list of all packages that depend on the package. ");
169  else if(command == "depends-on1")
170  output.append("[package]\n\nPrint newline-separated list of all packages that directly depend on the package.");
171  else if(command == "export")
172  output.append("[--deps-only] --lang=<lang> --attrib=<attrib> [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
173  else if(command == "plugins")
174  output.append("--attrib=<attrib> [--top=<toppkg>] [package]\n\nExamine packages that depend directly on the given package, giving name and the exported attribute with the name <attrib>\n\nIf --top=<toppkg> is given, then in addition to depending directly on the given package, to be scanned for exports, a package must also be a dependency of <toppkg>, or be <toppkg> itself.");
175  else if(command == "cflags-only-I")
176  output.append("[--deps-only] [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
177  else if(command == "cflags-only-other")
178  output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/cflags that don't start with -I.\n\nIf --deps-only is provided, then the package itself is excluded.");
179  else if(command == "libs-only-L")
180  output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
181  else if(command == "libs-only-l")
182  output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -l.\n\nIf --deps-only is provided, then the package itself is excluded.");
183  else if(command == "libs-only-other")
184  output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that don't start with -l or -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
185  else if(command == "profile")
186  output.append("[--length=<length>] [--zombie-only]\n\nForce a full crawl of package directories and report the directories that took the longest time to crawl.\n\n--length=N how many directories to display\n\n--zombie-only Only print directories that do not have any manifests.");
187  output.append("\n");
188  } else {
189  output.append(rp.usage());
190  }
191  return true;
192  }
193 
194  std::vector<std::string> search_path;
195  if(!rp.getSearchPathFromEnv(search_path))
196  return false;
197 
198  // COMMAND: profile
199  if(command == "profile")
200  {
201  if(package_given || target.size() || top.size() ||
202  deps_only || lang.size() || attrib.size())
203  {
204  rp.logError( "invalid option(s) given");
205  return false;
206  }
207  std::vector<std::string> dirs;
208  if(rp.profile(search_path, zombie_only, length, dirs))
209  return false;
210  for(std::vector<std::string>::const_iterator it = dirs.begin();
211  it != dirs.end();
212  ++it)
213  output.append((*it) + "\n");
214  return true;
215  }
216 
217  // We crawl here because profile (above) does its own special crawl.
218  rp.crawl(search_path, force);
219 
220  // COMMAND: find [package]
221  if(command == "find")
222  {
223  if(!package.size())
224  {
225  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
226  return false;
227  }
228  if(target.size() || top.size() || length_str.size() ||
229  zombie_only || deps_only || lang.size() || attrib.size())
230  {
231  rp.logError( "invalid option(s) given");
232  return false;
233  }
234  std::string path;
235  if(!rp.find(package, path))
236  return false;
237  output.append(path + "\n");
238  return true;
239  }
240  // COMMAND: list
241  else if(command == "list")
242  {
243  if(package_given || target.size() || top.size() || length_str.size() ||
244  zombie_only || deps_only || lang.size() || attrib.size())
245  {
246  rp.logError( "invalid option(s) given");
247  return false;
248  }
249  std::set<std::pair<std::string, std::string> > list;
250  rp.list(list);
251  for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
252  it != list.end();
253  ++it)
254  {
255  output.append(it->first + " " + it->second + "\n");
256  }
257  return true;
258  }
259  // COMMAND: list-names
260  else if(command == "list-names")
261  {
262  if(package_given || target.size() || top.size() || length_str.size() ||
263  zombie_only || deps_only || lang.size() || attrib.size())
264  {
265  rp.logError( "invalid option(s) given");
266  return false;
267  }
268  std::set<std::pair<std::string, std::string> > list;
269  rp.list(list);
270  for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
271  it != list.end();
272  ++it)
273  {
274  output.append(it->first + "\n");
275  }
276  return true;
277  }
278  // COMMAND: list-duplicates
279  else if(command == "list-duplicates")
280  {
281  if(package_given || target.size() || top.size() || length_str.size() ||
282  zombie_only || deps_only || lang.size() || attrib.size())
283  {
284  rp.logError( "invalid option(s) given");
285  return false;
286  }
287  std::map<std::string, std::vector<std::string> > dups;
288  rp.listDuplicatesWithPaths(dups);
289  // if there are dups, list-duplicates prints them and returns non-zero
290  for(std::map<std::string, std::vector<std::string> >::const_iterator it = dups.begin();
291  it != dups.end();
292  ++it)
293  {
294  output.append(it->first + "\n");
295  for(std::vector<std::string>::const_iterator jt = it->second.begin();
296  jt != it->second.end();
297  ++jt)
298  {
299  output.append("- " + *jt + "\n");
300  }
301  }
302  return true;
303  }
304  // COMMAND: langs
305  else if(rp.getName() == ROSPACK_NAME && command == "langs")
306  {
307  if(package_given || target.size() || top.size() || length_str.size() ||
308  zombie_only || deps_only || lang.size() || attrib.size())
309  {
310  rp.logError( "invalid option(s) given");
311  return false;
312  }
313  std::vector<std::string> deps;
314  if(!rp.depsOn("roslang", true, deps))
315  return false;
316  const char* ros_lang_disable;
317  if((ros_lang_disable = getenv("ROS_LANG_DISABLE")))
318  {
319  std::vector<std::string> disable_langs;
320  // I can't see that boost filesystem has an elegant cross platform
321  // representation for this anywhere like qt/python have.
322  #if defined(WIN32)
323  const char *path_delim = ";";
324  #else
325  const char *path_delim = ":";
326  #endif
327  boost::split(disable_langs, ros_lang_disable,
328  boost::is_any_of(path_delim),
329  boost::token_compress_on);
330  std::vector<std::string>::iterator it = deps.begin();
331  while(it != deps.end())
332  {
333  if(std::find(disable_langs.begin(), disable_langs.end(), *it) !=
334  disable_langs.end())
335  it = deps.erase(it);
336  else
337  ++it;
338  }
339  }
340  for(std::vector<std::string>::const_iterator it = deps.begin();
341  it != deps.end();
342  ++it)
343  {
344  if(it != deps.begin())
345  output.append(" ");
346  output.append(*it);
347  }
348  output.append("\n");
349  return true;
350  }
351  // COMMAND: depends [package] (alias: deps)
352  else if(command == "depends" || command == "deps" ||
353  command == "depends1" || command == "deps1")
354  {
355  if(!package.size())
356  {
357  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
358  return false;
359  }
360  if(target.size() || top.size() || length_str.size() ||
361  zombie_only || deps_only || lang.size() || attrib.size())
362  {
363  rp.logError( "invalid option(s) given");
364  return false;
365  }
366  std::vector<std::string> deps;
367  if(!rp.deps(package, (command == "depends1" || command == "deps1"), deps))
368  return false;
369  for(std::vector<std::string>::const_iterator it = deps.begin();
370  it != deps.end();
371  ++it)
372  output.append(*it + "\n");
373  return true;
374  }
375  // COMMAND: depends-manifests [package] (alias: deps-manifests)
376  else if(command == "depends-manifests" || command == "deps-manifests")
377  {
378  if(!package.size())
379  {
380  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
381  return false;
382  }
383  if(target.size() || top.size() || length_str.size() ||
384  zombie_only || deps_only || lang.size() || attrib.size())
385  {
386  rp.logError( "invalid option(s) given");
387  return false;
388  }
389  std::vector<std::string> manifests;
390  if(!rp.depsManifests(package, false, manifests))
391  return false;
392  for(std::vector<std::string>::const_iterator it = manifests.begin();
393  it != manifests.end();
394  ++it)
395  {
396  if(it != manifests.begin())
397  output.append(" ");
398  output.append(*it);
399  }
400  output.append("\n");
401  return true;
402  }
403  // COMMAND: depends-msgsrv [package] (alias: deps-msgsrv)
404  else if(rp.getName() == ROSPACK_NAME &&
405  (command == "depends-msgsrv" || command == "deps-msgsrv"))
406  {
407  if(!package.size())
408  {
409  rp.logError( "no package given");
410  return false;
411  }
412  if(target.size() || top.size() || length_str.size() ||
413  zombie_only || deps_only || lang.size() || attrib.size())
414  {
415  rp.logError( "invalid option(s) given");
416  return false;
417  }
418  std::vector<std::string> gens;
419  if(!rp.depsMsgSrv(package, false, gens))
420  return false;
421  for(std::vector<std::string>::const_iterator it = gens.begin();
422  it != gens.end();
423  ++it)
424  {
425  if(it != gens.begin())
426  output.append(" ");
427  output.append(*it);
428  }
429  output.append("\n");
430  return true;
431  }
432  // COMMAND: depends-indent [package] (alias: deps-indent)
433  else if(command == "depends-indent" || command == "deps-indent")
434  {
435  if(!package.size())
436  {
437  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
438  return false;
439  }
440  if(target.size() || top.size() || length_str.size() ||
441  zombie_only || deps_only || lang.size() || attrib.size())
442  {
443  rp.logError( "invalid option(s) given");
444  return false;
445  }
446  std::vector<std::string> deps;
447  if(!rp.depsIndent(package, false, deps))
448  return false;
449  for(std::vector<std::string>::const_iterator it = deps.begin();
450  it != deps.end();
451  ++it)
452  output.append(*it + "\n");
453  return true;
454  }
455  // COMMAND: depends-why [package] (alias: deps-why)
456  else if(command == "depends-why" || command == "deps-why")
457  {
458  if(!package.size() || !target.size())
459  {
460  rp.logError(std::string("no ") + rp.get_manifest_type() + " or target given");
461  return false;
462  }
463  if(top.size() || length_str.size() ||
464  zombie_only || deps_only || lang.size() || attrib.size())
465  {
466  rp.logError( "invalid option(s) given");
467  return false;
468  }
469  std::string why_output;
470  if(!rp.depsWhy(package, target, why_output))
471  return false;
472  output.append(why_output);
473  return true;
474  }
475  // COMMAND: rosdep [package] (alias: rosdeps)
476  // COMMAND: rosdep0 [package] (alias: rosdeps0)
477  else if(rp.getName() == ROSPACK_NAME &&
478  (command == "rosdep" || command == "rosdeps" ||
479  command == "rosdep0" || command == "rosdeps0"))
480  {
481  if(!package.size())
482  {
483  rp.logError( "no package given");
484  return false;
485  }
486  if(target.size() || top.size() || length_str.size() ||
487  zombie_only || deps_only || lang.size() || attrib.size())
488  {
489  rp.logError( "invalid option(s) given");
490  return false;
491  }
492  std::set<std::string> rosdeps;
493  if(!rp.rosdeps(package, (command == "rosdep0" || command == "rosdeps0"), rosdeps))
494  return false;
495  for(std::set<std::string>::const_iterator it = rosdeps.begin();
496  it != rosdeps.end();
497  ++it)
498  output.append(*it + "\n");
499  return true;
500  }
501  // COMMAND: vcs [package]
502  // COMMAND: vcs0 [package]
503  else if(rp.getName() == ROSPACK_NAME &&
504  (command == "vcs" || command == "vcs0"))
505  {
506  if(!package.size())
507  {
508  rp.logError( "no package given");
509  return false;
510  }
511  if(target.size() || top.size() || length_str.size() ||
512  zombie_only || deps_only || lang.size() || attrib.size())
513  {
514  rp.logError( "invalid option(s) given");
515  return false;
516  }
517  std::vector<std::string> vcs;
518  if(!rp.vcs(package, (command == "vcs0"), vcs))
519  return false;
520  for(std::vector<std::string>::const_iterator it = vcs.begin();
521  it != vcs.end();
522  ++it)
523  output.append(*it + "\n");
524  return true;
525  }
526  // COMMAND: depends-on [package]
527  // COMMAND: depends-on1 [package]
528  else if(command == "depends-on" || command == "depends-on1")
529  {
530  if(!package.size())
531  {
532  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
533  return false;
534  }
535  if(target.size() || top.size() || length_str.size() ||
536  zombie_only || deps_only || lang.size() || attrib.size())
537  {
538  rp.logError( "invalid option(s) given");
539  return false;
540  }
541  std::vector<std::string> deps;
542  if(!rp.depsOn(package, (command == "depends-on1"), deps))
543  return false;
544  for(std::vector<std::string>::const_iterator it = deps.begin();
545  it != deps.end();
546  ++it)
547  output.append(*it + "\n");
548  return true;
549  }
550  // COMMAND: export [--deps-only] --lang=<lang> --attrib=<attrib> [package]
551  else if(rp.getName() == ROSPACK_NAME && command == "export")
552  {
553  if(!package.size() || !lang.size() || !attrib.size())
554  {
555  rp.logError( "no package / lang / attrib given");
556  return false;
557  }
558  if(target.size() || top.size() || length_str.size() || zombie_only)
559  {
560  rp.logError( "invalid option(s) given");
561  return false;
562  }
563  std::vector<std::string> flags;
564  if(!rp.exports(package, lang, attrib, deps_only, flags))
565  return false;
566  for(std::vector<std::string>::const_iterator it = flags.begin();
567  it != flags.end();
568  ++it)
569  {
570  if(it != flags.begin())
571  output.append(" ");
572  output.append(*it);
573  }
574  output.append("\n");
575  return true;
576  }
577  // COMMAND: plugins --attrib=<attrib> [--top=<toppkg>] [package]
578  else if(rp.getName() == ROSPACK_NAME && command == "plugins")
579  {
580  if(!package.size() || !attrib.size())
581  {
582  rp.logError( "no package / attrib given");
583  return false;
584  }
585  if(target.size() || length_str.size() || zombie_only)
586  {
587  rp.logError( "invalid option(s) given");
588  return false;
589  }
590  std::vector<std::string> flags;
591  if(!rp.plugins(package, attrib, top, flags))
592  return false;
593  for(std::vector<std::string>::const_iterator it = flags.begin();
594  it != flags.end();
595  ++it)
596  output.append(*it + "\n");
597  return true;
598  }
599  // COMMAND: cflags-only-I [--deps-only] [package]
600  else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-I")
601  {
602  if(!package.size())
603  {
604  rp.logError( "no package given");
605  return false;
606  }
607  if(target.size() || top.size() || length_str.size() || zombie_only)
608  {
609  rp.logError( "invalid option(s) given");
610  return false;
611  }
612  std::vector<std::pair<std::string, bool> > flags;
613  if(!rp.cpp_exports(package, "--cflags-only-I", "cflags", deps_only, flags))
614  return false;
615 
616  std::string dry_combined;
617  std::string wet_combined;
618  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
619  it != flags.end();
620  ++it)
621  {
622  std::string& combined = it->second ? wet_combined : dry_combined;
623  if(!combined.empty())
624  combined.append(" ");
625  combined.append(it->first);
626  }
627 
628  std::string dry_result;
629  parse_compiler_flags(dry_combined, "-I", true, false, dry_result);
630  output.append(dry_result);
631 
632  std::string wet_result;
633  parse_compiler_flags(wet_combined, "-I", true, false, wet_result);
634  if(!dry_result.empty() && !wet_result.empty())
635  output.append(" ");
636  if(!rp.reorder_paths(wet_result, wet_result))
637  return false;
638  output.append(wet_result + "\n");
639  return true;
640  }
641  // COMMAND: cflags-only-other [--deps-only] [package]
642  else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-other")
643  {
644  if(!package.size())
645  {
646  rp.logError( "no package given");
647  return false;
648  }
649  if(target.size() || top.size() || length_str.size() || zombie_only)
650  {
651  rp.logError( "invalid option(s) given");
652  return false;
653  }
654  std::vector<std::pair<std::string, bool> > flags;
655  if(!rp.cpp_exports(package, "--cflags-only-other", "cflags", deps_only, flags))
656  return false;
657  std::string combined;
658  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
659  it != flags.end();
660  ++it)
661  {
662  if(it != flags.begin())
663  combined.append(" ");
664  combined.append(it->first);
665  }
666  std::string result;
667  parse_compiler_flags(combined, "-I", false, false, result);
668  output.append(result + "\n");
669  return true;
670  }
671  // COMMAND: libs-only-L [--deps-only] [package]
672  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-L")
673  {
674  if(!package.size())
675  {
676  rp.logError( "no package given");
677  return false;
678  }
679  if(target.size() || top.size() || length_str.size() || zombie_only)
680  {
681  rp.logError( "invalid option(s) given");
682  return false;
683  }
684  std::vector<std::pair<std::string, bool> > flags;
685  if(!rp.cpp_exports(package, "--libs-only-L", "lflags", deps_only, flags))
686  return false;
687 
688  std::string dry_combined;
689  std::string wet_combined;
690  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
691  it != flags.end();
692  ++it)
693  {
694  std::string& combined = it->second ? wet_combined : dry_combined;
695  if(!combined.empty())
696  combined.append(" ");
697  combined.append(it->first);
698  }
699 
700  std::string dry_result;
701  parse_compiler_flags(dry_combined, "-L", true, false, dry_result);
702  output.append(dry_result);
703 
704  std::string wet_result;
705  parse_compiler_flags(wet_combined, "-L", true, false, wet_result);
706  if(!dry_result.empty() && !wet_result.empty())
707  output.append(" ");
708  if(!rp.reorder_paths(wet_result, wet_result))
709  return false;
710  output.append(wet_result + "\n");
711  return true;
712  }
713  // COMMAND: libs-only-l [--deps-only] [package]
714  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-l")
715  {
716  if(!package.size())
717  {
718  rp.logError( "no package given");
719  return false;
720  }
721  if(target.size() || top.size() || length_str.size() || zombie_only)
722  {
723  rp.logError( "invalid option(s) given");
724  return false;
725  }
726  std::vector<std::pair<std::string, bool> > flags;
727  if(!rp.cpp_exports(package, "--libs-only-l", "lflags", deps_only, flags))
728  return false;
729  std::string combined;
730  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
731  it != flags.end();
732  ++it)
733  {
734  if(it != flags.begin())
735  combined.append(" ");
736  combined.append(it->first);
737  }
738  std::string result;
739  parse_compiler_flags(combined, "-l", true, true, result);
740  output.append(result + "\n");
741  return true;
742  }
743  // COMMAND: libs-only-other [--deps-only] [package]
744  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-other")
745  {
746  if(!package.size())
747  {
748  rp.logError( "no package given");
749  return false;
750  }
751  if(target.size() || top.size() || length_str.size() || zombie_only)
752  {
753  rp.logError( "invalid option(s) given");
754  return false;
755  }
756  std::vector<std::pair<std::string, bool> > flags;
757  if(!rp.cpp_exports(package, "--libs-only-other", "lflags", deps_only, flags))
758  return false;
759  std::string combined;
760  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
761  it != flags.end();
762  ++it)
763  {
764  if(it != flags.begin())
765  combined.append(" ");
766  combined.append(it->first);
767  }
768  std::string intermediate;
769  parse_compiler_flags(combined, "-L", false, false, intermediate);
770  std::string result;
771  parse_compiler_flags(intermediate, "-l", false, false, result);
772  output.append(result + "\n");
773  return true;
774  }
775  // COMMAND: contents [stack]
776  else if(rp.getName() == ROSSTACK_NAME && command == "contents")
777  {
778  if(!package.size())
779  {
780  rp.logError( "no stack given");
781  return false;
782  }
783  if(target.size() || top.size() || length_str.size() ||
784  zombie_only || deps_only || lang.size() || attrib.size())
785  {
786  rp.logError( "invalid option(s) given");
787  return false;
788  }
789 
790  std::set<std::string> packages;
791  rp.contents(package, packages);
792  for(std::set<std::string>::const_iterator it = packages.begin();
793  it != packages.end();
794  ++it)
795  output.append(*it + "\n");
796  return true;
797  }
798  // COMMAND: contains [package]
799  else if(rp.getName() == ROSSTACK_NAME &&
800  ((command == "contains") || (command == "contains-path")))
801  {
802  if(!package.size())
803  {
804  rp.logError( "no package given");
805  return false;
806  }
807  if(target.size() || top.size() || length_str.size() ||
808  zombie_only || deps_only || lang.size() || attrib.size())
809  {
810  rp.logError( "invalid option(s) given");
811  return false;
812  }
813  std::string name, path;
814  if(!rp.contains(package, name, path))
815  return false;
816  if(command == "contains")
817  output.append(name + "\n");
818  else // command == "contains-path"
819  output.append(path + "\n");
820  return true;
821  }
822  else
823  {
824  rp.logError(std::string("command ") + command + " not implemented");
825  return false;
826  }
827 }
828 
829 bool
830 parse_args(int argc, char** argv,
831  rospack::Rosstackage& rp, po::variables_map& vm)
832 {
833  po::options_description desc("Allowed options");
834  desc.add_options()
835  ("command", po::value<std::string>(), "command")
836  ("package", po::value<std::string>(), "package")
837  ("target", po::value<std::string>(), "target")
838  ("deps-only", "deps-only")
839  ("lang", po::value<std::string>(), "lang")
840  ("attrib", po::value<std::string>(), "attrib")
841  ("top", po::value<std::string>(), "top")
842  ("length", po::value<std::string>(), "length")
843  ("zombie-only", "zombie-only")
844  ("help", "help")
845  ("-h", "help")
846  ("quiet,q", "quiet");
847 
848  po::positional_options_description pd;
849  pd.add("command", 1).add("package", 1);
850  try
851  {
852  po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);
853  }
854  catch(boost::program_options::error e)
855  {
856  rp.logError( std::string("failed to parse command-line options: ") + e.what());
857  return false;
858  }
859  po::notify(vm);
860 
861  return true;
862 }
863 
864 }
bool exports(const std::string &name, const std::string &lang, const std::string &attrib, bool deps_only, std::vector< std::string > &flags)
Compute exports declared in a package and its dependencies. Used by rosbuild.
Definition: rospack.cpp:984
void parse_compiler_flags(const std::string &instring, const std::string &token, bool select, bool last, std::string &outstring)
Definition: utils.cpp:75
bool depsMsgSrv(const std::string &name, bool direct, std::vector< std::string > &gens)
List the marker files in a packages&#39;s dependencies that indicate that those packages contain auto-gen...
Definition: rospack.cpp:1151
bool inStackage(std::string &name)
Is the current working directory a stackage?
Definition: rospack.cpp:399
string package
Definition: deep.py:54
bool contents(const std::string &name, std::set< std::string > &packages)
Compute the packages that are contained in a stack.
Definition: rospack.cpp:448
bool reorder_paths(const std::string &paths, std::string &reordered)
Reorder the paths according to the workspace chaining.
Definition: rospack.cpp:920
bool deps(const std::string &name, bool direct, std::vector< std::string > &deps)
Compute dependencies of a stackage (i.e., stackages that this stackages depends on).
Definition: rospack.cpp:554
virtual std::string get_manifest_type()
Definition: rospack.h:553
void setQuiet(bool quiet)
Control warning and error console output.
Definition: rospack.cpp:311
bool parse_args(int argc, char **argv, rospack::Rosstackage &rp, po::variables_map &vm)
bool rosdeps(const std::string &name, bool direct, std::set< std::string > &rosdeps)
Compute rosdep entries that are declared in manifest of a package and its dependencies. Used by rosmake.
Definition: rospack.cpp:687
bool rospack_run(int argc, char **argv, rospack::Rosstackage &rp, std::string &output)
void listDuplicatesWithPaths(std::map< std::string, std::vector< std::string > > &dups)
Identify duplicate stackages and provide their paths. Forces crawl.
Definition: rospack.cpp:534
void list(std::set< std::pair< std::string, std::string > > &list)
List names and paths of all stackages.
Definition: rospack.cpp:506
bool contains(const std::string &name, std::string &stack, std::string &path)
Find the stack that contains a package.
Definition: rospack.cpp:474
bool getSearchPathFromEnv(std::vector< std::string > &sp)
Helper method to construct a directory search path by looking at relevant environment variables...
Definition: rospack.cpp:283
virtual const char * usage()
Usage string, to be overridden by derived classes.
Definition: rospack.h:217
bool depsManifests(const std::string &name, bool direct, std::vector< std::string > &manifests)
List the manifests of a stackage&#39;s dependencies. Used by rosbuild.
Definition: rospack.cpp:662
bool depsOn(const std::string &name, bool direct, std::vector< std::string > &deps)
Compute reverse dependencies of a stackage (i.e., stackages that depend on this stackage). Forces crawl.
Definition: rospack.cpp:579
const std::string & getName()
Get the name of the tool that&#39;s in use (e.g., "rospack" or "rosstack")
Definition: rospack.h:248
The base class for package/stack ("stackage") crawlers. Users of the library should use the functiona...
Definition: rospack.h:141
void crawl(std::vector< std::string > search_path, bool force)
Crawl the filesystem, accumulating a database of stackages. May read results from a cache file instea...
Definition: rospack.cpp:360
bool vcs(const std::string &name, bool direct, std::vector< std::string > &vcs)
Compute vcs entries that are declared in manifest of a package and its dependencies. Was used by Hudson build scripts; might not be needed.
Definition: rospack.cpp:761
void logError(const std::string &msg, bool append_errno=false)
Log a error (usually goes to stderr).
Definition: rospack.cpp:276
static const char * ROSSTACK_NAME
Definition: utils.h:43
bool depsIndent(const std::string &name, bool direct, std::vector< std::string > &deps)
Generate indented list of a stackage&#39;s dependencies, including duplicates. Intended for visual debugg...
Definition: rospack.cpp:593
bool cpp_exports(const std::string &name, const std::string &type, const std::string &attrib, bool deps_only, std::vector< std::pair< std::string, bool > > &flags)
Compute cpp exports declared in a package and its dependencies. Used by rosbuild. ...
Definition: rospack.cpp:809
bool profile(const std::vector< std::string > &search_path, bool zombie_only, int length, std::vector< std::string > &dirs)
Report on time taken to crawl for stackages. Intended for use in debugging misconfigured stackage tre...
Definition: rospack.cpp:1325
bool find(const std::string &name, std::string &path)
Look for a stackage.
Definition: rospack.cpp:435
static const char * ROSPACK_NAME
Definition: utils.h:42
bool plugins(const std::string &name, const std::string &attrib, const std::string &top, std::vector< std::string > &flags)
Compute exported plugins declared in packages that depend on a package. Forces crawl. Used by rosbuild and roslib.
Definition: rospack.cpp:1085
bool depsWhy(const std::string &from, const std::string &to, std::string &output)
Compute all dependency chains from one stackage to another. Intended for visual debugging of dependen...
Definition: rospack.cpp:620


rospack
Author(s): Brian Gerkey, Morgan Quigley, Dirk Thomas
autogenerated on Mon Feb 28 2022 23:32:59