Add -rpath-link option, currently unused.
[external/binutils.git] / gold / options.h
1 // options.h -- handle command line options for gold  -*- C++ -*-
2
3 // Command_line
4 //   Holds everything we get from the command line.
5 // General_options (from Command_line::options())
6 //   Options which are not position dependent.
7 // Input_argument (from Command_line::inputs())
8 //   The list of input files, including -l options.
9 // Position_dependent_options (from Input_argument::options())
10 //   Position dependent options which apply to this argument.
11
12 #ifndef GOLD_OPTIONS_H
13 #define GOLD_OPTIONS_H
14
15 #include <list>
16 #include <string>
17 #include <vector>
18
19 namespace gold
20 {
21
22 class Command_line;
23 class Input_file_group;
24
25 namespace options {
26
27 class Command_line_options;
28 struct One_option;
29
30 } // End namespace gold::options.
31
32 // The position independent options which apply to the whole link.
33 // There are a lot of them.
34
35 class General_options
36 {
37  public:
38   General_options();
39
40   // -E: export dynamic symbols.
41   bool
42   export_dynamic() const
43   { return this->export_dynamic_; }
44
45   // -I: dynamic linker name.
46   const char*
47   dynamic_linker() const
48   { return this->dynamic_linker_; }
49
50   // -L: Library search path.
51   typedef std::vector<const char*> Dir_list;
52
53   const Dir_list&
54   search_path() const
55   { return this->search_path_; }
56
57   // -o: Output file name.
58   const char*
59   output_file_name() const
60   { return this->output_file_name_; }
61
62   // -r: Whether we are doing a relocatable link.
63   bool
64   is_relocatable() const
65   { return this->is_relocatable_; }
66
67   // --eh-frame-hdr: Whether to generate an exception frame header.
68   bool
69   create_eh_frame_hdr() const
70   { return this->create_eh_frame_hdr_; }
71
72   // --rpath: The runtime search path.
73   const Dir_list&
74   rpath() const
75   { return this->rpath_; }
76
77   // --rpath-link: The link time search patch for shared libraries.
78   const Dir_list&
79   rpath_link() const
80   { return this->rpath_link_; }
81
82   // --shared: Whether generating a shared object.
83   bool
84   is_shared() const
85   { return this->is_shared_; }
86
87   // --static: Whether doing a static link.
88   bool
89   is_static() const
90   { return this->is_static_; }
91
92  private:
93   // Don't copy this structure.
94   General_options(const General_options&);
95   General_options& operator=(const General_options&);
96
97   friend class Command_line;
98   friend class options::Command_line_options;
99
100   void
101   set_export_dynamic()
102   { this->export_dynamic_ = true; }
103
104   void
105   set_dynamic_linker(const char* arg)
106   { this->dynamic_linker_ = arg; }
107
108   void
109   add_to_search_path(const char* arg)
110   { this->search_path_.push_back(arg); }
111
112   void
113   set_output_file_name(const char* arg)
114   { this->output_file_name_ = arg; }
115
116   void
117   set_relocatable()
118   { this->is_relocatable_ = true; }
119
120   void
121   create_eh_frame_hdr()
122   { this->create_eh_frame_hdr_ = true; }
123
124   void
125   add_to_rpath(const char* arg)
126   { this->rpath_.push_back(arg); }
127
128   void
129   add_to_rpath_link(const char* arg)
130   { this->rpath_link_.push_back(arg); }
131
132   void
133   set_shared()
134   { this->is_shared_ = true; }
135
136   void
137   set_static()
138   { this->is_static_ = true; }
139
140   void
141   ignore(const char*)
142   { }
143
144   bool export_dynamic_;
145   const char* dynamic_linker_;
146   Dir_list search_path_;
147   const char* output_file_name_;
148   bool is_relocatable_;
149   bool create_eh_frame_hdr_;
150   Dir_list rpath_;
151   Dir_list rpath_link_;
152   bool is_shared_;
153   bool is_static_;
154 };
155
156 // The current state of the position dependent options.
157
158 class Position_dependent_options
159 {
160  public:
161   Position_dependent_options();
162
163   // -Bstatic: Whether we are searching for a static archive rather
164   // than a shared object.
165   bool
166   do_static_search() const
167   { return this->do_static_search_; }
168
169   // --as-needed: Whether to add a DT_NEEDED argument only if the
170   // dynamic object is used.
171   bool
172   as_needed() const
173   { return this->as_needed_; }
174
175   // --whole-archive: Whether to include the entire contents of an
176   // --archive.
177   bool
178   include_whole_archive() const
179   { return this->include_whole_archive_; }
180
181   void
182   set_static_search()
183   { this->do_static_search_ = true; }
184
185   void
186   set_dynamic_search()
187   { this->do_static_search_ = false; }
188
189   void
190   set_as_needed()
191   { this->as_needed_ = true; }
192
193   void
194   clear_as_needed()
195   { this->as_needed_ = false; }
196
197   void
198   set_whole_archive()
199   { this->include_whole_archive_ = true; }
200
201   void
202   clear_whole_archive()
203   { this->include_whole_archive_ = false; }
204
205  private:
206   bool do_static_search_;
207   bool as_needed_;
208   bool include_whole_archive_;
209 };
210
211 // A single file or library argument from the command line.
212
213 class Input_file_argument
214 {
215  public:
216   Input_file_argument()
217     : name_(), is_lib_(false), options_()
218   { }
219
220   Input_file_argument(const char* name, bool is_lib,
221                       const Position_dependent_options& options)
222     : name_(name), is_lib_(is_lib), options_(options)
223   { }
224
225   const char*
226   name() const
227   { return this->name_.c_str(); }
228
229   const Position_dependent_options&
230   options() const
231   { return this->options_; }
232
233   bool
234   is_lib() const
235   { return this->is_lib_; }
236
237  private:
238   // We use std::string, not const char*, here for convenience when
239   // using script files, so that we do not have to preserve the string
240   // in that case.
241   std::string name_;
242   bool is_lib_;
243   Position_dependent_options options_;
244 };
245
246 // A file or library, or a group, from the command line.
247
248 class Input_argument
249 {
250  public:
251   // Create a file or library argument.
252   explicit Input_argument(Input_file_argument file)
253     : is_file_(true), file_(file), group_(NULL)
254   { }
255
256   // Create a group argument.
257   explicit Input_argument(Input_file_group* group)
258     : is_file_(false), group_(group)
259   { }
260
261   // Return whether this is a file.
262   bool
263   is_file() const
264   { return this->is_file_; }
265
266   // Return whether this is a group.
267   bool
268   is_group() const
269   { return !this->is_file_; }
270
271   // Return the information about the file.
272   const Input_file_argument&
273   file() const
274   {
275     gold_assert(this->is_file_);
276     return this->file_;
277   }
278
279   // Return the information about the group.
280   const Input_file_group*
281   group() const
282   {
283     gold_assert(!this->is_file_);
284     return this->group_;
285   }
286
287   Input_file_group*
288   group()
289   {
290     gold_assert(!this->is_file_);
291     return this->group_;
292   }
293
294  private:
295   bool is_file_;
296   Input_file_argument file_;
297   Input_file_group* group_;
298 };
299
300 // A group from the command line.  This is a set of arguments within
301 // --start-group ... --end-group.
302
303 class Input_file_group
304 {
305  public:
306   typedef std::vector<Input_argument> Files;
307   typedef Files::const_iterator const_iterator;
308
309   Input_file_group()
310     : files_()
311   { }
312
313   // Add a file to the end of the group.
314   void
315   add_file(const Input_file_argument& arg)
316   { this->files_.push_back(Input_argument(arg)); }
317
318   // Iterators to iterate over the group contents.
319
320   const_iterator
321   begin() const
322   { return this->files_.begin(); }
323
324   const_iterator
325   end() const
326   { return this->files_.end(); }
327
328  private:
329   Files files_;
330 };
331
332 // A list of files from the command line or a script.
333
334 class Input_arguments
335 {
336  public:
337   typedef std::vector<Input_argument> Input_argument_list;
338   typedef Input_argument_list::const_iterator const_iterator;
339
340   Input_arguments()
341     : input_argument_list_(), in_group_(false)
342   { }
343
344   // Add a file.
345   void
346   add_file(const Input_file_argument& arg);
347
348   // Start a group (the --start-group option).
349   void
350   start_group();
351
352   // End a group (the --end-group option).
353   void
354   end_group();
355
356   // Return whether we are currently in a group.
357   bool
358   in_group() const
359   { return this->in_group_; }
360
361   // Iterators to iterate over the list of input files.
362
363   const_iterator
364   begin() const
365   { return this->input_argument_list_.begin(); }
366
367   const_iterator
368   end() const
369   { return this->input_argument_list_.end(); }
370
371   // Return whether the list is empty.
372   bool
373   empty() const
374   { return this->input_argument_list_.empty(); }
375
376  private:
377   Input_argument_list input_argument_list_;
378   bool in_group_;
379 };
380
381 // All the information read from the command line.
382
383 class Command_line
384 {
385  public:
386   typedef Input_arguments::const_iterator const_iterator;
387
388   Command_line();
389
390   // Process the command line options.  This will exit with an
391   // appropriate error message if an unrecognized option is seen.
392   void
393   process(int argc, char** argv);
394
395   // Handle a -l option.
396   int
397   process_l_option(int, char**, char*);
398
399   // Handle a --start-group option.
400   void
401   start_group(const char* arg);
402
403   // Handle a --end-group option.
404   void
405   end_group(const char* arg);
406
407   // Get the general options.
408   const General_options&
409   options() const
410   { return this->options_; }
411
412   // Iterators to iterate over the list of input files.
413
414   const_iterator
415   begin() const
416   { return this->inputs_.begin(); }
417
418   const_iterator
419   end() const
420   { return this->inputs_.end(); }
421
422  private:
423   Command_line(const Command_line&);
424   Command_line& operator=(const Command_line&);
425
426   // Report usage error.
427   void
428   usage() ATTRIBUTE_NORETURN;
429   void
430   usage(const char* msg, const char* opt) ATTRIBUTE_NORETURN;
431   void
432   usage(const char* msg, char opt) ATTRIBUTE_NORETURN;
433
434   // Apply a command line option.
435   void
436   apply_option(const gold::options::One_option&, const char*);
437
438   // Add a file.
439   void
440   add_file(const char* name, bool is_lib);
441
442   General_options options_;
443   Position_dependent_options position_options_;
444   Input_arguments inputs_;
445 };
446
447 } // End namespace gold.
448
449 #endif // !defined(GOLD_OPTIONS_H)