Branch data Line data Source code
1 : : /* gm2spec.cc specific flags and argument handling within GNU Modula-2.
2 : :
3 : : Copyright (C) 2007-2025 Free Software Foundation, Inc.
4 : : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5 : :
6 : : This file is part of GNU Modula-2.
7 : :
8 : : GNU Modula-2 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, or (at your option)
11 : : any later version.
12 : :
13 : : GNU Modula-2 is distributed in the hope that it will be useful, but
14 : : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with GNU Modula-2; see the file COPYING3. If not see
20 : : <http://www.gnu.org/licenses/>. */
21 : :
22 : : #include "config.h"
23 : : #define INCLUDE_STRING
24 : : #define INCLUDE_VECTOR
25 : : #include "system.h"
26 : : #include "coretypes.h"
27 : : #include "tm.h"
28 : : #include "xregex.h"
29 : : #include "obstack.h"
30 : : #include "intl.h"
31 : : #include "prefix.h"
32 : : #include "opt-suggestions.h"
33 : : #include "gcc.h"
34 : : #include "opts.h"
35 : : #include "vec.h"
36 : :
37 : : #include "m2/gm2config.h"
38 : :
39 : : #ifdef HAVE_DIRENT_H
40 : : #include <dirent.h>
41 : : #else
42 : : #ifdef HAVE_SYS_NDIR_H
43 : : #include <sys/ndir.h>
44 : : #endif
45 : : #ifdef HAVE_SYS_DIR_H
46 : : #include <sys/dir.h>
47 : : #endif
48 : : #ifdef HAVE_NDIR_H
49 : : #include <ndir.h>
50 : : #endif
51 : : #endif
52 : :
53 : : /* This bit is set if the arguments is a M2 source file. */
54 : : #define M2SOURCE (1<<1)
55 : : /* This bit is set if we saw a `-xfoo' language specification. */
56 : : #define LANGSPEC (1<<2)
57 : : /* This bit is set if they did `-lm' or `-lmath'. */
58 : : #define MATHLIB (1<<3)
59 : : /* This bit is set if they did `-lc'. */
60 : : #define WITHLIBC (1<<4)
61 : : /* Skip this option. */
62 : : #define SKIPOPT (1<<5)
63 : :
64 : : #ifndef MATH_LIBRARY
65 : : #define MATH_LIBRARY "m"
66 : : #endif
67 : : #ifndef MATH_LIBRARY_PROFILE
68 : : #define MATH_LIBRARY_PROFILE MATH_LIBRARY
69 : : #endif
70 : :
71 : : #ifndef LIBSTDCXX
72 : : #define LIBSTDCXX "stdc++"
73 : : #endif
74 : : #ifndef LIBSTDCXX_PROFILE
75 : : #define LIBSTDCXX_PROFILE LIBSTDCXX
76 : : #endif
77 : : #ifndef LIBSTDCXX_STATIC
78 : : #define LIBSTDCXX_STATIC NULL
79 : : #endif
80 : :
81 : : #ifndef LIBCXX
82 : : #define LIBCXX "c++"
83 : : #endif
84 : : #ifndef LIBCXX_PROFILE
85 : : #define LIBCXX_PROFILE LIBCXX
86 : : #endif
87 : : #ifndef LIBCXX_STATIC
88 : : #define LIBCXX_STATIC NULL
89 : : #endif
90 : :
91 : : #ifndef LIBCXXABI
92 : : #define LIBCXXABI "c++abi"
93 : : #endif
94 : : #ifndef LIBCXXABI_PROFILE
95 : : #define LIBCXXABI_PROFILE LIBCXXABI
96 : : #endif
97 : : #ifndef LIBCXXABI_STATIC
98 : : #define LIBCXXABI_STATIC NULL
99 : : #endif
100 : :
101 : : /* The values used here must match those of the stdlib_kind enumeration
102 : : in c.opt. */
103 : : enum stdcxxlib_kind
104 : : {
105 : : USE_LIBSTDCXX = 1,
106 : : USE_LIBCXX = 2
107 : : };
108 : :
109 : : #define DEFAULT_DIALECT "pim"
110 : :
111 : : #undef DEBUG_ARG
112 : :
113 : : typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs;
114 : :
115 : : /* These are the library names which are installed as part of gm2 and reflect
116 : : -flibs=name. The -flibs= option provides the user with a short cut to add
117 : : libraries without having to know the include and link path. */
118 : :
119 : : static const char *library_name[maxlib]
120 : : = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
121 : :
122 : : /* They match the installed archive name for example libm2iso.a,
123 : : libm2pim.a, libm2min.a, libm2log.a and libm2cor.a. They also match a
124 : : subdirectory name where the definition modules are kept. The driver
125 : : checks the argument to -flibs= for an entry in library_name or
126 : : alternatively the existance of the subdirectory (to allow for third
127 : : party libraries to coexist). */
128 : :
129 : : static const char *library_abbrev[maxlib]
130 : : = { "iso", "pim", "min", "log", "cor" };
131 : :
132 : : /* Users may specifiy -flibs=pim,iso etc which are mapped onto
133 : : -flibs=m2pim,m2iso respectively. This provides a match between
134 : : the dialect of Modula-2 and the library set. */
135 : :
136 : : static bool seen_scaffold_static = false;
137 : : static bool seen_scaffold_dynamic = false;
138 : : static bool seen_scaffold_main = false;
139 : : static bool scaffold_static = false;
140 : : static bool scaffold_dynamic = true; // Default uses -fscaffold-dynamic.
141 : : static bool scaffold_main = false;
142 : : static bool seen_gen_module_list = false;
143 : : static bool seen_uselist = false;
144 : : static bool uselist = false;
145 : : static bool gen_module_list = true; // Default uses -fgen-module-list=-.
146 : : static const char *gen_module_filename = "-";
147 : : /* The original argument list and related info is copied here. */
148 : : static unsigned int gm2_xargc;
149 : : static const struct cl_decoded_option *gm2_x_decoded_options;
150 : : static void append_arg (const struct cl_decoded_option *);
151 : :
152 : : /* The new argument list will be built here. */
153 : : static unsigned int gm2_newargc;
154 : : static struct cl_decoded_option *gm2_new_decoded_options;
155 : : static const char *libraries = NULL; /* Abbreviated libraries. */
156 : : static const char *m2_path_name = "";
157 : :
158 : 364263 : typedef struct named_path_s {
159 : : std::vector<const char*>path;
160 : : const char *name;
161 : : } named_path;
162 : :
163 : : static std::vector<named_path>Ipaths;
164 : :
165 : :
166 : : static void
167 : 123368 : push_back_Ipath (const char *arg)
168 : : {
169 : 123368 : if (Ipaths.empty ())
170 : : {
171 : 19629 : named_path np;
172 : 19629 : np.path.push_back (arg);
173 : 19629 : np.name = m2_path_name;
174 : 19629 : Ipaths.push_back (np);
175 : 19629 : }
176 : : else
177 : : {
178 : 103739 : if (strcmp (Ipaths.back ().name,
179 : : m2_path_name) == 0)
180 : 36140 : Ipaths.back ().path.push_back (arg);
181 : : else
182 : : {
183 : 67599 : named_path np;
184 : 67599 : np.path.push_back (arg);
185 : 67599 : np.name = m2_path_name;
186 : 67599 : Ipaths.push_back (np);
187 : 67599 : }
188 : : }
189 : 123368 : }
190 : :
191 : : /* Return whether strings S1 and S2 are both NULL or both the same
192 : : string. */
193 : :
194 : : static bool
195 : 513330 : strings_same (const char *s1, const char *s2)
196 : : {
197 : 513330 : return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
198 : : }
199 : :
200 : : bool
201 : 102777 : options_same (const struct cl_decoded_option *opt1,
202 : : const struct cl_decoded_option *opt2)
203 : : {
204 : 102777 : return (opt1->opt_index == opt2->opt_index
205 : 85555 : && strings_same (opt1->arg, opt2->arg)
206 : 85555 : && strings_same (opt1->orig_option_with_args_text,
207 : 85555 : opt2->orig_option_with_args_text)
208 : 85555 : && strings_same (opt1->canonical_option[0],
209 : 85555 : opt2->canonical_option[0])
210 : 85555 : && strings_same (opt1->canonical_option[1],
211 : 85555 : opt2->canonical_option[1])
212 : 85555 : && strings_same (opt1->canonical_option[2],
213 : 85555 : opt2->canonical_option[2])
214 : 85555 : && strings_same (opt1->canonical_option[3],
215 : 85555 : opt2->canonical_option[3])
216 : 85555 : && (opt1->canonical_option_num_elements
217 : 85555 : == opt2->canonical_option_num_elements)
218 : 85555 : && opt1->value == opt2->value
219 : 188332 : && opt1->errors == opt2->errors);
220 : : }
221 : :
222 : : /* Append another argument to the list being built. */
223 : :
224 : : static void
225 : 641228 : append_arg (const struct cl_decoded_option *arg)
226 : : {
227 : 641228 : static unsigned int newargsize;
228 : :
229 : 641228 : if (gm2_new_decoded_options == gm2_x_decoded_options
230 : 105184 : && gm2_newargc < gm2_xargc
231 : 744005 : && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
232 : : {
233 : 85555 : ++gm2_newargc;
234 : 85555 : return; /* Nothing new here. */
235 : : }
236 : :
237 : 555673 : if (gm2_new_decoded_options == gm2_x_decoded_options)
238 : : { /* Make new arglist. */
239 : 19629 : unsigned int i;
240 : :
241 : 19629 : newargsize = (gm2_xargc << 2) + 20; /* This should handle all. */
242 : 19629 : gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
243 : :
244 : : /* Copy what has been done so far. */
245 : 105184 : for (i = 0; i < gm2_newargc; ++i)
246 : 85555 : gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
247 : : }
248 : :
249 : 555673 : if (gm2_newargc == newargsize)
250 : 0 : fatal_error (input_location, "overflowed output argument list for %qs",
251 : 0 : arg->orig_option_with_args_text);
252 : :
253 : 555673 : gm2_new_decoded_options[gm2_newargc++] = *arg;
254 : : }
255 : :
256 : : /* Append an option described by OPT_INDEX, ARG and VALUE to the list
257 : : being built. */
258 : :
259 : : static void
260 : 337994 : append_option (size_t opt_index, const char *arg, int value)
261 : : {
262 : 337994 : struct cl_decoded_option decoded;
263 : :
264 : 337994 : generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
265 : 337994 : append_arg (&decoded);
266 : 337994 : }
267 : :
268 : : /* safe_strdup safely duplicates a string. */
269 : :
270 : : static char *
271 : 220172 : safe_strdup (const char *s)
272 : : {
273 : 0 : if (s != NULL)
274 : 123368 : return xstrdup (s);
275 : : return NULL;
276 : : }
277 : :
278 : : /* add_default_libs adds the -l option which is derived from the
279 : : libraries. */
280 : :
281 : : static int
282 : 2394 : add_default_libs (const char *libraries)
283 : : {
284 : 2394 : const char *l = libraries;
285 : 2394 : const char *e;
286 : 2394 : char *libname;
287 : 2394 : unsigned int libcount = 0;
288 : :
289 : 9576 : while ((l != NULL) && (l[0] != (char)0))
290 : : {
291 : 9576 : e = index (l, ',');
292 : 9576 : if (e == NULL)
293 : : {
294 : 2394 : libname = xstrdup (l);
295 : 2394 : l = NULL;
296 : 2394 : append_option (OPT_l, safe_strdup (libname), 1);
297 : 2394 : libcount++;
298 : 2394 : free (libname);
299 : : }
300 : : else
301 : : {
302 : 7182 : libname = xstrndup (l, e - l);
303 : 7182 : l = e + 1;
304 : 7182 : append_option (OPT_l, safe_strdup (libname), 1);
305 : 7182 : libcount++;
306 : 7182 : free (libname);
307 : : }
308 : : }
309 : 2394 : return libcount;
310 : : }
311 : :
312 : : /* add_word returns a new string which has the contents of lib
313 : : appended to list. If list is NULL then lib is duplicated and
314 : : returned otherwise the list is appended by "," and the contents of
315 : : lib. */
316 : :
317 : : static const char *
318 : 12068 : add_word (const char *list, const char *lib)
319 : : {
320 : 12068 : char *copy;
321 : 12068 : if (list == NULL)
322 : 3017 : return xstrdup (lib);
323 : 9051 : copy = (char *) xmalloc (strlen (list) + strlen (lib) + 1 + 1);
324 : 9051 : strcpy (copy, list);
325 : 9051 : strcat (copy, ",");
326 : 9051 : strcat (copy, lib);
327 : 9051 : return copy;
328 : : }
329 : :
330 : : /* convert_abbreviation checks abbreviation against known library
331 : : abbreviations. If an abbreviation is found it converts the element
332 : : to the full library name, otherwise the user supplied name is added
333 : : to the full_libraries list. A new string is returned. */
334 : :
335 : : static const char *
336 : 12068 : convert_abbreviation (const char *full_libraries, const char *abbreviation)
337 : : {
338 : 72408 : for (int i = 0; i < maxlib; i++)
339 : 60340 : if (strcmp (abbreviation, library_abbrev[i]) == 0)
340 : 0 : return add_word (full_libraries, library_name[i]);
341 : : /* Perhaps the user typed in the whole lib name rather than an abbrev. */
342 : 36204 : for (int i = 0; i < maxlib; i++)
343 : 36204 : if (strcmp (abbreviation, library_name[i]) == 0)
344 : 12068 : return add_word (full_libraries, abbreviation);
345 : : /* Not found, probably a user typo. */
346 : 0 : error ("%qs is not a valid Modula-2 system library name or abbreviation",
347 : : abbreviation);
348 : 0 : return full_libraries;
349 : : }
350 : :
351 : : /* convert_abbreviations checks each element in the library list to
352 : : see if an a known library abbreviation was used. If found it
353 : : converts the element to the full library name, otherwise the
354 : : element is copied into the list. A new string is returned. */
355 : :
356 : : static const char *
357 : 3017 : convert_abbreviations (const char *libraries)
358 : : {
359 : 3017 : const char *start = libraries;
360 : 3017 : const char *end;
361 : 3017 : const char *full_libraries = NULL;
362 : :
363 : 12068 : do
364 : : {
365 : 12068 : end = index (start, ',');
366 : 12068 : if (end == NULL)
367 : : {
368 : 3017 : full_libraries = convert_abbreviation (full_libraries, start);
369 : 3017 : start = NULL;
370 : : }
371 : : else
372 : : {
373 : 9051 : full_libraries = convert_abbreviation (full_libraries,
374 : 9051 : xstrndup (start, end - start));
375 : 9051 : start = end + 1;
376 : : }
377 : : }
378 : 12068 : while ((start != NULL) && (start[0] != (char)0));
379 : 3017 : return full_libraries;
380 : : }
381 : :
382 : : /* add_m2_I_path appends -fm2-pathname and -fm2-pathnameI options to
383 : : the command line which are contructed in the saved Ipaths. */
384 : :
385 : : static void
386 : 19629 : add_m2_I_path (void)
387 : : {
388 : 106857 : for (auto np : Ipaths)
389 : : {
390 : 87228 : if (strcmp (np.name, "") == 0)
391 : 2429 : append_option (OPT_fm2_pathname_, safe_strdup ("-"), 1);
392 : : else
393 : 84799 : append_option (OPT_fm2_pathname_, safe_strdup (np.name), 1);
394 : 210596 : for (auto *s : np.path)
395 : 246736 : append_option (OPT_fm2_pathnameI, safe_strdup (s), 1);
396 : 87228 : }
397 : 19629 : Ipaths.clear();
398 : 19629 : }
399 : :
400 : :
401 : : void
402 : 19629 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
403 : : unsigned int *in_decoded_options_count,
404 : : int *in_added_libraries)
405 : : {
406 : 19629 : unsigned int argc = *in_decoded_options_count;
407 : 19629 : struct cl_decoded_option *decoded_options = *in_decoded_options;
408 : 19629 : unsigned int i;
409 : :
410 : : /* True if we saw a `-xfoo' language specification on the command
411 : : line. This function will add a -xmodula-2 if the user has not
412 : : already placed one onto the command line. */
413 : 19629 : bool seen_x_flag = false;
414 : 19629 : const char *language = NULL;
415 : :
416 : : /* If nonzero, the user gave us the `-p' or `-pg' flag. */
417 : 19629 : int saw_profile_flag = 0;
418 : :
419 : : /* What action to take for the c++ runtime library:
420 : : -1 means we should not link it in.
421 : : 0 means we should link it if it is needed.
422 : : 1 means it is needed and should be linked in.
423 : : 2 means it is needed but should be linked statically. */
424 : 19629 : int library = 0;
425 : :
426 : : /* Which c++ runtime library to link. */
427 : 19629 : stdcxxlib_kind which_library = USE_LIBSTDCXX;
428 : :
429 : 19629 : const char *dialect = DEFAULT_DIALECT;
430 : :
431 : : /* An array used to flag each argument that needs a bit set for
432 : : LANGSPEC, MATHLIB, or WITHLIBC. */
433 : 19629 : int *args;
434 : :
435 : : /* Have we seen -fmod=? */
436 : 19629 : char *module_extension = NULL;
437 : :
438 : : /* Should the driver perform a link? */
439 : 19629 : bool linking = true;
440 : :
441 : : /* Should the driver link the shared gm2 libs? */
442 : 19629 : bool shared_libgm2 = true;
443 : :
444 : : /* "-lm" or "-lmath" if it appears on the command line. */
445 : 19629 : const struct cl_decoded_option *saw_math = NULL;
446 : :
447 : : /* "-lc" if it appears on the command line. */
448 : 19629 : const struct cl_decoded_option *saw_libc = NULL;
449 : :
450 : : /* By default, we throw on the math library if we have one. */
451 : 19629 : int need_math = (MATH_LIBRARY[0] != '\0');
452 : :
453 : : /* 1 if we should add -lpthread to the command-line.
454 : : FIXME: the default should be a configuration choice. */
455 : 19629 : int need_pthread = 1;
456 : :
457 : : /* True if we saw -static. */
458 : 19629 : int static_link = 0;
459 : :
460 : : /* True if we should add -shared-libgcc to the command-line. */
461 : 19629 : int shared_libgcc = 1;
462 : :
463 : : /* Have we seen the -v flag? */
464 : 19629 : bool verbose = false;
465 : :
466 : : /* Have we seen the -fm2-pathname flag? */
467 : 19629 : bool seen_pathname = false;
468 : :
469 : : /* The number of libraries added in. */
470 : 19629 : int added_libraries;
471 : :
472 : : /* True if we should add -fplugin=m2rte to the command-line. */
473 : 19629 : bool need_plugin = false;
474 : :
475 : : /* True if we should set up include paths and library paths. */
476 : 19629 : bool allow_libraries = true;
477 : :
478 : : #if defined(DEBUG_ARG)
479 : : printf ("argc = %d\n", argc);
480 : : fprintf (stderr, "Incoming:");
481 : : for (i = 0; i < argc; i++)
482 : : fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
483 : : fprintf (stderr, "\n");
484 : : #endif
485 : :
486 : : // add_spec_function ("m2I", add_m2_I_path);
487 : 19629 : gm2_xargc = argc;
488 : 19629 : gm2_x_decoded_options = decoded_options;
489 : 19629 : gm2_newargc = 0;
490 : 19629 : gm2_new_decoded_options = decoded_options;
491 : 19629 : added_libraries = *in_added_libraries;
492 : 19629 : args = XCNEWVEC (int, argc);
493 : :
494 : : /* First pass through arglist.
495 : :
496 : : If -nostdlib or a "turn-off-linking" option is anywhere in the
497 : : command line, don't do any library-option processing (except
498 : : relating to -x). */
499 : :
500 : 547292 : for (i = 1; i < argc; i++)
501 : : {
502 : 527663 : const char *arg = decoded_options[i].arg;
503 : 527663 : args[i] = 0;
504 : : #if defined(DEBUG_ARG)
505 : : printf ("1st pass: %s\n",
506 : : decoded_options[i].orig_option_with_args_text);
507 : : #endif
508 : 527663 : switch (decoded_options[i].opt_index)
509 : : {
510 : : case OPT_fiso:
511 : 527663 : dialect = "iso";
512 : : break;
513 : 170 : case OPT_fpim2:
514 : 170 : dialect = "pim2";
515 : 170 : break;
516 : 33 : case OPT_fpim3:
517 : 33 : dialect = "pim3";
518 : 33 : break;
519 : 158 : case OPT_fpim4:
520 : 158 : dialect = "pim4";
521 : 158 : break;
522 : 11882 : case OPT_fpim:
523 : 11882 : dialect = "pim";
524 : 11882 : break;
525 : 19181 : case OPT_flibs_:
526 : 19181 : libraries = xstrdup (arg);
527 : 19181 : allow_libraries = decoded_options[i].value;
528 : 19181 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
529 : 19181 : break;
530 : 6 : case OPT_fmod_:
531 : 6 : module_extension = xstrdup (arg);
532 : : #if defined(DEBUG_ARG)
533 : : printf ("seen -fmod=%s\n", module_extension);
534 : : #endif
535 : 6 : break;
536 : 0 : case OPT_fpthread:
537 : 0 : need_pthread = decoded_options[i].value;
538 : 0 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
539 : 0 : break;
540 : 515 : case OPT_fm2_plugin:
541 : 515 : need_plugin = decoded_options[i].value;
542 : : #ifndef ENABLE_PLUGIN
543 : : if (need_plugin)
544 : : error ("plugin support is disabled; configure with "
545 : : "%<--enable-plugin%>");
546 : : #endif
547 : 515 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
548 : 515 : break;
549 : 65 : case OPT_fscaffold_dynamic:
550 : 65 : seen_scaffold_dynamic = true;
551 : 65 : scaffold_dynamic = decoded_options[i].value;
552 : 65 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
553 : 65 : break;
554 : 22 : case OPT_fscaffold_static:
555 : 22 : seen_scaffold_static = true;
556 : 22 : scaffold_static = decoded_options[i].value;
557 : 22 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
558 : 22 : break;
559 : 90 : case OPT_fscaffold_main:
560 : 90 : seen_scaffold_main = true;
561 : 90 : scaffold_main = decoded_options[i].value;
562 : 90 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
563 : 90 : break;
564 : 0 : case OPT_fgen_module_list_:
565 : 0 : seen_gen_module_list = true;
566 : 0 : gen_module_list = decoded_options[i].value;
567 : 0 : if (gen_module_list)
568 : 0 : gen_module_filename = decoded_options[i].arg;
569 : : break;
570 : 0 : case OPT_fuse_list_:
571 : 0 : seen_uselist = true;
572 : 0 : uselist = decoded_options[i].value;
573 : 0 : break;
574 : 103246 : case OPT_fm2_pathname_:
575 : 103246 : seen_pathname = true;
576 : 103246 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
577 : 103246 : m2_path_name = decoded_options[i].arg;
578 : 103246 : break;
579 : 0 : case OPT__help:
580 : 0 : case OPT__help_:
581 : : /* Let gcc.cc handle this, as it has a really
582 : : cool facility for handling --help and --verbose --help. */
583 : 0 : *in_added_libraries = 0;
584 : 0 : return;
585 : 120939 : case OPT_I:
586 : 120939 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
587 : 120939 : push_back_Ipath (decoded_options[i].arg);
588 : 120939 : break;
589 : 0 : case OPT_nostdlib:
590 : 0 : case OPT_nostdlib__:
591 : 0 : case OPT_nodefaultlibs:
592 : 0 : library = -1;
593 : 0 : break;
594 : :
595 : 2570 : case OPT_l:
596 : 2570 : if (strcmp (arg, MATH_LIBRARY) == 0)
597 : : {
598 : 2570 : args[i] |= MATHLIB;
599 : 2570 : need_math = 0;
600 : : }
601 : 0 : else if (strcmp (arg, "c") == 0)
602 : 0 : args[i] |= WITHLIBC;
603 : : else
604 : : /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
605 : 0 : library = (library == 0) ? 1 : library;
606 : : break;
607 : :
608 : 0 : case OPT_pg:
609 : 0 : case OPT_p:
610 : 0 : saw_profile_flag++;
611 : 0 : break;
612 : :
613 : 0 : case OPT_x:
614 : 0 : seen_x_flag = true;
615 : 0 : language = arg;
616 : 0 : break;
617 : :
618 : 0 : case OPT_v:
619 : 0 : verbose = true;
620 : 0 : break;
621 : :
622 : 0 : case OPT_Xlinker:
623 : 0 : case OPT_Wl_:
624 : : /* Arguments that go directly to the linker might be .o files,
625 : : or something, and so might cause libstdc++ to be needed. */
626 : 0 : if (library == 0)
627 : 527663 : library = 1;
628 : : break;
629 : :
630 : 12314 : case OPT_c:
631 : 12314 : case OPT_r:
632 : 12314 : case OPT_S:
633 : 12314 : case OPT_E:
634 : 12314 : case OPT_M:
635 : 12314 : case OPT_MM:
636 : 12314 : case OPT_fsyntax_only:
637 : : /* Don't specify libraries if we won't link, since that would
638 : : cause a warning. */
639 : 12314 : linking = false;
640 : 12314 : library = -1;
641 : 12314 : break;
642 : :
643 : : /* PCH makes no sense here, we do not catch -output-pch on purpose,
644 : : that should flag an error. */
645 : 0 : case OPT_fpch_deps:
646 : 0 : case OPT_fpch_preprocess:
647 : 0 : case OPT_Winvalid_pch:
648 : 0 : args[i] |= SKIPOPT;
649 : 0 : break;
650 : :
651 : 0 : case OPT_static:
652 : 0 : static_link = 1;
653 : 0 : break;
654 : :
655 : 0 : case OPT_static_libgcc:
656 : 0 : shared_libgcc = 0;
657 : 0 : break;
658 : :
659 : 0 : case OPT_static_libstdc__:
660 : 0 : library = library >= 0 ? 2 : library;
661 : : #ifdef HAVE_LD_STATIC_DYNAMIC
662 : : /* Remove -static-libstdc++ from the command only if target supports
663 : : LD_STATIC_DYNAMIC. When not supported, it is left in so that a
664 : : back-end target can use outfile substitution. */
665 : 0 : args[i] |= SKIPOPT;
666 : : #endif
667 : 0 : break;
668 : :
669 : 0 : case OPT_static_libgm2:
670 : 0 : shared_libgm2 = false;
671 : : #ifdef HAVE_LD_STATIC_DYNAMIC
672 : : /* Remove -static-libgm2 from the command only if target supports
673 : : LD_STATIC_DYNAMIC. When not supported, it is left in so that a
674 : : back-end target can use outfile substitution. */
675 : 0 : args[i] |= SKIPOPT;
676 : : #endif
677 : 0 : break;
678 : :
679 : 0 : case OPT_stdlib_:
680 : 0 : which_library = (stdcxxlib_kind) decoded_options[i].value;
681 : 0 : break;
682 : :
683 : 26217 : case OPT_SPECIAL_input_file:
684 : 26217 : {
685 : 26217 : const char *source_file = decoded_options[i].orig_option_with_args_text;
686 : : #if defined(DEBUG_ARG)
687 : : printf ("seen OPT_SPECIAL_input_file: %s\n", source_file);
688 : : #endif
689 : 26217 : if (source_file != NULL)
690 : : {
691 : : /* Record that this is a Modula-2 source file. */
692 : 26217 : const char *suffix = strrchr (source_file, '.');
693 : : #if defined(DEBUG_ARG)
694 : : printf ("ext = %s\n", suffix);
695 : : #endif
696 : 26217 : if ((suffix != NULL)
697 : 26214 : && ((strcmp (suffix, ".mod") == 0)
698 : 11346 : || ((module_extension != NULL)
699 : 6 : && (strcmp (suffix, module_extension) == 0))))
700 : : {
701 : : #if defined(DEBUG_ARG)
702 : : printf ("modula-2 source file detected: %s\n", source_file);
703 : : #endif
704 : 14874 : args[i] |= M2SOURCE;
705 : : }
706 : : }
707 : : }
708 : : break;
709 : :
710 : : default:
711 : : break;
712 : : }
713 : : }
714 : 19629 : if (language != NULL && (strcmp (language, "modula-2") != 0))
715 : : return;
716 : :
717 : 19629 : if (! seen_pathname)
718 : : /* Not seen -fm2-pathname therefore make current working directory
719 : : the first place to look for modules. */
720 : 2429 : push_back_Ipath (".");
721 : :
722 : : /* Override the default when the user specifies it. */
723 : 19629 : if (seen_scaffold_static && scaffold_static && !seen_scaffold_dynamic)
724 : 0 : scaffold_dynamic = false;
725 : :
726 : : /* If both options have been seen and both are true, that means the user
727 : : tried to set both. */
728 : 19629 : if (seen_scaffold_dynamic && scaffold_dynamic
729 : 0 : && seen_scaffold_static && scaffold_static)
730 : 0 : error ("%qs and %qs cannot both be enabled",
731 : : "-fscaffold-dynamic", "-fscaffold-static");
732 : :
733 : 19629 : if (uselist && gen_module_list)
734 : : {
735 : 0 : if (! seen_gen_module_list)
736 : 0 : gen_module_list = false;
737 : 0 : if (uselist && gen_module_list)
738 : 0 : error ("%qs and %qs cannot both be enabled",
739 : : "-fgen-module-list=", "-fuse-list=");
740 : : }
741 : :
742 : :
743 : : /* There's no point adding -shared-libgcc if we don't have a shared
744 : : libgcc. */
745 : : #ifndef ENABLE_SHARED_LIBGCC
746 : : shared_libgcc = 0;
747 : : #endif
748 : :
749 : : /* Second pass through arglist, transforming arguments as appropriate. */
750 : :
751 : 19629 : append_arg (&decoded_options[0]); /* Start with command name, of course. */
752 : 566921 : for (i = 1; i < argc; ++i)
753 : : {
754 : : #if defined(DEBUG_ARG)
755 : : printf ("2nd pass: %s",
756 : : decoded_options[i].orig_option_with_args_text);
757 : : if ((args[i] & SKIPOPT) != 0)
758 : : printf (" skipped");
759 : : if ((args[i] & M2SOURCE) != 0)
760 : : printf (" m2 source");
761 : : printf ("\n");
762 : : #endif
763 : 527663 : if ((args[i] & SKIPOPT) == 0)
764 : : {
765 : 283605 : if ((args[i] & M2SOURCE) == 0)
766 : : {
767 : 268731 : append_arg (&decoded_options[i]);
768 : : /* Make sure -lstdc++ is before the math library, since libstdc++
769 : : itself uses those math routines. */
770 : 268731 : if (!saw_math && (args[i] & MATHLIB) && library > 0)
771 : : saw_math = &decoded_options[i];
772 : :
773 : 268731 : if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
774 : : saw_libc = &decoded_options[i];
775 : : }
776 : : else
777 : : {
778 : 14874 : if ((! seen_x_flag) && module_extension)
779 : : {
780 : : #if defined(DEBUG_ARG)
781 : : printf (" adding: -x modula-2 ");
782 : : #endif
783 : 6 : append_option (OPT_x, "modula-2", 1);
784 : : }
785 : 14874 : append_arg (&decoded_options[i]);
786 : : #if defined(DEBUG_ARG)
787 : : printf (" adding: %s\n",
788 : : decoded_options[i].orig_option_with_args_text);
789 : : #endif
790 : 14874 : if ((! seen_x_flag) && module_extension)
791 : : {
792 : : #if defined(DEBUG_ARG)
793 : : printf (" adding: -x none ");
794 : : #endif
795 : 6 : append_option (OPT_x, "none", 1);
796 : : }
797 : : }
798 : : }
799 : : #if defined(DEBUG_ARG)
800 : : else
801 : : printf ("skipping: %s\n",
802 : : decoded_options[i].orig_option_with_args_text);
803 : : #endif
804 : : }
805 : :
806 : 19629 : add_m2_I_path ();
807 : : /* We now add in extra arguments to facilitate a successful link.
808 : : Note that the libraries are added to the end of the link here
809 : : and also placed earlier into the link by lang-specs.h. Possibly
810 : : this is needed because the m2pim,m2iso libraries are cross linked
811 : : (--fixme-- combine all the m2 libraries into a single archive).
812 : :
813 : : We also add default scaffold linking options. */
814 : :
815 : : /* If we have not seen either uselist or gen_module_list and we need
816 : : to link or compile a module list then we turn on -fgen_module_list=-
817 : : as the default. */
818 : 19629 : if (!seen_uselist && !seen_gen_module_list
819 : 19629 : && (linking || scaffold_main))
820 : 7328 : append_option (OPT_fgen_module_list_, "-", 1);
821 : :
822 : : /* We checked that they were not both enabled above, if there was a set
823 : : value (even iff that is 'off'), pass that to the FE. */
824 : 19629 : if (seen_scaffold_dynamic || scaffold_dynamic)
825 : 19629 : append_option (OPT_fscaffold_dynamic, NULL, scaffold_dynamic);
826 : 19629 : if (seen_scaffold_static)
827 : 22 : append_option (OPT_fscaffold_static, NULL, scaffold_static);
828 : :
829 : : /* If the user has set fscaffold-main specifically, use that. Otherwise, if
830 : : we are linking then set it so that we generate the relevant code for the
831 : : main module. */
832 : 19629 : if (seen_scaffold_main)
833 : 90 : append_option (OPT_fscaffold_main, NULL, scaffold_main);
834 : 19539 : else if (linking)
835 : 7268 : append_option (OPT_fscaffold_main, NULL, true);
836 : :
837 : 19629 : if (allow_libraries)
838 : : {
839 : : /* If the libraries have not been specified by the user, select the
840 : : appropriate libraries for the active dialect. */
841 : 3017 : if (libraries == NULL)
842 : : {
843 : 3017 : if (strcmp (dialect, "iso") == 0)
844 : 306 : libraries = xstrdup ("m2iso,m2cor,m2pim,m2log");
845 : : else
846 : : /* Default to pim libraries otherwise. */
847 : 2711 : libraries = xstrdup ("m2cor,m2log,m2pim,m2iso");
848 : : }
849 : 3017 : libraries = convert_abbreviations (libraries);
850 : 3017 : append_option (OPT_flibs_, xstrdup (libraries), 1);
851 : : }
852 : : else
853 : 16612 : append_option (OPT_flibs_, xstrdup ("-"), 0); /* no system libs. */
854 : :
855 : 19629 : if (need_plugin)
856 : 211 : append_option (OPT_fplugin_, "m2rte", 1);
857 : :
858 : 19629 : if (linking)
859 : : {
860 : 7316 : if (allow_libraries)
861 : : {
862 : : #ifdef HAVE_LD_STATIC_DYNAMIC
863 : 2394 : if (!shared_libgm2)
864 : 0 : append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
865 : : #endif
866 : 2394 : added_libraries += add_default_libs (libraries);
867 : : #ifdef HAVE_LD_STATIC_DYNAMIC
868 : 2394 : if (!shared_libgm2)
869 : 0 : append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
870 : : #endif
871 : : }
872 : :
873 : : /* Add `-lstdc++' if we haven't already done so. */
874 : : #ifdef HAVE_LD_STATIC_DYNAMIC
875 : 7316 : if (library > 1 && !static_link)
876 : 0 : append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
877 : : #endif
878 : 7316 : if (which_library == USE_LIBCXX)
879 : : {
880 : 0 : append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
881 : 0 : added_libraries++;
882 : 0 : if (LIBCXXABI != NULL)
883 : : {
884 : 0 : append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
885 : : : LIBCXXABI, 1);
886 : 0 : added_libraries++;
887 : : }
888 : : }
889 : : else
890 : : {
891 : 7316 : append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
892 : : : LIBSTDCXX, 1);
893 : 7316 : added_libraries++;
894 : : }
895 : : /* Add target-dependent static library, if necessary. */
896 : 7316 : if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
897 : : {
898 : : append_option (OPT_l, LIBSTDCXX_STATIC, 1);
899 : : added_libraries++;
900 : : }
901 : : #ifdef HAVE_LD_STATIC_DYNAMIC
902 : 7316 : if (library > 1 && !static_link)
903 : 0 : append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
904 : : #endif
905 : : }
906 : 19629 : if (need_math)
907 : : {
908 : 17059 : append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
909 : : MATH_LIBRARY, 1);
910 : 17059 : added_libraries++;
911 : : }
912 : 19629 : if (need_pthread)
913 : : {
914 : 19629 : append_option (OPT_l, "pthread", 1);
915 : 19629 : added_libraries++;
916 : : }
917 : 19629 : if (shared_libgcc && !static_link)
918 : 19629 : append_option (OPT_shared_libgcc, NULL, 1);
919 : :
920 : 19629 : if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
921 : : {
922 : 0 : fprintf (stderr, _("Driving:"));
923 : 0 : for (i = 0; i < gm2_newargc; i++)
924 : 0 : fprintf (stderr, " %s",
925 : 0 : gm2_new_decoded_options[i].orig_option_with_args_text);
926 : 0 : fprintf (stderr, "\n");
927 : 0 : fprintf (stderr, "new argc = %d, added_libraries = %d\n",
928 : : gm2_newargc, added_libraries);
929 : : }
930 : :
931 : 19629 : *in_decoded_options_count = gm2_newargc;
932 : 19629 : *in_decoded_options = gm2_new_decoded_options;
933 : 19629 : *in_added_libraries = added_libraries;
934 : : }
935 : :
936 : :
937 : : /* Called before linking. Returns 0 on success and -1 on failure. */
938 : : int
939 : 13249 : lang_specific_pre_link (void) /* Not used for M2. */
940 : : {
941 : 13249 : return 0;
942 : : }
943 : :
944 : : /* Number of extra output files that lang_specific_pre_link may generate. */
945 : : int lang_specific_extra_outfiles = 0;
|