Can now do a full static link of hello, world in C or C++
[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 #include <cassert>
19
20 namespace gold
21 {
22
23 class Command_line;
24 class Input_file_group;
25
26 namespace options {
27
28 class Command_line_options;
29 struct One_option;
30
31 } // End namespace gold::options.
32
33 // The position independent options which apply to the whole link.
34 // There are a lot of them.
35
36 class General_options
37 {
38  public:
39   General_options();
40
41   // -L: Library search path.
42   typedef std::list<const char*> Dir_list;
43
44   const Dir_list&
45   search_path() const
46   { return this->search_path_; }
47
48   // -o: Output file name.
49   const char*
50   output_file_name() const
51   { return this->output_file_name_; }
52
53   // -r: Whether we are doing a relocatable link.
54   bool
55   is_relocatable() const
56   { return this->is_relocatable_; }
57
58   // --shared: Whether generating a shared object.
59   bool
60   is_shared() const
61   { return this->is_shared_; }
62
63   // --static: Whether doing a static link.
64   bool
65   is_static() const
66   { return this->is_static_; }
67
68  private:
69   friend class Command_line;
70   friend class options::Command_line_options;
71
72   void
73   add_to_search_path(const char* arg)
74   { this->search_path_.push_back(arg); }
75
76   void
77   set_output_file_name(const char* arg)
78   { this->output_file_name_ = arg; }
79
80   void
81   set_relocatable()
82   { this->is_relocatable_ = true; }
83
84   void
85   set_shared()
86   { this->is_shared_ = true; }
87
88   void
89   set_static()
90   { this->is_static_ = true; }
91
92   Dir_list search_path_;
93   const char* output_file_name_;
94   bool is_relocatable_;
95   bool is_shared_;
96   bool is_static_;
97
98   // Don't copy this structure.
99   General_options(const General_options&);
100   General_options& operator=(const General_options&);
101 };
102
103 // The current state of the position dependent options.
104
105 class Position_dependent_options
106 {
107  public:
108   Position_dependent_options();
109
110   // -Bstatic: Whether we are searching for a static archive rather
111   // -than a shared object.
112   bool
113   do_static_search()
114   { return this->do_static_search_; }
115
116  private:
117   friend class Command_line;
118   friend class options::Command_line_options;
119
120   void
121   set_static_search()
122   { this->do_static_search_ = true; }
123
124   void
125   set_dynamic_search()
126   { this->do_static_search_ = false; }
127
128   bool do_static_search_;
129 };
130
131 // A single file or library argument from the command line.
132
133 class Input_file_argument
134 {
135  public:
136   Input_file_argument()
137     : name_(NULL), is_lib_(false), options_()
138   { }
139
140   Input_file_argument(const char* name, bool is_lib,
141                       const Position_dependent_options& options)
142     : name_(name), is_lib_(is_lib), options_(options)
143   { }
144
145   const char*
146   name() const
147   { return this->name_; }
148
149   const Position_dependent_options&
150   options() const
151   { return this->options_; }
152
153   bool
154   is_lib() const
155   { return this->is_lib_; }
156
157  private:
158   const char* name_;
159   bool is_lib_;
160   Position_dependent_options options_;
161 };
162
163 // A file or library, or a group, from the command line.
164
165 class Input_argument
166 {
167  public:
168   // Create a file or library argument.
169   explicit Input_argument(Input_file_argument file)
170     : is_file_(true), file_(file), group_(NULL)
171   { }
172
173   // Create a group argument.
174   explicit Input_argument(Input_file_group* group)
175     : is_file_(false), group_(group)
176   { }
177
178   // Return whether this is a file.
179   bool
180   is_file() const
181   { return this->is_file_; }
182
183   // Return whether this is a group.
184   bool
185   is_group() const
186   { return !this->is_file_; }
187
188   // Return the information about the file.
189   const Input_file_argument&
190   file() const
191   {
192     assert(this->is_file_);
193     return this->file_;
194   }
195
196   // Return the information about the group.
197   const Input_file_group*
198   group() const
199   {
200     assert(!this->is_file_);
201     return this->group_;
202   }
203
204   Input_file_group*
205   group()
206   {
207     assert(!this->is_file_);
208     return this->group_;
209   }
210
211  private:
212   bool is_file_;
213   Input_file_argument file_;
214   Input_file_group* group_;
215 };
216
217 // A group from the command line.  This is a set of arguments within
218 // --start-group ... --end-group.
219
220 class Input_file_group
221 {
222  public:
223   typedef std::vector<Input_argument> Files;
224   typedef Files::const_iterator const_iterator;
225
226   Input_file_group()
227     : files_()
228   { }
229
230   // Add a file to the end of the group.
231   void
232   add_file(const Input_file_argument& arg)
233   { this->files_.push_back(Input_argument(arg)); }
234
235   // Iterators to iterate over the group contents.
236
237   const_iterator
238   begin() const
239   { return this->files_.begin(); }
240
241   const_iterator
242   end() const
243   { return this->files_.end(); }
244
245  private:
246   Files files_;
247 };
248
249 // All the information read from the command line.
250
251 class Command_line
252 {
253  public:
254   typedef std::vector<Input_argument> Input_arguments;
255   typedef Input_arguments::const_iterator const_iterator;
256
257   Command_line();
258
259   // Process the command line options.  This will exit with an
260   // appropriate error message if an unrecognized option is seen.
261   void
262   process(int argc, char** argv);
263
264   // Handle a -l option.
265   int
266   process_l_option(int, char**, char*);
267
268   // Handle a --start-group option.
269   void
270   start_group(const char* arg);
271
272   // Handle a --end-group option.
273   void
274   end_group(const char* arg);
275
276   // Get the general options.
277   const General_options&
278   options() const
279   { return this->options_; }
280
281   // Iterators to iterate over the list of input files.
282
283   const_iterator
284   begin() const
285   { return this->inputs_.begin(); }
286
287   const_iterator
288   end() const
289   { return this->inputs_.end(); }
290
291  private:
292   Command_line(const Command_line&);
293   Command_line& operator=(const Command_line&);
294
295   // Report usage error.
296   void
297   usage() ATTRIBUTE_NORETURN;
298   void
299   usage(const char* msg, const char* opt) ATTRIBUTE_NORETURN;
300   void
301   usage(const char* msg, char opt) ATTRIBUTE_NORETURN;
302
303   // Apply a command line option.
304   void
305   apply_option(const gold::options::One_option&, const char*);
306
307   // Add a file.
308   void
309   add_file(const char* name, bool is_lib);
310
311   General_options options_;
312   Position_dependent_options position_options_;
313   Input_arguments inputs_;
314   bool in_group_;
315 };
316
317 } // End namespace gold.
318
319 #endif // !defined(GOLD_OPTIONS_H)