1 /* gm2spec.cc specific flags and argument handling within GNU Modula-2.
3 Copyright (C) 2007-2023 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6 This file is part of GNU Modula-2.
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)
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.
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/>. */
24 #include "coretypes.h"
30 #include "opt-suggestions.h"
35 #include "m2/gm2config.h"
40 #ifdef HAVE_SYS_NDIR_H
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)
61 #define MATH_LIBRARY "m"
63 #ifndef MATH_LIBRARY_PROFILE
64 #define MATH_LIBRARY_PROFILE MATH_LIBRARY
68 #define LIBSTDCXX "stdc++"
70 #ifndef LIBSTDCXX_PROFILE
71 #define LIBSTDCXX_PROFILE LIBSTDCXX
73 #ifndef LIBSTDCXX_STATIC
74 #define LIBSTDCXX_STATIC NULL
80 #ifndef LIBCXX_PROFILE
81 #define LIBCXX_PROFILE LIBCXX
84 #define LIBCXX_STATIC NULL
88 #define LIBCXXABI "c++abi"
90 #ifndef LIBCXXABI_PROFILE
91 #define LIBCXXABI_PROFILE LIBCXXABI
93 #ifndef LIBCXXABI_STATIC
94 #define LIBCXXABI_STATIC NULL
97 /* The values used here must match those of the stdlib_kind enumeration
105 #define DEFAULT_DIALECT "pim"
109 typedef enum { iso
, pim
, min
, logitech
, pimcoroutine
, maxlib
} libs
;
111 /* These are the library names which are installed as part of gm2 and reflect
112 -flibs=name. The -flibs= option provides the user with a short cut to add
113 libraries without having to know the include and link path. */
115 static const char *library_name
[maxlib
]
116 = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
118 /* They match the installed archive name for example libm2iso.a,
119 libm2pim.a, libm2min.a, libm2log.a and libm2cor.a. They also match a
120 subdirectory name where the definition modules are kept. The driver
121 checks the argument to -flibs= for an entry in library_name or
122 alternatively the existance of the subdirectory (to allow for third
123 party libraries to coexist). */
125 static const char *library_abbrev
[maxlib
]
126 = { "iso", "pim", "min", "log", "cor" };
128 /* Users may specifiy -flibs=pim,iso etc which are mapped onto
129 -flibs=m2pim,m2iso respectively. This provides a match between
130 the dialect of Modula-2 and the library set. */
132 static bool seen_scaffold_static
= false;
133 static bool seen_scaffold_dynamic
= false;
134 static bool seen_scaffold_main
= false;
135 static bool scaffold_static
= false;
136 static bool scaffold_dynamic
= true; // Default uses -fscaffold-dynamic.
137 static bool scaffold_main
= false;
138 static bool seen_gen_module_list
= false;
139 static bool seen_uselist
= false;
140 static bool uselist
= false;
141 static bool gen_module_list
= true; // Default uses -fgen-module-list=-.
142 static const char *gen_module_filename
= "-";
143 /* The original argument list and related info is copied here. */
144 static unsigned int gm2_xargc
;
145 static const struct cl_decoded_option
*gm2_x_decoded_options
;
146 static void append_arg (const struct cl_decoded_option
*);
148 /* The new argument list will be built here. */
149 static unsigned int gm2_newargc
;
150 static struct cl_decoded_option
*gm2_new_decoded_options
;
151 static const char *libraries
= NULL
; /* Abbreviated libraries. */
154 /* Return whether strings S1 and S2 are both NULL or both the same
158 strings_same (const char *s1
, const char *s2
)
160 return s1
== s2
|| (s1
!= NULL
&& s2
!= NULL
&& strcmp (s1
, s2
) == 0);
164 options_same (const struct cl_decoded_option
*opt1
,
165 const struct cl_decoded_option
*opt2
)
167 return (opt1
->opt_index
== opt2
->opt_index
168 && strings_same (opt1
->arg
, opt2
->arg
)
169 && strings_same (opt1
->orig_option_with_args_text
,
170 opt2
->orig_option_with_args_text
)
171 && strings_same (opt1
->canonical_option
[0],
172 opt2
->canonical_option
[0])
173 && strings_same (opt1
->canonical_option
[1],
174 opt2
->canonical_option
[1])
175 && strings_same (opt1
->canonical_option
[2],
176 opt2
->canonical_option
[2])
177 && strings_same (opt1
->canonical_option
[3],
178 opt2
->canonical_option
[3])
179 && (opt1
->canonical_option_num_elements
180 == opt2
->canonical_option_num_elements
)
181 && opt1
->value
== opt2
->value
182 && opt1
->errors
== opt2
->errors
);
185 /* Append another argument to the list being built. */
188 append_arg (const struct cl_decoded_option
*arg
)
190 static unsigned int newargsize
;
192 if (gm2_new_decoded_options
== gm2_x_decoded_options
193 && gm2_newargc
< gm2_xargc
194 && options_same (arg
, &gm2_x_decoded_options
[gm2_newargc
]))
197 return; /* Nothing new here. */
200 if (gm2_new_decoded_options
== gm2_x_decoded_options
)
201 { /* Make new arglist. */
204 newargsize
= (gm2_xargc
<< 2) + 20; /* This should handle all. */
205 gm2_new_decoded_options
= XNEWVEC (struct cl_decoded_option
, newargsize
);
207 /* Copy what has been done so far. */
208 for (i
= 0; i
< gm2_newargc
; ++i
)
209 gm2_new_decoded_options
[i
] = gm2_x_decoded_options
[i
];
212 if (gm2_newargc
== newargsize
)
213 fatal_error (input_location
, "overflowed output argument list for %qs",
214 arg
->orig_option_with_args_text
);
216 gm2_new_decoded_options
[gm2_newargc
++] = *arg
;
219 /* Append an option described by OPT_INDEX, ARG and VALUE to the list
223 append_option (size_t opt_index
, const char *arg
, int value
)
225 struct cl_decoded_option decoded
;
227 generate_option (opt_index
, arg
, value
, CL_DRIVER
, &decoded
);
228 append_arg (&decoded
);
231 /* safe_strdup safely duplicates a string. */
234 safe_strdup (const char *s
)
241 /* add_default_libs adds the -l option which is derived from the
245 add_default_libs (const char *libraries
)
247 const char *l
= libraries
;
250 unsigned int libcount
= 0;
252 while ((l
!= NULL
) && (l
[0] != (char)0))
257 libname
= xstrdup (l
);
259 append_option (OPT_l
, safe_strdup (libname
), 1);
265 libname
= xstrndup (l
, e
- l
);
267 append_option (OPT_l
, safe_strdup (libname
), 1);
275 /* add_word returns a new string which has the contents of lib
276 appended to list. If list is NULL then lib is duplicated and
277 returned otherwise the list is appended by "," and the contents of
281 add_word (const char *list
, const char *lib
)
285 return xstrdup (lib
);
286 copy
= (char *) xmalloc (strlen (list
) + strlen (lib
) + 1 + 1);
293 /* convert_abbreviation checks abbreviation against known library
294 abbreviations. If an abbreviation is found it converts the element
295 to the full library name, otherwise the user supplied name is added
296 to the full_libraries list. A new string is returned. */
299 convert_abbreviation (const char *full_libraries
, const char *abbreviation
)
301 for (int i
= 0; i
< maxlib
; i
++)
302 if (strcmp (abbreviation
, library_abbrev
[i
]) == 0)
303 return add_word (full_libraries
, library_name
[i
]);
304 /* Perhaps the user typed in the whole lib name rather than an abbrev. */
305 for (int i
= 0; i
< maxlib
; i
++)
306 if (strcmp (abbreviation
, library_name
[i
]) == 0)
307 return add_word (full_libraries
, abbreviation
);
308 /* Not found, probably a user typo. */
309 error ("%qs is not a valid Modula-2 system library name or abbreviation",
311 return full_libraries
;
314 /* convert_abbreviations checks each element in the library list to
315 see if an a known library abbreviation was used. If found it
316 converts the element to the full library name, otherwise the
317 element is copied into the list. A new string is returned. */
320 convert_abbreviations (const char *libraries
)
322 const char *start
= libraries
;
324 const char *full_libraries
= NULL
;
328 end
= index (start
, ',');
331 full_libraries
= convert_abbreviation (full_libraries
, start
);
336 full_libraries
= convert_abbreviation (full_libraries
,
337 xstrndup (start
, end
- start
));
341 while ((start
!= NULL
) && (start
[0] != (char)0));
342 return full_libraries
;
347 lang_specific_driver (struct cl_decoded_option
**in_decoded_options
,
348 unsigned int *in_decoded_options_count
,
349 int *in_added_libraries
)
351 unsigned int argc
= *in_decoded_options_count
;
352 struct cl_decoded_option
*decoded_options
= *in_decoded_options
;
355 /* True if we saw a `-xfoo' language specification on the command
356 line. This function will add a -xmodula-2 if the user has not
357 already placed one onto the command line. */
358 bool seen_x_flag
= false;
359 const char *language
= NULL
;
361 /* If nonzero, the user gave us the `-p' or `-pg' flag. */
362 int saw_profile_flag
= 0;
364 /* What action to take for the c++ runtime library:
365 -1 means we should not link it in.
366 0 means we should link it if it is needed.
367 1 means it is needed and should be linked in.
368 2 means it is needed but should be linked statically. */
371 /* Which c++ runtime library to link. */
372 stdcxxlib_kind which_library
= USE_LIBSTDCXX
;
374 const char *dialect
= DEFAULT_DIALECT
;
376 /* An array used to flag each argument that needs a bit set for
377 LANGSPEC, MATHLIB, or WITHLIBC. */
380 /* Have we seen -fmod=? */
381 bool seen_module_extension
= false;
383 /* Should the driver perform a link? */
386 /* Should the driver link the shared gm2 libs? */
387 bool shared_libgm2
= true;
389 /* "-lm" or "-lmath" if it appears on the command line. */
390 const struct cl_decoded_option
*saw_math
= NULL
;
392 /* "-lc" if it appears on the command line. */
393 const struct cl_decoded_option
*saw_libc
= NULL
;
395 /* By default, we throw on the math library if we have one. */
396 int need_math
= (MATH_LIBRARY
[0] != '\0');
398 /* 1 if we should add -lpthread to the command-line.
399 FIXME: the default should be a configuration choice. */
400 int need_pthread
= 1;
402 /* True if we saw -static. */
405 /* True if we should add -shared-libgcc to the command-line. */
406 int shared_libgcc
= 1;
408 /* Have we seen the -v flag? */
409 bool verbose
= false;
411 /* The number of libraries added in. */
415 /* True if we should add -fplugin=m2rte to the command-line. */
416 bool need_plugin
= true;
418 bool need_plugin
= false;
421 /* True if we should set up include paths and library paths. */
422 bool allow_libraries
= true;
424 #if defined(DEBUG_ARG)
425 printf ("argc = %d\n", argc
);
426 fprintf (stderr
, "Incoming:");
427 for (i
= 0; i
< argc
; i
++)
428 fprintf (stderr
, " %s", decoded_options
[i
].orig_option_with_args_text
);
429 fprintf (stderr
, "\n");
433 gm2_x_decoded_options
= decoded_options
;
435 gm2_new_decoded_options
= decoded_options
;
436 added_libraries
= *in_added_libraries
;
437 args
= XCNEWVEC (int, argc
);
439 /* First pass through arglist.
441 If -nostdlib or a "turn-off-linking" option is anywhere in the
442 command line, don't do any library-option processing (except
445 for (i
= 1; i
< argc
; i
++)
447 const char *arg
= decoded_options
[i
].arg
;
449 #if defined(DEBUG_ARG)
450 printf ("1st pass: %s\n",
451 decoded_options
[i
].orig_option_with_args_text
);
453 switch (decoded_options
[i
].opt_index
)
471 libraries
= xstrdup (arg
);
472 allow_libraries
= decoded_options
[i
].value
;
473 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
476 seen_module_extension
= true;
477 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
480 need_pthread
= decoded_options
[i
].value
;
481 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
484 need_plugin
= decoded_options
[i
].value
;
485 #ifndef ENABLE_PLUGIN
487 error ("plugin support is disabled; configure with "
488 "%<--enable-plugin%>");
490 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
492 case OPT_fscaffold_dynamic
:
493 seen_scaffold_dynamic
= true;
494 scaffold_dynamic
= decoded_options
[i
].value
;
495 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
497 case OPT_fscaffold_static
:
498 seen_scaffold_static
= true;
499 scaffold_static
= decoded_options
[i
].value
;
500 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
502 case OPT_fscaffold_main
:
503 seen_scaffold_main
= true;
504 scaffold_main
= decoded_options
[i
].value
;
505 args
[i
] |= SKIPOPT
; /* We will add the option if it is needed. */
507 case OPT_fgen_module_list_
:
508 seen_gen_module_list
= true;
509 gen_module_list
= decoded_options
[i
].value
;
511 gen_module_filename
= decoded_options
[i
].arg
;
515 uselist
= decoded_options
[i
].value
;
520 case OPT_nodefaultlibs
:
525 if (strcmp (arg
, MATH_LIBRARY
) == 0)
530 else if (strcmp (arg
, "c") == 0)
533 /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
534 library
= (library
== 0) ? 1 : library
;
553 /* Arguments that go directly to the linker might be .o files,
554 or something, and so might cause libstdc++ to be needed. */
565 case OPT_fsyntax_only
:
566 /* Don't specify libraries if we won't link, since that would
572 /* PCH makes no sense here, we do not catch -output-pch on purpose,
573 that should flag an error. */
575 case OPT_fpch_preprocess
:
576 case OPT_Winvalid_pch
:
584 case OPT_static_libgcc
:
588 case OPT_static_libstdc__
:
589 library
= library
>= 0 ? 2 : library
;
590 #ifdef HAVE_LD_STATIC_DYNAMIC
591 /* Remove -static-libstdc++ from the command only if target supports
592 LD_STATIC_DYNAMIC. When not supported, it is left in so that a
593 back-end target can use outfile substitution. */
598 case OPT_static_libgm2
:
599 shared_libgm2
= false;
600 #ifdef HAVE_LD_STATIC_DYNAMIC
601 /* Remove -static-libgm2 from the command only if target supports
602 LD_STATIC_DYNAMIC. When not supported, it is left in so that a
603 back-end target can use outfile substitution. */
609 which_library
= (stdcxxlib_kind
) decoded_options
[i
].value
;
616 if (language
!= NULL
&& (strcmp (language
, "modula-2") != 0))
619 /* Override the default when the user specifies it. */
620 if (seen_scaffold_static
&& scaffold_static
&& !seen_scaffold_dynamic
)
621 scaffold_dynamic
= false;
623 /* If both options have been seen and both are true, that means the user
624 tried to set both. */
625 if (seen_scaffold_dynamic
&& scaffold_dynamic
626 && seen_scaffold_static
&& scaffold_static
)
627 error ("%qs and %qs cannot both be enabled",
628 "-fscaffold-dynamic", "-fscaffold-static");
630 if (uselist
&& gen_module_list
)
632 if (! seen_gen_module_list
)
633 gen_module_list
= false;
634 if (uselist
&& gen_module_list
)
635 error ("%qs and %qs cannot both be enabled",
636 "-fgen-module-list=", "-fuse-list=");
640 /* There's no point adding -shared-libgcc if we don't have a shared
642 #ifndef ENABLE_SHARED_LIBGCC
646 /* Second pass through arglist, transforming arguments as appropriate. */
648 append_arg (&decoded_options
[0]); /* Start with command name, of course. */
649 for (i
= 1; i
< argc
; ++i
)
651 #if defined(DEBUG_ARG)
652 printf ("2nd pass: %s\n",
653 decoded_options
[i
].orig_option_with_args_text
);
655 if ((args
[i
] & SKIPOPT
) == 0)
657 append_arg (&decoded_options
[i
]);
658 /* Make sure -lstdc++ is before the math library, since libstdc++
659 itself uses those math routines. */
660 if (!saw_math
&& (args
[i
] & MATHLIB
) && library
> 0)
661 saw_math
= &decoded_options
[i
];
663 if (!saw_libc
&& (args
[i
] & WITHLIBC
) && library
> 0)
664 saw_libc
= &decoded_options
[i
];
666 #if defined(DEBUG_ARG)
668 printf ("skipping: %s\n",
669 decoded_options
[i
].orig_option_with_args_text
);
673 /* We now add in extra arguments to facilitate a successful link.
674 Note that the libraries are added to the end of the link here
675 and also placed earlier into the link by lang-specs.h. Possibly
676 this is needed because the m2pim,m2iso libraries are cross linked
677 (--fixme-- combine all the m2 libraries into a single archive).
679 We also add default scaffold linking options. */
681 /* If we have not seen either uselist or gen_module_list and we need
682 to link or compile a module list then we turn on -fgen_module_list=-
684 if (!seen_uselist
&& !seen_gen_module_list
685 && (linking
|| scaffold_main
))
686 append_option (OPT_fgen_module_list_
, "-", 1);
688 /* We checked that they were not both enabled above, if there was a set
689 value (even iff that is 'off'), pass that to the FE. */
690 if (seen_scaffold_dynamic
|| scaffold_dynamic
)
691 append_option (OPT_fscaffold_dynamic
, NULL
, scaffold_dynamic
);
692 if (seen_scaffold_static
)
693 append_option (OPT_fscaffold_static
, NULL
, scaffold_static
);
695 /* If the user has set fscaffold-main specifically, use that. Otherwise, if
696 we are linking then set it so that we generate the relevant code for the
698 if (seen_scaffold_main
)
699 append_option (OPT_fscaffold_main
, NULL
, scaffold_main
);
701 append_option (OPT_fscaffold_main
, NULL
, true);
705 /* If the libraries have not been specified by the user, select the
706 appropriate libraries for the active dialect. */
707 if (libraries
== NULL
)
709 if (strcmp (dialect
, "iso") == 0)
710 libraries
= xstrdup ("m2iso,m2cor,m2pim,m2log");
712 /* Default to pim libraries otherwise. */
713 libraries
= xstrdup ("m2pim,m2iso,m2cor,m2log");
715 libraries
= convert_abbreviations (libraries
);
716 append_option (OPT_flibs_
, xstrdup (libraries
), 1);
719 append_option (OPT_flibs_
, xstrdup ("-"), 0); /* no system libs. */
721 if ((! seen_x_flag
) && seen_module_extension
)
722 append_option (OPT_x
, "modula-2", 1);
725 append_option (OPT_fplugin_
, "m2rte", 1);
731 #ifdef HAVE_LD_STATIC_DYNAMIC
733 append_option (OPT_Wl_
, LD_STATIC_OPTION
, 1);
735 added_libraries
+= add_default_libs (libraries
);
736 #ifdef HAVE_LD_STATIC_DYNAMIC
738 append_option (OPT_Wl_
, LD_DYNAMIC_OPTION
, 1);
742 /* Add `-lstdc++' if we haven't already done so. */
743 #ifdef HAVE_LD_STATIC_DYNAMIC
744 if (library
> 1 && !static_link
)
745 append_option (OPT_Wl_
, LD_STATIC_OPTION
, 1);
747 if (which_library
== USE_LIBCXX
)
749 append_option (OPT_l
, saw_profile_flag
? LIBCXX_PROFILE
: LIBCXX
, 1);
751 if (LIBCXXABI
!= NULL
)
753 append_option (OPT_l
, saw_profile_flag
? LIBCXXABI_PROFILE
760 append_option (OPT_l
, saw_profile_flag
? LIBSTDCXX_PROFILE
764 /* Add target-dependent static library, if necessary. */
765 if ((static_link
|| library
> 1) && LIBSTDCXX_STATIC
!= NULL
)
767 append_option (OPT_l
, LIBSTDCXX_STATIC
, 1);
770 #ifdef HAVE_LD_STATIC_DYNAMIC
771 if (library
> 1 && !static_link
)
772 append_option (OPT_Wl_
, LD_DYNAMIC_OPTION
, 1);
777 append_option (OPT_l
, saw_profile_flag
? MATH_LIBRARY_PROFILE
:
783 append_option (OPT_l
, "pthread", 1);
786 if (shared_libgcc
&& !static_link
)
787 append_option (OPT_shared_libgcc
, NULL
, 1);
789 if (verbose
&& gm2_new_decoded_options
!= gm2_x_decoded_options
)
791 fprintf (stderr
, _("Driving:"));
792 for (i
= 0; i
< gm2_newargc
; i
++)
793 fprintf (stderr
, " %s",
794 gm2_new_decoded_options
[i
].orig_option_with_args_text
);
795 fprintf (stderr
, "\n");
796 fprintf (stderr
, "new argc = %d, added_libraries = %d\n",
797 gm2_newargc
, added_libraries
);
800 *in_decoded_options_count
= gm2_newargc
;
801 *in_decoded_options
= gm2_new_decoded_options
;
802 *in_added_libraries
= added_libraries
;
806 /* Called before linking. Returns 0 on success and -1 on failure. */
808 lang_specific_pre_link (void) /* Not used for M2. */
813 /* Number of extra output files that lang_specific_pre_link may generate. */
814 int lang_specific_extra_outfiles
= 0;