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