| 1 | <html> | 
|---|
| 2 | <head> | 
|---|
| 3 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|---|
| 4 | <title>Tutorial</title> | 
|---|
| 5 | <link rel="stylesheet" href="../boostbook.css" type="text/css"> | 
|---|
| 6 | <meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> | 
|---|
| 7 | <link rel="start" href="../index.html" title="The Boost C++ Libraries"> | 
|---|
| 8 | <link rel="up" href="../program_options.html" title="Chapter 7. Boost.Program_options"> | 
|---|
| 9 | <link rel="prev" href="../program_options.html" title="Chapter 7. Boost.Program_options"> | 
|---|
| 10 | <link rel="next" href="overview.html" title="Library Overview"> | 
|---|
| 11 | </head> | 
|---|
| 12 | <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | 
|---|
| 13 | <table cellpadding="2" width="100%"> | 
|---|
| 14 | <td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> | 
|---|
| 15 | <td align="center"><a href="../../../index.htm">Home</a></td> | 
|---|
| 16 | <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> | 
|---|
| 17 | <td align="center"><a href="../../../people/people.htm">People</a></td> | 
|---|
| 18 | <td align="center"><a href="../../../more/faq.htm">FAQ</a></td> | 
|---|
| 19 | <td align="center"><a href="../../../more/index.htm">More</a></td> | 
|---|
| 20 | </table> | 
|---|
| 21 | <hr> | 
|---|
| 22 | <div class="spirit-nav"> | 
|---|
| 23 | <a accesskey="p" href="../program_options.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="overview.html"><img src="../images/next.png" alt="Next"></a> | 
|---|
| 24 | </div> | 
|---|
| 25 | <div class="section" lang="en"> | 
|---|
| 26 | <div class="titlepage"><div><div><h3 class="title"> | 
|---|
| 27 | <a name="program_options.tutorial"></a>Tutorial</h3></div></div></div> | 
|---|
| 28 | <div class="toc"><dl> | 
|---|
| 29 | <dt><span class="section"><a href="tutorial.html#id2714212">Getting Started</a></span></dt> | 
|---|
| 30 | <dt><span class="section"><a href="tutorial.html#id2714372">Option Details</a></span></dt> | 
|---|
| 31 | <dt><span class="section"><a href="tutorial.html#id2714557">Multiple Sources</a></span></dt> | 
|---|
| 32 | </dl></div> | 
|---|
| 33 | <p>In this section, we'll take a look at the most common usage scenarios | 
|---|
| 34 |   of the program_options library, starting with the simplest one. The examples | 
|---|
| 35 |   show only the interesting code parts, but the complete programs can be found | 
|---|
| 36 |   in the "BOOST_ROOT/libs/program_options/example" directory. Through all the | 
|---|
| 37 |   examples, we'll assume that the following namespace alias is in effect: | 
|---|
| 38 | </p> | 
|---|
| 39 | <pre class="programlisting">namespace po = boost::program_options;</pre> | 
|---|
| 40 | <div class="section" lang="en"> | 
|---|
| 41 | <div class="titlepage"><div><div><h4 class="title"> | 
|---|
| 42 | <a name="id2714212"></a>Getting Started</h4></div></div></div> | 
|---|
| 43 | <p>The first example is the simplest possible: it only handles two | 
|---|
| 44 |     options. Here's the source code (the full program is in | 
|---|
| 45 |     "example/first.cpp"): | 
|---|
| 46 |  | 
|---|
| 47 | </p> | 
|---|
| 48 | <pre class="programlisting"> | 
|---|
| 49 | // Declare the supported options. | 
|---|
| 50 | po::options_description desc("Allowed options"); | 
|---|
| 51 | desc.add_options() | 
|---|
| 52 |     ("help", "produce help message") | 
|---|
| 53 |     ("compression", po::value<int>(), "set compression level") | 
|---|
| 54 | ; | 
|---|
| 55 |  | 
|---|
| 56 | po::variables_map vm; | 
|---|
| 57 | po::store(po::parse_command_line(ac, av, desc), vm); | 
|---|
| 58 | po::notify(vm);     | 
|---|
| 59 |  | 
|---|
| 60 | if (vm.count("help")) { | 
|---|
| 61 |     cout << desc << "\n"; | 
|---|
| 62 |     return 1; | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | if (vm.count("compression")) { | 
|---|
| 66 |     cout << "Compression level was set to "  | 
|---|
| 67 |  << vm["compression"].as<int>() << ".\n"; | 
|---|
| 68 | } else { | 
|---|
| 69 |     cout << "Compression level was not set.\n"; | 
|---|
| 70 | } | 
|---|
| 71 | </pre> | 
|---|
| 72 | <p>We start by declaring all allowed options using the | 
|---|
| 73 |     <code class="computeroutput"><a href="../options_description.html" title="Class options_description">options_description</a></code> class. The <code class="computeroutput">add_options</code> method of that | 
|---|
| 74 |     class returns a special proxy object that defines | 
|---|
| 75 |     <code class="computeroutput">operator()</code>. Calls to that operator actually declare | 
|---|
| 76 |     options. The parameters are option name, information about value, and option | 
|---|
| 77 |     description. In this example, the first option has no value, and the second | 
|---|
| 78 |     one has a value of type <code class="computeroutput">int</code>. | 
|---|
| 79 |   </p> | 
|---|
| 80 | <p>After that, an object of class <code class="computeroutput">variables_map</code> is | 
|---|
| 81 |     declared. That class is intended to store values of options, and can store | 
|---|
| 82 |     values of arbitrary types. Next, the calls to <code class="computeroutput">store</code>, | 
|---|
| 83 |     <code class="computeroutput">parse_command_line</code> and <code class="computeroutput">notify</code> functions cause | 
|---|
| 84 |     <code class="computeroutput">vm</code> to contain all the options found on the command | 
|---|
| 85 |     line.</p> | 
|---|
| 86 | <p>And now, finally, we can use the options as we like. The | 
|---|
| 87 |     <code class="computeroutput">variables_map</code> class can be used just like | 
|---|
| 88 |     <code class="computeroutput">std::map</code>, except that values stored there must be retrieved | 
|---|
| 89 |     with the <code class="computeroutput">as</code> method shown above. (If the type specified in the | 
|---|
| 90 |     call to the <code class="computeroutput">as</code> method is different from the actually stored | 
|---|
| 91 |     type, an exception is thrown.) | 
|---|
| 92 |   </p> | 
|---|
| 93 | <p>It's now a good time to try compiling the code yourself, but if | 
|---|
| 94 |     you're not yet ready, here's an example session: | 
|---|
| 95 | </p> | 
|---|
| 96 | <pre class="screen"> | 
|---|
| 97 | $<strong class="userinput"><code>bin/gcc/debug/first</code></strong> | 
|---|
| 98 | Compression level was not set. | 
|---|
| 99 | $<strong class="userinput"><code>bin/gcc/debug/first --help</code></strong> | 
|---|
| 100 | Allowed options: | 
|---|
| 101 |   --help                 : produce help message | 
|---|
| 102 |   --compression arg      : set compression level | 
|---|
| 103 | $<strong class="userinput"><code>bin/gcc/debug/first --compression 10</code></strong> | 
|---|
| 104 | Compression level was set to 10. | 
|---|
| 105 |     </pre> | 
|---|
| 106 | </div> | 
|---|
| 107 | <div class="section" lang="en"> | 
|---|
| 108 | <div class="titlepage"><div><div><h4 class="title"> | 
|---|
| 109 | <a name="id2714372"></a>Option Details</h4></div></div></div> | 
|---|
| 110 | <p>An option value, surely, can have other types than <code class="computeroutput">int</code>, and | 
|---|
| 111 |   can have other interesting properties, which we'll discuss right now. The | 
|---|
| 112 |   complete version of the code snipped below can be found in | 
|---|
| 113 |   "example/options_description.cpp".</p> | 
|---|
| 114 | <p>Imagine we're writing a compiler. It should take the optimization | 
|---|
| 115 |     level, a number of include paths, and a number of input files, and perform some | 
|---|
| 116 |     interesting work. Let's describe the options: | 
|---|
| 117 |     </p> | 
|---|
| 118 | <pre class="programlisting"> | 
|---|
| 119 | int opt; | 
|---|
| 120 | po::options_description desc("Allowed options"); | 
|---|
| 121 | desc.add_options() | 
|---|
| 122 |     ("help", "produce help message") | 
|---|
| 123 |     ("optimization", po::value<int>(&opt)->default_value(10),  | 
|---|
| 124 |   "optimization level") | 
|---|
| 125 |     ("include-path,I", po::value< vector<string> >(),  | 
|---|
| 126 |   "include path") | 
|---|
| 127 |     ("input-file", po::value< vector<string> >(), "input file") | 
|---|
| 128 | ; | 
|---|
| 129 | </pre> | 
|---|
| 130 | <p>The "--help" option should be familiar from the previous example.  | 
|---|
| 131 |     It's a good idea to have this option in all cases.</p> | 
|---|
| 132 | <p>The "optimization" option shows two new features. First, we specify | 
|---|
| 133 |     the address of the variable(<code class="computeroutput">&opt</code>). After storing values, that | 
|---|
| 134 |     variable will have the value of the option. Second, we specify a default | 
|---|
| 135 |     value of 10, which will be used if no value is specified by the user. | 
|---|
| 136 |   </p> | 
|---|
| 137 | <p>The "include-path" option is an example of the only case where | 
|---|
| 138 |     the interface of the <code class="computeroutput">options_description</code> class serves only one | 
|---|
| 139 |     source -- the command line. Users typically like to use short option names | 
|---|
| 140 |     for common options, and the "include-path,I" name specifies that short | 
|---|
| 141 |     option name is "I". So, both "--include-path" and "-I" can be used. | 
|---|
| 142 |   </p> | 
|---|
| 143 | <p>The "input-file" option specifies the list of files to | 
|---|
| 144 |     process. That's okay for a start, but, of course, writing something like: | 
|---|
| 145 |     </p> | 
|---|
| 146 | <pre class="screen"><strong class="userinput"><code>compiler --input-file=a.cpp</code></strong></pre> | 
|---|
| 147 | <p> | 
|---|
| 148 |     is a little non-standard, compared with | 
|---|
| 149 |     </p> | 
|---|
| 150 | <pre class="screen"><strong class="userinput"><code>compiler a.cpp</code></strong></pre> | 
|---|
| 151 | <p> | 
|---|
| 152 |     We'll address this in a moment. | 
|---|
| 153 |   </p> | 
|---|
| 154 | <p> | 
|---|
| 155 |     The command line tokens which have no option name, as above, are | 
|---|
| 156 |     called "positional options" by this library. They can be handled | 
|---|
| 157 |     too. With a little help from the user, the library can decide that "a.cpp" | 
|---|
| 158 |     really means the same as "--input-file=a.cpp". Here's the additional code | 
|---|
| 159 |     we need: | 
|---|
| 160 |     </p> | 
|---|
| 161 | <pre class="programlisting"> | 
|---|
| 162 | po::positional_options_description p; | 
|---|
| 163 | p.add("input-file", -1); | 
|---|
| 164 |  | 
|---|
| 165 | po::variables_map vm; | 
|---|
| 166 | po::store(po::command_line_parser(ac, av). | 
|---|
| 167 |           options(desc).positional(p).run(), vm); | 
|---|
| 168 | po::notify(vm); | 
|---|
| 169 |     </pre> | 
|---|
| 170 | <p> | 
|---|
| 171 |     The first two lines say that all positional options should be translated | 
|---|
| 172 |     into "input-file" options. Also note that we use the | 
|---|
| 173 |     <code class="computeroutput">command_line_parser</code> class to parse the command | 
|---|
| 174 |     line, not the <code class="computeroutput"><a href="../parse_command_line.html" title="Function template parse_command_line">parse_command_line</a></code> | 
|---|
| 175 |     function. The latter is a convenient wrapper for simple cases, but now we | 
|---|
| 176 |     need to pass additional information. | 
|---|
| 177 |   </p> | 
|---|
| 178 | <p>By now, all options are described and parsed. We'll save ourselves the | 
|---|
| 179 |       trouble of implementing the rest of the compiler logic and only print the | 
|---|
| 180 |       options: | 
|---|
| 181 |     </p> | 
|---|
| 182 | <pre class="programlisting"> | 
|---|
| 183 | if (vm.count("include-path")) | 
|---|
| 184 | { | 
|---|
| 185 |     cout << "Include paths are: "  | 
|---|
| 186 |          << vm["include-path"].as< vector<string> >() << "\n"; | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | if (vm.count("input-file")) | 
|---|
| 190 | { | 
|---|
| 191 |     cout << "Input files are: "  | 
|---|
| 192 |          << vm["input-file"].as< vector<string> >() << "\n"; | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | cout << "Optimization level is " << opt << "\n";                 | 
|---|
| 196 | </pre> | 
|---|
| 197 | <p>Here's an example session: | 
|---|
| 198 |     </p> | 
|---|
| 199 | <pre class="screen"> | 
|---|
| 200 | $<strong class="userinput"><code>bin/gcc/debug/options_description --help</code></strong> | 
|---|
| 201 | Usage: options_description [options] | 
|---|
| 202 | Allowed options: | 
|---|
| 203 |   --help                 : produce help message | 
|---|
| 204 |   --optimization arg     : optimization level | 
|---|
| 205 |   -I [ --include-path ] arg : include path | 
|---|
| 206 |   --input-file arg       : input file | 
|---|
| 207 | $bin/gcc/debug/options_description | 
|---|
| 208 | Optimization level is 10 | 
|---|
| 209 | $<strong class="userinput"><code>bin/gcc/debug/options_description --optimization 4 -I foo a.cpp</code></strong> | 
|---|
| 210 | Include paths are: foo | 
|---|
| 211 | Input files are: a.cpp | 
|---|
| 212 | Optimization level is 4 | 
|---|
| 213 | </pre> | 
|---|
| 214 | <p> | 
|---|
| 215 |     Oops, there's a slight problem. It's still possible to specify the | 
|---|
| 216 |     "--input-file" option, and usage message says so, which can be confusing | 
|---|
| 217 |     for the user. It would be nice to hide this information, but let's wait | 
|---|
| 218 |     for the next example. | 
|---|
| 219 |   </p> | 
|---|
| 220 | </div> | 
|---|
| 221 | <div class="section" lang="en"> | 
|---|
| 222 | <div class="titlepage"><div><div><h4 class="title"> | 
|---|
| 223 | <a name="id2714557"></a>Multiple Sources</h4></div></div></div> | 
|---|
| 224 | <p>It's quite likely that specifying all options to our compiler on the | 
|---|
| 225 |     command line will annoy users. What if a user installs a new library and | 
|---|
| 226 |     wants to always pass an additional command line element? What if he has | 
|---|
| 227 |     made some choices which should be applied on every run? It's desirable to | 
|---|
| 228 |     create a config file with common settings which will be used together with | 
|---|
| 229 |     the command line. | 
|---|
| 230 |     </p> | 
|---|
| 231 | <p>Of course, there will be a need to combine the values from command | 
|---|
| 232 |     line and config file. For example, the optimization level specified on the | 
|---|
| 233 |     command line should override the value from the config file. On the other | 
|---|
| 234 |     hand, include paths should be combined. | 
|---|
| 235 |     </p> | 
|---|
| 236 | <p>Let's see the code now. The complete program is in | 
|---|
| 237 |       "examples/multiple_sources.cpp". The option definition has two interesting | 
|---|
| 238 |       details. First, we declare several instances of the | 
|---|
| 239 |       <code class="computeroutput">options_description</code> class. The reason is that, in general, | 
|---|
| 240 |       not all options are alike. Some options, like "input-file" above, should | 
|---|
| 241 |       not be presented in an automatic help message. Some options make sense only | 
|---|
| 242 |       in the config file. Finally, it's nice to have some structure in the help message, | 
|---|
| 243 |       not just a long list of options. Let's declare several option groups: | 
|---|
| 244 |       </p> | 
|---|
| 245 | <pre class="programlisting"> | 
|---|
| 246 | // Declare a group of options that will be  | 
|---|
| 247 | // allowed only on command line | 
|---|
| 248 | po::options_description generic("Generic options"); | 
|---|
| 249 | generic.add_options() | 
|---|
| 250 |     ("version,v", "print version string") | 
|---|
| 251 |     ("help", "produce help message")     | 
|---|
| 252 |     ; | 
|---|
| 253 |      | 
|---|
| 254 | // Declare a group of options that will be  | 
|---|
| 255 | // allowed both on command line and in | 
|---|
| 256 | // config file | 
|---|
| 257 | po::options_description config("Configuration"); | 
|---|
| 258 | config.add_options() | 
|---|
| 259 |     ("optimization", po::value<int>(&opt)->default_value(10),  | 
|---|
| 260 |           "optimization level") | 
|---|
| 261 |     ("include-path,I",  | 
|---|
| 262 |          po::value< vector<string> >()->composing(),  | 
|---|
| 263 |          "include path") | 
|---|
| 264 |     ; | 
|---|
| 265 |  | 
|---|
| 266 | // Hidden options, will be allowed both on command line and | 
|---|
| 267 | // in config file, but will not be shown to the user. | 
|---|
| 268 | po::options_description hidden("Hidden options"); | 
|---|
| 269 | hidden.add_options() | 
|---|
| 270 |     ("input-file", po::value< vector<string> >(), "input file") | 
|---|
| 271 |     ;         | 
|---|
| 272 | </pre> | 
|---|
| 273 | <p> | 
|---|
| 274 |       Note the call to the <code class="computeroutput">composing</code> method in the declaration of the | 
|---|
| 275 |       "include-path" option. It tells the library that values from different sources | 
|---|
| 276 |       should be composed together, as we'll see shortly. | 
|---|
| 277 |     </p> | 
|---|
| 278 | <p>     | 
|---|
| 279 |       The <code class="computeroutput">add</code> method of the <code class="computeroutput">options_description</code> | 
|---|
| 280 |       class can be used to further group the options: | 
|---|
| 281 |       </p> | 
|---|
| 282 | <pre class="programlisting"> | 
|---|
| 283 | po::options_description cmdline_options; | 
|---|
| 284 | cmdline_options.add(generic).add(config).add(hidden); | 
|---|
| 285 |  | 
|---|
| 286 | po::options_description config_file_options; | 
|---|
| 287 | config_file_options.add(config).add(hidden); | 
|---|
| 288 |  | 
|---|
| 289 | po::options_description visible("Allowed options"); | 
|---|
| 290 | visible.add(generic).add(config); | 
|---|
| 291 |       </pre> | 
|---|
| 292 | <p>The parsing and storing of values follows the usual pattern, except that | 
|---|
| 293 |       we additionally call <code class="computeroutput">parse_config_file</code>, and | 
|---|
| 294 |       call the <code class="computeroutput"><a href="../id2349650.html" title="Function store">store</a></code> function twice. But what | 
|---|
| 295 |       happens if the same value is specified both on the command line and in | 
|---|
| 296 |       config file? Usually, the value stored first is preferred. This is what | 
|---|
| 297 |       happens for the "--optimization" option. For "composing" options, like | 
|---|
| 298 |       "include-file", the values are merged. | 
|---|
| 299 |     </p> | 
|---|
| 300 | <p>Here's an example session: | 
|---|
| 301 | </p> | 
|---|
| 302 | <pre class="screen"> | 
|---|
| 303 | $<strong class="userinput"><code>bin/gcc/debug/multiple_sources</code></strong> | 
|---|
| 304 | Include paths are: /opt | 
|---|
| 305 | Optimization level is 1 | 
|---|
| 306 | $<strong class="userinput"><code>bin/gcc/debug/multiple_sources --help</code></strong> | 
|---|
| 307 | Allows options: | 
|---|
| 308 |  | 
|---|
| 309 | Generic options: | 
|---|
| 310 |   -v [ --version ]       : print version string | 
|---|
| 311 |   --help                 : produce help message | 
|---|
| 312 |  | 
|---|
| 313 | Configuration: | 
|---|
| 314 |   --optimization n       : optimization level | 
|---|
| 315 |   -I [ --include-path ] path : include path | 
|---|
| 316 |  | 
|---|
| 317 | $<strong class="userinput"><code>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</code></strong> | 
|---|
| 318 | Include paths are: foo /opt | 
|---|
| 319 | Input files are: a.cpp b.cpp | 
|---|
| 320 | Optimization level is 4 | 
|---|
| 321 | </pre> | 
|---|
| 322 | <p> | 
|---|
| 323 |       The first invocation uses values from the configuration file. The second | 
|---|
| 324 |       invocation also uses values from command line. As we see, the include | 
|---|
| 325 |       paths on the command line and in the configuration file are merged, | 
|---|
| 326 |       while optimization is taken from the command line. | 
|---|
| 327 |     </p> | 
|---|
| 328 | </div> | 
|---|
| 329 | </div> | 
|---|
| 330 | <table width="100%"><tr> | 
|---|
| 331 | <td align="left"></td> | 
|---|
| 332 | <td align="right"><small>Copyright © 2002-2004 Vladimir Prus</small></td> | 
|---|
| 333 | </tr></table> | 
|---|
| 334 | <hr> | 
|---|
| 335 | <div class="spirit-nav"> | 
|---|
| 336 | <a accesskey="p" href="../program_options.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../program_options.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="overview.html"><img src="../images/next.png" alt="Next"></a> | 
|---|
| 337 | </div> | 
|---|
| 338 | </body> | 
|---|
| 339 | </html> | 
|---|