From Craig Silverstein: add support for searching for input files
[platform/upstream/binutils.git] / gold / options.cc
1 // options.c -- handle command line options for gold
2
3 // Copyright 2006, 2007 Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
5
6 // This file is part of gold.
7
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
12
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 // MA 02110-1301, USA.
22
23 #include <iostream>
24
25 #include "gold.h"
26 #include "options.h"
27
28 namespace gold
29 {
30
31 // The information we keep for a single command line option.
32
33 struct options::One_option
34 {
35   // The single character option name, or '\0' if this is only a long
36   // option.
37   char short_option;
38
39   // The long option name, or NULL if this is only a short option.
40   const char* long_option;
41
42   // Description of the option for --help output, or NULL if there is none.
43   const char* doc;
44
45   // How to print the option name in --help output, or NULL to use the
46   // default.
47   const char* help_output;
48
49   // Long option dash control.  This is ignored if long_option is
50   // NULL.
51   enum
52     {
53       // Long option normally takes one dash; two dashes are also
54       // accepted.
55       ONE_DASH,
56       // Long option normally takes two dashes; one dash is also
57       // accepted.
58       TWO_DASHES,
59       // Long option always takes two dashes.
60       EXACTLY_TWO_DASHES
61     } dash;
62
63   // Function for special handling, or NULL.  Returns the number of
64   // arguments to skip.  This will normally be at least 1, but it may
65   // be 0 if this function changes *argv.  ARG points to the location
66   // in *ARGV where the option starts, which may be helpful for a
67   // short option.
68   int (*special)(int argc, char** argv, char *arg, Command_line*);
69
70   // If this is a position independent option which does not take an
71   // argument, this is the member function to call to record it.
72   void (General_options::*general_noarg)();
73
74   // If this is a position independent function which takes an
75   // argument, this is the member function to call to record it.
76   void (General_options::*general_arg)(const char*);
77
78   // If this is a position dependent option which does not take an
79   // argument, this is the member function to call to record it.
80   void (Position_dependent_options::*dependent_noarg)();
81
82   // If this is a position dependent option which takes an argument,
83   // this is the member function to record it.
84   void (Position_dependent_options::*dependent_arg)(const char*);
85
86   // Return whether this option takes an argument.
87   bool
88   takes_argument() const
89   { return this->general_arg != NULL || this->dependent_arg != NULL; }
90 };
91
92 class options::Command_line_options
93 {
94  public:
95   static const One_option options[];
96   static const int options_size;
97 };
98
99 } // End namespace gold.
100
101 namespace
102 {
103
104 // Handle the special -l option, which adds an input file.
105
106 int
107 library(int argc, char** argv, char* arg, gold::Command_line* cmdline)
108 {
109   return cmdline->process_l_option(argc, argv, arg);
110 }
111
112 // Handle the special --start-group option.
113
114 int
115 start_group(int, char**, char* arg, gold::Command_line* cmdline)
116 {
117   cmdline->start_group(arg);
118   return 1;
119 }
120
121 // Handle the special --end-group option.
122
123 int
124 end_group(int, char**, char* arg, gold::Command_line* cmdline)
125 {
126   cmdline->end_group(arg);
127   return 1;
128 }
129
130 // Report usage information for ld --help, and exit.
131
132 int
133 help(int, char**, char*, gold::Command_line*)
134 {
135   printf(_("Usage: %s [options] file...\nOptions:\n"), gold::program_name);
136
137   const int options_size = gold::options::Command_line_options::options_size;
138   const gold::options::One_option* options =
139     gold::options::Command_line_options::options;
140   for (int i = 0; i < options_size; ++i)
141     {
142       if (options[i].doc == NULL)
143         continue;
144
145       printf("  ");
146       int len = 2;
147       bool comma = false;
148
149       int j = i;
150       do
151         {
152           if (options[j].help_output != NULL)
153             {
154               if (comma)
155                 {
156                   printf(", ");
157                   len += 2;
158                 }
159               printf(options[j].help_output);
160               len += std::strlen(options[i].help_output);
161               comma = true;
162             }
163           else
164             {
165               if (options[j].short_option != '\0')
166                 {
167                   if (comma)
168                     {
169                       printf(", ");
170                       len += 2;
171                     }
172                   printf("-%c", options[j].short_option);
173                   len += 2;
174                   comma = true;
175                 }
176
177               if (options[j].long_option != NULL)
178                 {
179                   if (comma)
180                     {
181                       printf(", ");
182                       len += 2;
183                     }
184                   if (options[j].dash == gold::options::One_option::ONE_DASH)
185                     {
186                       printf("-");
187                       ++len;
188                     }
189                   else
190                     {
191                       printf("--");
192                       len += 2;
193                     }
194                   printf("%s", options[j].long_option);
195                   len += std::strlen(options[j].long_option);
196                   comma = true;
197                 }
198             }
199           ++j;
200         }
201       while (j < options_size && options[j].doc == NULL);
202
203       if (len >= 30)
204         {
205           printf("\n");
206           len = 0;
207         }
208       for (; len < 30; ++len)
209         std::putchar(' ');
210
211       std::puts(options[i].doc);
212     }
213
214   gold::gold_exit(true);
215
216   return 0;
217 }
218
219 } // End anonymous namespace.
220
221 namespace gold
222 {
223
224 // Helper macros used to specify the options.  We could also do this
225 // using constructors, but then g++ would generate code to initialize
226 // the array.  We want the array to be initialized statically so that
227 // we get better startup time.
228
229 #define GENERAL_NOARG(short_option, long_option, doc, help, dash, func) \
230   { short_option, long_option, doc, help, options::One_option::dash, \
231       NULL, func, NULL, NULL, NULL }
232 #define GENERAL_ARG(short_option, long_option, doc, help, dash, func)   \
233   { short_option, long_option, doc, help, options::One_option::dash, \
234       NULL, NULL, func, NULL, NULL }
235 #define POSDEP_NOARG(short_option, long_option, doc, help, dash, func)  \
236   { short_option, long_option, doc, help, options::One_option::dash, \
237       NULL,  NULL, NULL, func, NULL }
238 #define POSDEP_ARG(short_option, long_option, doc, help, dash, func)    \
239   { short_option, long_option, doc, help, options::One_option::dash, \
240       NULL, NULL, NULL, NULL, func }
241 #define SPECIAL(short_option, long_option, doc, help, dash, func)       \
242   { short_option, long_option, doc, help, options::One_option::dash, \
243       func, NULL, NULL, NULL, NULL }
244
245 // Here is the actual list of options which we accept.
246
247 const options::One_option
248 options::Command_line_options::options[] =
249 {
250   SPECIAL('l', "library", N_("Search for library LIBNAME"),
251           N_("-lLIBNAME, --library LIBNAME"), TWO_DASHES,
252           &library),
253   SPECIAL('(', "start-group", N_("Start a library search group"), NULL,
254           TWO_DASHES, &start_group),
255   SPECIAL(')', "end-group", N_("End a library search group"), NULL,
256           TWO_DASHES, &end_group),
257   GENERAL_NOARG('E', "export-dynamic", N_("Export all dynamic symbols"),
258                 NULL, TWO_DASHES, &General_options::set_export_dynamic),
259   GENERAL_ARG('I', "dynamic-linker", N_("Set dynamic linker path"),
260               N_("-I PROGRAM, --dynamic-linker PROGRAM"), TWO_DASHES,
261               &General_options::set_dynamic_linker),
262   GENERAL_ARG('L', "library-path", N_("Add directory to search path"),
263               N_("-L DIR, --library-path DIR"), TWO_DASHES,
264               &General_options::add_to_search_path),
265   GENERAL_ARG('m', NULL, N_("Ignored for compatibility"), NULL, ONE_DASH,
266               &General_options::ignore),
267   GENERAL_ARG('O', NULL, N_("Optimize output file size"),
268               N_("-O level"), ONE_DASH,
269               &General_options::set_optimization_level),
270   GENERAL_ARG('o', "output", N_("Set output file name"),
271               N_("-o FILE, --output FILE"), TWO_DASHES,
272               &General_options::set_output_file_name),
273   GENERAL_NOARG('r', NULL, N_("Generate relocatable output"), NULL,
274                 ONE_DASH, &General_options::set_relocatable),
275   GENERAL_ARG('R', "rpath", N_("Add DIR to runtime search path"),
276               N_("-R DIR, -rpath DIR"), ONE_DASH,
277               &General_options::add_to_rpath),
278   GENERAL_NOARG('\0', "eh-frame-hdr", N_("Create exception frame header"),
279                 NULL, TWO_DASHES, &General_options::set_create_eh_frame_hdr),
280   GENERAL_ARG('\0', "rpath-link",
281               N_("Add DIR to link time shared library search path"),
282               N_("--rpath-link DIR"), TWO_DASHES,
283               &General_options::add_to_rpath_link),
284   GENERAL_NOARG('\0', "shared", N_("Generate shared library"),
285                 NULL, ONE_DASH, &General_options::set_shared),
286   GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
287                 NULL, ONE_DASH, &General_options::set_static),
288   GENERAL_ARG('\0', "sysroot", N_("Currently ignored"), NULL, TWO_DASHES,
289               &General_options::ignore),
290   POSDEP_NOARG('\0', "as-needed",
291                N_("Only set DT_NEEDED for dynamic libs if used"),
292                NULL, TWO_DASHES, &Position_dependent_options::set_as_needed),
293   POSDEP_NOARG('\0', "no-as-needed",
294                N_("Always DT_NEEDED for dynamic libs (default)"),
295                NULL, TWO_DASHES, &Position_dependent_options::clear_as_needed),
296   POSDEP_NOARG('\0', "whole-archive",
297                N_("Include all archive contents"),
298                NULL, TWO_DASHES,
299                &Position_dependent_options::set_whole_archive),
300   POSDEP_NOARG('\0', "no-whole-archive",
301                N_("Include only needed archive contents"),
302                NULL, TWO_DASHES,
303                &Position_dependent_options::clear_whole_archive),
304   SPECIAL('\0', "help", N_("Report usage information"), NULL,
305           TWO_DASHES, &help)
306 };
307
308 const int options::Command_line_options::options_size =
309   sizeof (options) / sizeof (options[0]);
310
311 // The default values for the general options.
312
313 General_options::General_options()
314   : export_dynamic_(false),
315     dynamic_linker_(NULL),
316     search_path_(),
317     optimization_level_(0),
318     output_file_name_("a.out"),
319     is_relocatable_(false),
320     create_eh_frame_hdr_(false),
321     rpath_(),
322     rpath_link_(),
323     is_shared_(false),
324     is_static_(false)
325 {
326 }
327
328 // The default values for the position dependent options.
329
330 Position_dependent_options::Position_dependent_options()
331   : do_static_search_(false),
332     as_needed_(false),
333     include_whole_archive_(false)
334 {
335 }
336
337 // Input_arguments methods.
338
339 // Add a file to the list.
340
341 void
342 Input_arguments::add_file(const Input_file_argument& file)
343 {
344   if (!this->in_group_)
345     this->input_argument_list_.push_back(Input_argument(file));
346   else
347     {
348       gold_assert(!this->input_argument_list_.empty());
349       gold_assert(this->input_argument_list_.back().is_group());
350       this->input_argument_list_.back().group()->add_file(file);
351     }
352 }
353
354 // Start a group.
355
356 void
357 Input_arguments::start_group()
358 {
359   gold_assert(!this->in_group_);
360   Input_file_group* group = new Input_file_group();
361   this->input_argument_list_.push_back(Input_argument(group));
362   this->in_group_ = true;
363 }
364
365 // End a group.
366
367 void
368 Input_arguments::end_group()
369 {
370   gold_assert(this->in_group_);
371   this->in_group_ = false;
372 }
373
374 // Command_line options.
375
376 Command_line::Command_line()
377   : options_(), position_options_(), inputs_()
378 {
379 }
380
381 // Process the command line options.
382
383 void
384 Command_line::process(int argc, char** argv)
385 {
386   const int options_size = options::Command_line_options::options_size;
387   const options::One_option* options =
388     options::Command_line_options::options;
389   bool no_more_options = false;
390   int i = 0;
391   while (i < argc)
392     {
393       if (argv[i][0] != '-' || no_more_options)
394         {
395           this->add_file(argv[i], false);
396           ++i;
397           continue;
398         }
399
400       // Option starting with '-'.
401       int dashes = 1;
402       if (argv[i][1] == '-')
403         {
404           dashes = 2;
405           if (argv[i][2] == '\0')
406             {
407               no_more_options = true;
408               continue;
409             }
410         }
411
412       // Look for a long option match.
413       char* opt = argv[i] + dashes;
414       char first = opt[0];
415       int skiparg = 0;
416       char* arg = strchr(opt, '=');
417       if (arg != NULL)
418         *arg = '\0';
419       else if (i + 1 < argc)
420         {
421           arg = argv[i + 1];
422           skiparg = 1;
423         }
424
425       int j;
426       for (j = 0; j < options_size; ++j)
427         {
428           if (options[j].long_option != NULL
429               && (dashes == 2
430                   || (options[j].dash
431                       != options::One_option::EXACTLY_TWO_DASHES))
432               && first == options[j].long_option[0]
433               && strcmp(opt, options[j].long_option) == 0)
434             {
435               if (options[j].special)
436                 i += options[j].special(argc - 1, argv + i, opt, this);
437               else
438                 {
439                   if (!options[j].takes_argument())
440                     {
441                       arg = NULL;
442                       skiparg = 0;
443                     }
444                   else
445                     {
446                       if (arg == NULL)
447                         this->usage(_("missing argument"), argv[i]);
448                     }
449                   this->apply_option(options[j], arg);
450                   i += skiparg + 1;
451                 }
452               break;
453             }
454         }
455       if (j < options_size)
456         continue;
457
458       // If we saw two dashes, we need to see a long option.
459       if (dashes == 2)
460         this->usage(_("unknown option"), argv[i]);
461
462       // Look for a short option match.  There may be more than one
463       // short option in a given argument.
464       bool done = false;
465       char* s = argv[i] + 1;
466       ++i;
467       while (*s != '\0' && !done)
468         {
469           char opt = *s;
470           int j;
471           for (j = 0; j < options_size; ++j)
472             {
473               if (options[j].short_option == opt)
474                 {
475                   if (options[j].special)
476                     {
477                       // Undo the argument skip done above.
478                       --i;
479                       i += options[j].special(argc - i, argv + i, s, this);
480                       done = true;
481                     }
482                   else
483                     {
484                       arg = NULL;
485                       if (options[j].takes_argument())
486                         {
487                           if (s[1] != '\0')
488                             {
489                               arg = s + 1;
490                               done = true;
491                             }
492                           else if (i < argc)
493                             {
494                               arg = argv[i];
495                               ++i;
496                             }
497                           else
498                             this->usage(_("missing argument"), opt);
499                         }
500                       this->apply_option(options[j], arg);
501                     }
502                   break;
503                 }
504             }
505
506           if (j >= options_size)
507             this->usage(_("unknown option"), *s);
508
509           ++s;
510         }
511     }
512
513   if (this->inputs_.in_group())
514     {
515       fprintf(stderr, _("%s: missing group end"), program_name);
516       this->usage();
517     }
518
519   // FIXME: We should only do this when configured in native mode.
520   this->options_.add_to_search_path("/lib");
521   this->options_.add_to_search_path("/usr/lib");
522 }
523
524 // Apply a command line option.
525
526 void
527 Command_line::apply_option(const options::One_option& opt,
528                            const char* arg)
529 {
530   if (arg == NULL)
531     {
532       if (opt.general_noarg)
533         (this->options_.*(opt.general_noarg))();
534       else if (opt.dependent_noarg)
535         (this->position_options_.*(opt.dependent_noarg))();
536       else
537         gold_unreachable();
538     }
539   else
540     {
541       if (opt.general_arg)
542         (this->options_.*(opt.general_arg))(arg);
543       else if (opt.dependent_arg)
544         (this->position_options_.*(opt.dependent_arg))(arg);
545       else
546         gold_unreachable();
547     }
548 }
549
550 // Add an input file or library.
551
552 void
553 Command_line::add_file(const char* name, bool is_lib)
554 {
555   Input_file_argument file(name, is_lib, "", this->position_options_);
556   this->inputs_.add_file(file);
557 }
558
559 // Handle the -l option, which requires special treatment.
560
561 int
562 Command_line::process_l_option(int argc, char** argv, char* arg)
563 {
564   int ret;
565   const char* libname;
566   if (arg[1] != '\0')
567     {
568       ret = 1;
569       libname = arg + 1;
570     }
571   else if (argc > 1)
572     {
573       ret = 2;
574       libname = argv[argc + 1];
575     }
576   else
577     this->usage(_("missing argument"), arg);
578
579   this->add_file(libname, true);
580
581   return ret;
582 }
583
584 // Handle the --start-group option.
585
586 void
587 Command_line::start_group(const char* arg)
588 {
589   if (this->inputs_.in_group())
590     this->usage(_("may not nest groups"), arg);
591   this->inputs_.start_group();
592 }
593
594 // Handle the --end-group option.
595
596 void
597 Command_line::end_group(const char* arg)
598 {
599   if (!this->inputs_.in_group())
600     this->usage(_("group end without group start"), arg);
601   this->inputs_.end_group();
602 }
603
604 // Report a usage error.  */
605
606 void
607 Command_line::usage()
608 {
609   fprintf(stderr,
610           _("%s: use the --help option for usage information\n"),
611           program_name);
612   gold_exit(false);
613 }
614
615 void
616 Command_line::usage(const char* msg, const char *opt)
617 {
618   fprintf(stderr,
619           _("%s: %s: %s\n"),
620           program_name, opt, msg);
621   this->usage();
622 }
623
624 void
625 Command_line::usage(const char* msg, char opt)
626 {
627   fprintf(stderr,
628           _("%s: -%c: %s\n"),
629           program_name, opt, msg);
630   this->usage();
631 }
632
633 } // End namespace gold.