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  bool result = rp.depsOn("roslang", true, deps);
315  const char* ros_lang_disable;
316  if((ros_lang_disable = getenv("ROS_LANG_DISABLE")))
317  {
318  std::vector<std::string> disable_langs;
319  // I can't see that boost filesystem has an elegant cross platform
320  // representation for this anywhere like qt/python have.
321  #if defined(WIN32)
322  const char *path_delim = ";";
323  #else
324  const char *path_delim = ":";
325  #endif
326  boost::split(disable_langs, ros_lang_disable,
327  boost::is_any_of(path_delim),
328  boost::token_compress_on);
329  std::vector<std::string>::iterator it = deps.begin();
330  while(it != deps.end())
331  {
332  if(std::find(disable_langs.begin(), disable_langs.end(), *it) !=
333  disable_langs.end())
334  it = deps.erase(it);
335  else
336  ++it;
337  }
338  }
339  for(std::vector<std::string>::const_iterator it = deps.begin();
340  it != deps.end();
341  ++it)
342  {
343  if(it != deps.begin())
344  output.append(" ");
345  output.append(*it);
346  }
347  output.append("\n");
348  return result;
349  }
350  // COMMAND: depends [package] (alias: deps)
351  else if(command == "depends" || command == "deps" ||
352  command == "depends1" || command == "deps1")
353  {
354  if(!package.size())
355  {
356  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
357  return false;
358  }
359  if(target.size() || top.size() || length_str.size() ||
360  zombie_only || deps_only || lang.size() || attrib.size())
361  {
362  rp.logError( "invalid option(s) given");
363  return false;
364  }
365  std::vector<std::string> deps;
366  bool result = rp.deps(package, (command == "depends1" || command == "deps1"), deps);
367  for(std::vector<std::string>::const_iterator it = deps.begin();
368  it != deps.end();
369  ++it)
370  output.append(*it + "\n");
371  return result;
372  }
373  // COMMAND: depends-manifests [package] (alias: deps-manifests)
374  else if(command == "depends-manifests" || command == "deps-manifests")
375  {
376  if(!package.size())
377  {
378  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
379  return false;
380  }
381  if(target.size() || top.size() || length_str.size() ||
382  zombie_only || deps_only || lang.size() || attrib.size())
383  {
384  rp.logError( "invalid option(s) given");
385  return false;
386  }
387  std::vector<std::string> manifests;
388  bool result = rp.depsManifests(package, false, manifests);
389  for(std::vector<std::string>::const_iterator it = manifests.begin();
390  it != manifests.end();
391  ++it)
392  {
393  if(it != manifests.begin())
394  output.append(" ");
395  output.append(*it);
396  }
397  output.append("\n");
398  return result;
399  }
400  // COMMAND: depends-msgsrv [package] (alias: deps-msgsrv)
401  else if(rp.getName() == ROSPACK_NAME &&
402  (command == "depends-msgsrv" || command == "deps-msgsrv"))
403  {
404  if(!package.size())
405  {
406  rp.logError( "no package given");
407  return false;
408  }
409  if(target.size() || top.size() || length_str.size() ||
410  zombie_only || deps_only || lang.size() || attrib.size())
411  {
412  rp.logError( "invalid option(s) given");
413  return false;
414  }
415  std::vector<std::string> gens;
416  bool result = rp.depsMsgSrv(package, false, gens);
417  for(std::vector<std::string>::const_iterator it = gens.begin();
418  it != gens.end();
419  ++it)
420  {
421  if(it != gens.begin())
422  output.append(" ");
423  output.append(*it);
424  }
425  output.append("\n");
426  return result;
427  }
428  // COMMAND: depends-indent [package] (alias: deps-indent)
429  else if(command == "depends-indent" || command == "deps-indent")
430  {
431  if(!package.size())
432  {
433  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
434  return false;
435  }
436  if(target.size() || top.size() || length_str.size() ||
437  zombie_only || deps_only || lang.size() || attrib.size())
438  {
439  rp.logError( "invalid option(s) given");
440  return false;
441  }
442  std::vector<std::string> deps;
443  bool result = rp.depsIndent(package, false, deps);
444  for(std::vector<std::string>::const_iterator it = deps.begin();
445  it != deps.end();
446  ++it)
447  output.append(*it + "\n");
448  return result;
449  }
450  // COMMAND: depends-why [package] (alias: deps-why)
451  else if(command == "depends-why" || command == "deps-why")
452  {
453  if(!package.size() || !target.size())
454  {
455  rp.logError(std::string("no ") + rp.get_manifest_type() + " or target given");
456  return false;
457  }
458  if(top.size() || length_str.size() ||
459  zombie_only || deps_only || lang.size() || attrib.size())
460  {
461  rp.logError( "invalid option(s) given");
462  return false;
463  }
464  std::string why_output;
465  bool result = rp.depsWhy(package, target, why_output);
466  output.append(why_output);
467  return result;
468  }
469  // COMMAND: rosdep [package] (alias: rosdeps)
470  // COMMAND: rosdep0 [package] (alias: rosdeps0)
471  else if(rp.getName() == ROSPACK_NAME &&
472  (command == "rosdep" || command == "rosdeps" ||
473  command == "rosdep0" || command == "rosdeps0"))
474  {
475  if(!package.size())
476  {
477  rp.logError( "no package given");
478  return false;
479  }
480  if(target.size() || top.size() || length_str.size() ||
481  zombie_only || deps_only || lang.size() || attrib.size())
482  {
483  rp.logError( "invalid option(s) given");
484  return false;
485  }
486  std::set<std::string> rosdeps;
487  bool result = rp.rosdeps(package, (command == "rosdep0" || command == "rosdeps0"), rosdeps);
488  for(std::set<std::string>::const_iterator it = rosdeps.begin();
489  it != rosdeps.end();
490  ++it)
491  output.append(*it + "\n");
492  return result;
493  }
494  // COMMAND: vcs [package]
495  // COMMAND: vcs0 [package]
496  else if(rp.getName() == ROSPACK_NAME &&
497  (command == "vcs" || command == "vcs0"))
498  {
499  if(!package.size())
500  {
501  rp.logError( "no package given");
502  return false;
503  }
504  if(target.size() || top.size() || length_str.size() ||
505  zombie_only || deps_only || lang.size() || attrib.size())
506  {
507  rp.logError( "invalid option(s) given");
508  return false;
509  }
510  std::vector<std::string> vcs;
511  bool result = rp.vcs(package, (command == "vcs0"), vcs);
512  for(std::vector<std::string>::const_iterator it = vcs.begin();
513  it != vcs.end();
514  ++it)
515  output.append(*it + "\n");
516  return result;
517  }
518  // COMMAND: depends-on [package]
519  // COMMAND: depends-on1 [package]
520  else if(command == "depends-on" || command == "depends-on1")
521  {
522  if(!package.size())
523  {
524  rp.logError(std::string("no ") + rp.get_manifest_type() + " given");
525  return false;
526  }
527  if(target.size() || top.size() || length_str.size() ||
528  zombie_only || deps_only || lang.size() || attrib.size())
529  {
530  rp.logError( "invalid option(s) given");
531  return false;
532  }
533  std::vector<std::string> deps;
534  bool result = rp.depsOn(package, (command == "depends-on1"), deps);
535  for(std::vector<std::string>::const_iterator it = deps.begin();
536  it != deps.end();
537  ++it)
538  output.append(*it + "\n");
539  return result;
540  }
541  // COMMAND: export [--deps-only] --lang=<lang> --attrib=<attrib> [package]
542  else if(rp.getName() == ROSPACK_NAME && command == "export")
543  {
544  if(!package.size() || !lang.size() || !attrib.size())
545  {
546  rp.logError( "no package / lang / attrib given");
547  return false;
548  }
549  if(target.size() || top.size() || length_str.size() || zombie_only)
550  {
551  rp.logError( "invalid option(s) given");
552  return false;
553  }
554  std::vector<std::string> flags;
555  bool result = rp.exports(package, lang, attrib, deps_only, flags);
556  for(std::vector<std::string>::const_iterator it = flags.begin();
557  it != flags.end();
558  ++it)
559  {
560  if(it != flags.begin())
561  output.append(" ");
562  output.append(*it);
563  }
564  output.append("\n");
565  return result;
566  }
567  // COMMAND: plugins --attrib=<attrib> [--top=<toppkg>] [package]
568  else if(rp.getName() == ROSPACK_NAME && command == "plugins")
569  {
570  if(!package.size() || !attrib.size())
571  {
572  rp.logError( "no package / attrib given");
573  return false;
574  }
575  if(target.size() || length_str.size() || zombie_only)
576  {
577  rp.logError( "invalid option(s) given");
578  return false;
579  }
580  std::vector<std::string> flags;
581  if(!rp.plugins(package, attrib, top, flags))
582  return false;
583  for(std::vector<std::string>::const_iterator it = flags.begin();
584  it != flags.end();
585  ++it)
586  output.append(*it + "\n");
587  return true;
588  }
589  // COMMAND: cflags-only-I [--deps-only] [package]
590  else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-I")
591  {
592  if(!package.size())
593  {
594  rp.logError( "no package given");
595  return false;
596  }
597  if(target.size() || top.size() || length_str.size() || zombie_only)
598  {
599  rp.logError( "invalid option(s) given");
600  return false;
601  }
602  std::vector<std::pair<std::string, bool> > flags;
603  if(!rp.cpp_exports(package, "--cflags-only-I", "cflags", deps_only, flags))
604  return false;
605 
606  std::string dry_combined;
607  std::string wet_combined;
608  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
609  it != flags.end();
610  ++it)
611  {
612  std::string& combined = it->second ? wet_combined : dry_combined;
613  if(!combined.empty())
614  combined.append(" ");
615  combined.append(it->first);
616  }
617 
618  std::string dry_result;
619  parse_compiler_flags(dry_combined, "-I", true, false, dry_result);
620  output.append(dry_result);
621 
622  std::string wet_result;
623  parse_compiler_flags(wet_combined, "-I", true, false, wet_result);
624  if(!dry_result.empty() && !wet_result.empty())
625  output.append(" ");
626  if(!rp.reorder_paths(wet_result, wet_result))
627  return false;
628  output.append(wet_result + "\n");
629  return true;
630  }
631  // COMMAND: cflags-only-other [--deps-only] [package]
632  else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-other")
633  {
634  if(!package.size())
635  {
636  rp.logError( "no package given");
637  return false;
638  }
639  if(target.size() || top.size() || length_str.size() || zombie_only)
640  {
641  rp.logError( "invalid option(s) given");
642  return false;
643  }
644  std::vector<std::pair<std::string, bool> > flags;
645  if(!rp.cpp_exports(package, "--cflags-only-other", "cflags", deps_only, flags))
646  return false;
647  std::string combined;
648  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
649  it != flags.end();
650  ++it)
651  {
652  if(it != flags.begin())
653  combined.append(" ");
654  combined.append(it->first);
655  }
656  std::string result;
657  parse_compiler_flags(combined, "-I", false, false, result);
658  output.append(result + "\n");
659  return true;
660  }
661  // COMMAND: libs-only-L [--deps-only] [package]
662  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-L")
663  {
664  if(!package.size())
665  {
666  rp.logError( "no package given");
667  return false;
668  }
669  if(target.size() || top.size() || length_str.size() || zombie_only)
670  {
671  rp.logError( "invalid option(s) given");
672  return false;
673  }
674  std::vector<std::pair<std::string, bool> > flags;
675  if(!rp.cpp_exports(package, "--libs-only-L", "lflags", deps_only, flags))
676  return false;
677 
678  std::string dry_combined;
679  std::string wet_combined;
680  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
681  it != flags.end();
682  ++it)
683  {
684  std::string& combined = it->second ? wet_combined : dry_combined;
685  if(!combined.empty())
686  combined.append(" ");
687  combined.append(it->first);
688  }
689 
690  std::string dry_result;
691  parse_compiler_flags(dry_combined, "-L", true, false, dry_result);
692  output.append(dry_result);
693 
694  std::string wet_result;
695  parse_compiler_flags(wet_combined, "-L", true, false, wet_result);
696  if(!dry_result.empty() && !wet_result.empty())
697  output.append(" ");
698  if(!rp.reorder_paths(wet_result, wet_result))
699  return false;
700  output.append(wet_result + "\n");
701  return true;
702  }
703  // COMMAND: libs-only-l [--deps-only] [package]
704  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-l")
705  {
706  if(!package.size())
707  {
708  rp.logError( "no package given");
709  return false;
710  }
711  if(target.size() || top.size() || length_str.size() || zombie_only)
712  {
713  rp.logError( "invalid option(s) given");
714  return false;
715  }
716  std::vector<std::pair<std::string, bool> > flags;
717  if(!rp.cpp_exports(package, "--libs-only-l", "lflags", deps_only, flags))
718  return false;
719  std::string combined;
720  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
721  it != flags.end();
722  ++it)
723  {
724  if(it != flags.begin())
725  combined.append(" ");
726  combined.append(it->first);
727  }
728  std::string result;
729  parse_compiler_flags(combined, "-l", true, true, result);
730  output.append(result + "\n");
731  return true;
732  }
733  // COMMAND: libs-only-other [--deps-only] [package]
734  else if(rp.getName() == ROSPACK_NAME && command == "libs-only-other")
735  {
736  if(!package.size())
737  {
738  rp.logError( "no package given");
739  return false;
740  }
741  if(target.size() || top.size() || length_str.size() || zombie_only)
742  {
743  rp.logError( "invalid option(s) given");
744  return false;
745  }
746  std::vector<std::pair<std::string, bool> > flags;
747  if(!rp.cpp_exports(package, "--libs-only-other", "lflags", deps_only, flags))
748  return false;
749  std::string combined;
750  for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
751  it != flags.end();
752  ++it)
753  {
754  if(it != flags.begin())
755  combined.append(" ");
756  combined.append(it->first);
757  }
758  std::string intermediate;
759  parse_compiler_flags(combined, "-L", false, false, intermediate);
760  std::string result;
761  parse_compiler_flags(intermediate, "-l", false, false, result);
762  output.append(result + "\n");
763  return true;
764  }
765  // COMMAND: contents [stack]
766  else if(rp.getName() == ROSSTACK_NAME && command == "contents")
767  {
768  if(!package.size())
769  {
770  rp.logError( "no stack given");
771  return false;
772  }
773  if(target.size() || top.size() || length_str.size() ||
774  zombie_only || deps_only || lang.size() || attrib.size())
775  {
776  rp.logError( "invalid option(s) given");
777  return false;
778  }
779 
780  std::set<std::string> packages;
781  rp.contents(package, packages);
782  for(std::set<std::string>::const_iterator it = packages.begin();
783  it != packages.end();
784  ++it)
785  output.append(*it + "\n");
786  return true;
787  }
788  // COMMAND: contains [package]
789  else if(rp.getName() == ROSSTACK_NAME &&
790  ((command == "contains") || (command == "contains-path")))
791  {
792  if(!package.size())
793  {
794  rp.logError( "no package given");
795  return false;
796  }
797  if(target.size() || top.size() || length_str.size() ||
798  zombie_only || deps_only || lang.size() || attrib.size())
799  {
800  rp.logError( "invalid option(s) given");
801  return false;
802  }
803  std::string name, path;
804  if(!rp.contains(package, name, path))
805  return false;
806  if(command == "contains")
807  output.append(name + "\n");
808  else // command == "contains-path"
809  output.append(path + "\n");
810  return true;
811  }
812  else
813  {
814  rp.logError(std::string("command ") + command + " not implemented");
815  return false;
816  }
817 }
818 
819 bool
820 parse_args(int argc, char** argv,
821  rospack::Rosstackage& rp, po::variables_map& vm)
822 {
823  po::options_description desc("Allowed options");
824  desc.add_options()
825  ("command", po::value<std::string>(), "command")
826  ("package", po::value<std::string>(), "package")
827  ("target", po::value<std::string>(), "target")
828  ("deps-only", "deps-only")
829  ("lang", po::value<std::string>(), "lang")
830  ("attrib", po::value<std::string>(), "attrib")
831  ("top", po::value<std::string>(), "top")
832  ("length", po::value<std::string>(), "length")
833  ("zombie-only", "zombie-only")
834  ("help", "help")
835  ("-h", "help")
836  ("quiet,q", "quiet");
837 
838  po::positional_options_description pd;
839  pd.add("command", 1).add("package", 1);
840  try
841  {
842  po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);
843  }
844  catch(boost::program_options::error e)
845  {
846  rp.logError( std::string("failed to parse command-line options: ") + e.what());
847  return false;
848  }
849  po::notify(vm);
850 
851  return true;
852 }
853 
854 }
rospack::Rosstackage::usage
virtual const char * usage()
Usage string, to be overridden by derived classes.
Definition: rospack.h:217
rospack::Rosstackage::depsManifests
bool depsManifests(const std::string &name, bool direct, std::vector< std::string > &manifests)
List the manifests of a stackage's dependencies. Used by rosbuild.
Definition: rospack.cpp:665
rospack_cmdline.h
rospack::Rosstackage::listDuplicatesWithPaths
void listDuplicatesWithPaths(std::map< std::string, std::vector< std::string > > &dups)
Identify duplicate stackages and provide their paths. Forces crawl.
Definition: rospack.cpp:535
rospack::Rosstackage::rosdeps
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....
Definition: rospack.cpp:691
rospack::Rosstackage::getSearchPathFromEnv
bool getSearchPathFromEnv(std::vector< std::string > &sp)
Helper method to construct a directory search path by looking at relevant environment variables....
Definition: rospack.cpp:284
rospack::Rosstackage::depsOn
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)....
Definition: rospack.cpp:581
rospack::Rosstackage::list
void list(std::set< std::pair< std::string, std::string > > &list)
List names and paths of all stackages.
Definition: rospack.cpp:507
rospack::parse_compiler_flags
void parse_compiler_flags(const std::string &instring, const std::string &token, bool select, bool last, std::string &outstring)
Definition: utils.cpp:75
rospack.h
rospack::Rosstackage::depsIndent
bool depsIndent(const std::string &name, bool direct, std::vector< std::string > &deps)
Definition: rospack.cpp:594
rospack::Rosstackage::cpp_exports
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:815
rospack::Rosstackage::plugins
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....
Definition: rospack.cpp:1093
rospack::Rosstackage::find
bool find(const std::string &name, std::string &path)
Look for a stackage.
Definition: rospack.cpp:436
rospack::Rosstackage::getName
const std::string & getName()
Get the name of the tool that's in use (e.g., "rospack" or "rosstack")
Definition: rospack.h:248
rospack::Rosstackage::vcs
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....
Definition: rospack.cpp:766
rospack::Rosstackage::logError
void logError(const std::string &msg, bool append_errno=false)
Log a error (usually goes to stderr).
Definition: rospack.cpp:277
rospack::parse_args
bool parse_args(int argc, char **argv, rospack::Rosstackage &rp, po::variables_map &vm)
Definition: rospack_cmdline.cpp:820
rospack::Rosstackage::profile
bool profile(const std::vector< std::string > &search_path, bool zombie_only, int length, std::vector< std::string > &dirs)
Definition: rospack.cpp:1337
deep.package
string package
Definition: deep.py:54
rospack::Rosstackage::crawl
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:361
rospack::rospack_run
bool rospack_run(int argc, char **argv, rospack::Rosstackage &rp, std::string &output)
Definition: rospack_cmdline.cpp:49
utils.h
rospack::Rosstackage::inStackage
bool inStackage(std::string &name)
Is the current working directory a stackage?
Definition: rospack.cpp:400
rospack::Rosstackage::exports
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:991
rospack::Rosstackage::contents
bool contents(const std::string &name, std::set< std::string > &packages)
Compute the packages that are contained in a stack.
Definition: rospack.cpp:449
rospack::Rosstackage::depsWhy
bool depsWhy(const std::string &from, const std::string &to, std::string &output)
Definition: rospack.cpp:622
rospack::Rosstackage::deps
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:555
rospack::Rosstackage::setQuiet
void setQuiet(bool quiet)
Control warning and error console output.
Definition: rospack.cpp:312
rospack
Definition: rospack.h:123
rospack::Rosstackage::depsMsgSrv
bool depsMsgSrv(const std::string &name, bool direct, std::vector< std::string > &gens)
List the marker files in a packages's dependencies that indicate that those packages contain auto-gen...
Definition: rospack.cpp:1160
rospack::Rosstackage
The base class for package/stack ("stackage") crawlers. Users of the library should use the functiona...
Definition: rospack.h:141
rospack::ROSPACK_NAME
static const char * ROSPACK_NAME
Definition: utils.h:42
rospack::Rosstackage::reorder_paths
bool reorder_paths(const std::string &paths, std::string &reordered)
Reorder the paths according to the workspace chaining.
Definition: rospack.cpp:927
rospack::Rosstackage::get_manifest_type
virtual std::string get_manifest_type()
Definition: rospack.h:553
rospack::ROSSTACK_NAME
static const char * ROSSTACK_NAME
Definition: utils.h:43
rospack::Rosstackage::contains
bool contains(const std::string &name, std::string &stack, std::string &path)
Find the stack that contains a package.
Definition: rospack.cpp:475


rospack
Author(s): Brian Gerkey, Morgan Quigley, Dirk Thomas
autogenerated on Wed Mar 2 2022 00:54:50