xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/d-spec.cc (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1627f7eb2Smrg /* d-spec.c -- Specific flags and argument handling of the D front end.
2*4c3eb207Smrg    Copyright (C) 2006-2020 Free Software Foundation, Inc.
3627f7eb2Smrg 
4627f7eb2Smrg GCC is free software; you can redistribute it and/or modify
5627f7eb2Smrg it under the terms of the GNU General Public License as published by
6627f7eb2Smrg the Free Software Foundation; either version 3, or (at your option)
7627f7eb2Smrg any later version.
8627f7eb2Smrg 
9627f7eb2Smrg GCC is distributed in the hope that it will be useful,
10627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12627f7eb2Smrg GNU General Public License for more details.
13627f7eb2Smrg 
14627f7eb2Smrg You should have received a copy of the GNU General Public License
15627f7eb2Smrg along with GCC; see the file COPYING3.  If not see
16627f7eb2Smrg <http://www.gnu.org/licenses/>.  */
17627f7eb2Smrg 
18627f7eb2Smrg #include "config.h"
19627f7eb2Smrg #include "system.h"
20627f7eb2Smrg #include "coretypes.h"
21627f7eb2Smrg #include "opt-suggestions.h"
22627f7eb2Smrg #include "gcc.h"
23627f7eb2Smrg #include "tm.h"
24627f7eb2Smrg #include "opts.h"
25627f7eb2Smrg 
26627f7eb2Smrg /* This bit is set if the arguments is a D source file.  */
27627f7eb2Smrg #define DSOURCE		(1<<1)
28627f7eb2Smrg /* This bit is set if they did `-lstdc++'.  */
29627f7eb2Smrg #define WITHLIBCXX	(1<<2)
30627f7eb2Smrg /* Skip this option.  */
31627f7eb2Smrg #define SKIPOPT		(1<<3)
32627f7eb2Smrg 
33627f7eb2Smrg #ifndef LIBSTDCXX
34627f7eb2Smrg #define LIBSTDCXX "stdc++"
35627f7eb2Smrg #endif
36627f7eb2Smrg #ifndef LIBSTDCXX_PROFILE
37627f7eb2Smrg #define LIBSTDCXX_PROFILE LIBSTDCXX
38627f7eb2Smrg #endif
39627f7eb2Smrg 
40627f7eb2Smrg #ifndef LIBPHOBOS
41627f7eb2Smrg #define LIBPHOBOS "gphobos"
42627f7eb2Smrg #endif
43627f7eb2Smrg #ifndef LIBPHOBOS_PROFILE
44627f7eb2Smrg #define LIBPHOBOS_PROFILE LIBPHOBOS
45627f7eb2Smrg #endif
46627f7eb2Smrg 
47627f7eb2Smrg /* What do with libgphobos.  */
48627f7eb2Smrg enum phobos_action
49627f7eb2Smrg {
50627f7eb2Smrg   /* libgphobos should not be linked in.  */
51627f7eb2Smrg   PHOBOS_NOLINK = -1,
52627f7eb2Smrg   /* libgphobos should be linked in if it is needed.  */
53627f7eb2Smrg   PHOBOS_DEFAULT = 0,
54627f7eb2Smrg   /* libgphobos is needed and should be linked in.  */
55627f7eb2Smrg   PHOBOS_LINK,
56627f7eb2Smrg   /* libgphobos is needed and should be linked statically.  */
57627f7eb2Smrg   PHOBOS_STATIC,
58627f7eb2Smrg   /* libgphobos is needed and should be linked dynamically.  */
59627f7eb2Smrg   PHOBOS_DYNAMIC,
60627f7eb2Smrg };
61627f7eb2Smrg 
62627f7eb2Smrg static phobos_action phobos_library = PHOBOS_DEFAULT;
63627f7eb2Smrg 
64627f7eb2Smrg /* If true, do load libgphobos.spec even if not needed otherwise.  */
65627f7eb2Smrg static bool need_spec = false;
66627f7eb2Smrg 
67627f7eb2Smrg void
lang_specific_driver(cl_decoded_option ** in_decoded_options,unsigned int * in_decoded_options_count,int * in_added_libraries)68627f7eb2Smrg lang_specific_driver (cl_decoded_option **in_decoded_options,
69627f7eb2Smrg 		      unsigned int *in_decoded_options_count,
70627f7eb2Smrg 		      int *in_added_libraries)
71627f7eb2Smrg {
72627f7eb2Smrg   unsigned int i, j;
73627f7eb2Smrg 
74627f7eb2Smrg   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
75627f7eb2Smrg   int saw_profile_flag = 0;
76627f7eb2Smrg 
77627f7eb2Smrg   /* If true, the user gave `-g'.  Used by -debuglib.  */
78627f7eb2Smrg   bool saw_debug_flag = false;
79627f7eb2Smrg 
80627f7eb2Smrg   /* The new argument list will be contained in this.  */
81627f7eb2Smrg   cl_decoded_option *new_decoded_options;
82627f7eb2Smrg 
83627f7eb2Smrg   /* "-lstdc++" if it appears on the command line.  */
84627f7eb2Smrg   const cl_decoded_option *saw_libcxx = 0;
85627f7eb2Smrg 
86*4c3eb207Smrg   /* True if we saw `-static-libstdc++'.  */
87*4c3eb207Smrg   bool saw_static_libcxx = false;
88*4c3eb207Smrg 
89627f7eb2Smrg   /* Whether we need the C++ STD library.  */
90627f7eb2Smrg   bool need_stdcxx = false;
91627f7eb2Smrg 
92627f7eb2Smrg   /* True if we saw -static.  */
93627f7eb2Smrg   bool static_link = false;
94627f7eb2Smrg 
95627f7eb2Smrg   /* True if we should add -shared-libgcc to the command-line.  */
96627f7eb2Smrg   bool shared_libgcc = true;
97627f7eb2Smrg 
98627f7eb2Smrg   /* What default library to use instead of phobos.  */
99627f7eb2Smrg   const char *defaultlib = NULL;
100627f7eb2Smrg 
101627f7eb2Smrg   /* What debug library to use instead of phobos.  */
102627f7eb2Smrg   const char *debuglib = NULL;
103627f7eb2Smrg 
104627f7eb2Smrg   /* The total number of arguments with the new stuff.  */
105627f7eb2Smrg   unsigned int num_args = 1;
106627f7eb2Smrg 
107627f7eb2Smrg   /* "-fonly" if it appears on the command line.  */
108627f7eb2Smrg   const char *only_source_option = 0;
109627f7eb2Smrg 
110627f7eb2Smrg   /* Whether the -o option was used.  */
111627f7eb2Smrg   bool saw_opt_o = false;
112627f7eb2Smrg 
113627f7eb2Smrg   /* Whether the -c option was used.  Also used for -E, -fsyntax-only,
114627f7eb2Smrg      in general anything which implies only compilation and not linking.  */
115627f7eb2Smrg   bool saw_opt_c = false;
116627f7eb2Smrg 
117627f7eb2Smrg   /* Whether the -S option was used.  */
118627f7eb2Smrg   bool saw_opt_S = false;
119627f7eb2Smrg 
120627f7eb2Smrg   /* The first input file with an extension of .d.  */
121627f7eb2Smrg   const char *first_d_file = NULL;
122627f7eb2Smrg 
123627f7eb2Smrg   /* The total number of arguments with the new stuff.  */
124627f7eb2Smrg   unsigned int argc = *in_decoded_options_count;
125627f7eb2Smrg 
126627f7eb2Smrg   /* The argument list.  */
127627f7eb2Smrg   cl_decoded_option *decoded_options = *in_decoded_options;
128627f7eb2Smrg 
129627f7eb2Smrg   /* The number of libraries added in.  */
130627f7eb2Smrg   int added_libraries = *in_added_libraries;
131627f7eb2Smrg 
132627f7eb2Smrg   /* An array used to flag each argument that needs a bit set for
133627f7eb2Smrg      DSOURCE, MATHLIB, WITHTHREAD, WITHLIBC or WITHLIBCXX.  */
134627f7eb2Smrg   int *args = XCNEWVEC (int, argc);
135627f7eb2Smrg 
136627f7eb2Smrg   for (i = 1; i < argc; i++)
137627f7eb2Smrg     {
138627f7eb2Smrg       const char *arg = decoded_options[i].arg;
139627f7eb2Smrg       const int value = decoded_options[i].value;
140627f7eb2Smrg 
141627f7eb2Smrg       switch (decoded_options[i].opt_index)
142627f7eb2Smrg 	{
143627f7eb2Smrg 	case OPT_dstartfiles:
144627f7eb2Smrg 	  need_spec = true;
145627f7eb2Smrg 	  break;
146627f7eb2Smrg 
147627f7eb2Smrg 	case OPT_nostdlib:
148627f7eb2Smrg 	case OPT_nodefaultlibs:
149627f7eb2Smrg 	  phobos_library = PHOBOS_NOLINK;
150627f7eb2Smrg 	  break;
151627f7eb2Smrg 
152627f7eb2Smrg 	case OPT_nophoboslib:
153*4c3eb207Smrg 	  phobos_library = PHOBOS_NOLINK;
154627f7eb2Smrg 	  args[i] |= SKIPOPT;
155627f7eb2Smrg 	  break;
156627f7eb2Smrg 
157627f7eb2Smrg 	case OPT_fdruntime:
158627f7eb2Smrg 	  if (!value)
159*4c3eb207Smrg 	    phobos_library = PHOBOS_NOLINK;
160*4c3eb207Smrg 	  else
161*4c3eb207Smrg 	    phobos_library = PHOBOS_LINK;
162627f7eb2Smrg 	  break;
163627f7eb2Smrg 
164627f7eb2Smrg 	case OPT_defaultlib_:
165627f7eb2Smrg 	  if (defaultlib != NULL)
166627f7eb2Smrg 	    free (CONST_CAST (char *, defaultlib));
167627f7eb2Smrg 	  if (arg != NULL)
168627f7eb2Smrg 	    {
169627f7eb2Smrg 	      args[i] |= SKIPOPT;
170627f7eb2Smrg 	      defaultlib = XNEWVEC (char, strlen (arg));
171627f7eb2Smrg 	      strcpy (CONST_CAST (char *, defaultlib), arg);
172627f7eb2Smrg 	    }
173627f7eb2Smrg 	  break;
174627f7eb2Smrg 
175627f7eb2Smrg 	case OPT_debuglib_:
176627f7eb2Smrg 	  if (debuglib != NULL)
177627f7eb2Smrg 	    free (CONST_CAST (char *, debuglib));
178627f7eb2Smrg 	  if (arg != NULL)
179627f7eb2Smrg 	    {
180627f7eb2Smrg 	      args[i] |= SKIPOPT;
181627f7eb2Smrg 	      debuglib = XNEWVEC (char, strlen (arg));
182627f7eb2Smrg 	      strcpy (CONST_CAST (char *, debuglib), arg);
183627f7eb2Smrg 	    }
184627f7eb2Smrg 	  break;
185627f7eb2Smrg 
186627f7eb2Smrg 	case OPT_l:
187627f7eb2Smrg 	  if ((strcmp (arg, LIBSTDCXX) == 0)
188627f7eb2Smrg 	      || (strcmp (arg, LIBSTDCXX_PROFILE) == 0))
189627f7eb2Smrg 	    {
190627f7eb2Smrg 	      args[i] |= WITHLIBCXX;
191627f7eb2Smrg 	      need_stdcxx = false;
192627f7eb2Smrg 	    }
193627f7eb2Smrg 	  /* Unrecognized libraries (e.g. -ltango) may require libphobos.  */
194627f7eb2Smrg 	  else if (phobos_library == PHOBOS_DEFAULT)
195627f7eb2Smrg 	    phobos_library = PHOBOS_LINK;
196627f7eb2Smrg 	  break;
197627f7eb2Smrg 
198627f7eb2Smrg 	case OPT_pg:
199627f7eb2Smrg 	case OPT_p:
200627f7eb2Smrg 	  saw_profile_flag++;
201627f7eb2Smrg 	  break;
202627f7eb2Smrg 
203627f7eb2Smrg 	case OPT_g:
204627f7eb2Smrg 	  saw_debug_flag = true;
205627f7eb2Smrg 	  break;
206627f7eb2Smrg 
207627f7eb2Smrg 	case OPT_v:
208627f7eb2Smrg 	  /* If they only gave us `-v', don't try to link in libphobos.  */
209627f7eb2Smrg 	  if (argc == 2)
210627f7eb2Smrg 	    phobos_library = PHOBOS_NOLINK;
211627f7eb2Smrg 	  break;
212627f7eb2Smrg 
213627f7eb2Smrg 	case OPT_x:
214627f7eb2Smrg 	  if (phobos_library == PHOBOS_DEFAULT && (strcmp (arg, "d") == 0))
215627f7eb2Smrg 	    phobos_library = PHOBOS_LINK;
216627f7eb2Smrg 	  break;
217627f7eb2Smrg 
218627f7eb2Smrg 	case OPT_Xlinker:
219627f7eb2Smrg 	case OPT_Wl_:
220627f7eb2Smrg 	  /* Arguments that go directly to the linker might be .o files
221627f7eb2Smrg 	     or something, and so might cause libphobos to be needed.  */
222627f7eb2Smrg 	  if (phobos_library == PHOBOS_DEFAULT)
223627f7eb2Smrg 	    phobos_library = PHOBOS_LINK;
224627f7eb2Smrg 	  break;
225627f7eb2Smrg 
226627f7eb2Smrg 	case OPT_c:
227627f7eb2Smrg 	case OPT_E:
228627f7eb2Smrg 	case OPT_M:
229627f7eb2Smrg 	case OPT_MM:
230627f7eb2Smrg 	case OPT_fsyntax_only:
231627f7eb2Smrg 	  /* Don't specify libaries if we won't link, since that would
232627f7eb2Smrg 	     cause a warning.  */
233627f7eb2Smrg 	  saw_opt_c = true;
234627f7eb2Smrg 	  phobos_library = PHOBOS_NOLINK;
235627f7eb2Smrg 	  break;
236627f7eb2Smrg 
237627f7eb2Smrg 	case OPT_S:
238627f7eb2Smrg 	  saw_opt_S = true;
239627f7eb2Smrg 	  phobos_library = PHOBOS_NOLINK;
240627f7eb2Smrg 	  break;
241627f7eb2Smrg 
242627f7eb2Smrg 	case OPT_o:
243627f7eb2Smrg 	  saw_opt_o = true;
244627f7eb2Smrg 	  break;
245627f7eb2Smrg 
246627f7eb2Smrg 	case OPT_static:
247627f7eb2Smrg 	  static_link = true;
248627f7eb2Smrg 	  break;
249627f7eb2Smrg 
250627f7eb2Smrg 	case OPT_static_libgcc:
251627f7eb2Smrg 	  shared_libgcc = false;
252627f7eb2Smrg 	  break;
253627f7eb2Smrg 
254*4c3eb207Smrg 	case OPT_static_libstdc__:
255*4c3eb207Smrg 	  saw_static_libcxx = true;
256*4c3eb207Smrg 	  args[i] |= SKIPOPT;
257*4c3eb207Smrg 	  break;
258*4c3eb207Smrg 
259627f7eb2Smrg 	case OPT_static_libphobos:
260627f7eb2Smrg 	  if (phobos_library != PHOBOS_NOLINK)
261627f7eb2Smrg 	    phobos_library = PHOBOS_STATIC;
262627f7eb2Smrg 	  args[i] |= SKIPOPT;
263627f7eb2Smrg 	  break;
264627f7eb2Smrg 
265627f7eb2Smrg 	case OPT_shared_libphobos:
266627f7eb2Smrg 	  if (phobos_library != PHOBOS_NOLINK)
267627f7eb2Smrg 	    phobos_library = PHOBOS_DYNAMIC;
268627f7eb2Smrg 	  args[i] |= SKIPOPT;
269627f7eb2Smrg 	  break;
270627f7eb2Smrg 
271627f7eb2Smrg 	case OPT_fonly_:
272627f7eb2Smrg 	  args[i] |= SKIPOPT;
273627f7eb2Smrg 	  only_source_option = decoded_options[i].orig_option_with_args_text;
274627f7eb2Smrg 
275627f7eb2Smrg 	  if (arg != NULL)
276627f7eb2Smrg 	    {
277627f7eb2Smrg 	      const char *suffix = strrchr (only_source_option, '.');
278627f7eb2Smrg 	      if (suffix == NULL || strcmp (suffix, ".d") != 0)
279627f7eb2Smrg 		only_source_option = concat (only_source_option, ".d", NULL);
280627f7eb2Smrg 	    }
281627f7eb2Smrg 	  break;
282627f7eb2Smrg 
283627f7eb2Smrg 	case OPT_SPECIAL_input_file:
284627f7eb2Smrg 	  {
285627f7eb2Smrg 	    if (arg[0] == '\0' || arg[1] == '\0')
286627f7eb2Smrg 	      continue;
287627f7eb2Smrg 
288627f7eb2Smrg 	    if (phobos_library == PHOBOS_DEFAULT)
289627f7eb2Smrg 	      phobos_library = PHOBOS_LINK;
290627f7eb2Smrg 
291627f7eb2Smrg 	    /* Record that this is a D source file.  */
292627f7eb2Smrg 	    const char *suffix = strrchr (arg, '.');
293627f7eb2Smrg 	    if (suffix != NULL && strcmp (suffix, ".d") == 0)
294627f7eb2Smrg 	      {
295627f7eb2Smrg 		if (first_d_file == NULL)
296627f7eb2Smrg 		  first_d_file = arg;
297627f7eb2Smrg 
298627f7eb2Smrg 		args[i] |= DSOURCE;
299627f7eb2Smrg 	      }
300627f7eb2Smrg 
301627f7eb2Smrg 	    /* If this is a C++ source file, we'll need to link
302627f7eb2Smrg 	       against libstdc++ library.  */
303627f7eb2Smrg 	    if (suffix != NULL
304627f7eb2Smrg 		&& (strcmp (suffix, ".cc") == 0
305627f7eb2Smrg 		    || (strcmp (suffix, ".cpp") == 0)
306627f7eb2Smrg 		    || (strcmp (suffix, ".c++") == 0)))
307627f7eb2Smrg 	      need_stdcxx = true;
308627f7eb2Smrg 
309627f7eb2Smrg 	    break;
310627f7eb2Smrg 	  }
311627f7eb2Smrg 	}
312627f7eb2Smrg     }
313627f7eb2Smrg 
314627f7eb2Smrg   /* There's no point adding -shared-libgcc if we don't have a shared
315627f7eb2Smrg      libgcc.  */
316627f7eb2Smrg #ifndef ENABLE_SHARED_LIBGCC
317627f7eb2Smrg   shared_libgcc = false;
318627f7eb2Smrg #endif
319627f7eb2Smrg 
320627f7eb2Smrg   /* Make sure to have room for the trailing NULL argument.
321*4c3eb207Smrg      - need_stdcxx might add `-lstdcxx'
322*4c3eb207Smrg      - libphobos adds `-Bstatic -lphobos -Bdynamic'
323627f7eb2Smrg      - only_source adds 1 more arg, also maybe add `-o'.  */
324*4c3eb207Smrg   num_args = argc + need_stdcxx + shared_libgcc
325*4c3eb207Smrg     + (phobos_library != PHOBOS_NOLINK) * 4 + 2;
326627f7eb2Smrg   new_decoded_options = XNEWVEC (cl_decoded_option, num_args);
327627f7eb2Smrg 
328627f7eb2Smrg   i = 0;
329627f7eb2Smrg   j = 0;
330627f7eb2Smrg 
331627f7eb2Smrg   /* Copy the 0th argument, i.e., the name of the program itself.  */
332627f7eb2Smrg   new_decoded_options[j++] = decoded_options[i++];
333627f7eb2Smrg 
334627f7eb2Smrg   /* NOTE: We start at 1 now, not 0.  */
335627f7eb2Smrg   while (i < argc)
336627f7eb2Smrg     {
337627f7eb2Smrg       if (args[i] & SKIPOPT)
338627f7eb2Smrg 	{
339627f7eb2Smrg 	  ++i;
340627f7eb2Smrg 	  continue;
341627f7eb2Smrg 	}
342627f7eb2Smrg 
343627f7eb2Smrg       new_decoded_options[j] = decoded_options[i];
344627f7eb2Smrg 
345627f7eb2Smrg       if (!saw_libcxx && (args[i] & WITHLIBCXX))
346627f7eb2Smrg 	{
347627f7eb2Smrg 	  --j;
348627f7eb2Smrg 	  saw_libcxx = &decoded_options[i];
349627f7eb2Smrg 	}
350627f7eb2Smrg 
351627f7eb2Smrg       if (args[i] & DSOURCE)
352627f7eb2Smrg 	{
353627f7eb2Smrg 	  if (only_source_option)
354627f7eb2Smrg 	    --j;
355627f7eb2Smrg 	}
356627f7eb2Smrg 
357627f7eb2Smrg       i++;
358627f7eb2Smrg       j++;
359627f7eb2Smrg     }
360627f7eb2Smrg 
361627f7eb2Smrg   if (only_source_option)
362627f7eb2Smrg     {
363627f7eb2Smrg       const char *only_source_arg = only_source_option + 7;
364627f7eb2Smrg       generate_option (OPT_fonly_, only_source_arg, 1, CL_DRIVER,
365627f7eb2Smrg 		       &new_decoded_options[j]);
366627f7eb2Smrg       j++;
367627f7eb2Smrg 
368627f7eb2Smrg       generate_option_input_file (only_source_arg,
369627f7eb2Smrg 				  &new_decoded_options[j++]);
370627f7eb2Smrg     }
371627f7eb2Smrg 
372627f7eb2Smrg   /* If no reason to link against libphobos library, then don't add it.  */
373627f7eb2Smrg   if (phobos_library == PHOBOS_DEFAULT)
374627f7eb2Smrg     phobos_library = PHOBOS_NOLINK;
375627f7eb2Smrg 
376627f7eb2Smrg   /* If we didn't see a -o option, add one.  This is because we need the
377627f7eb2Smrg      driver to pass all .d files to the D compiler.  Without a -o option
378627f7eb2Smrg      the driver will invoke the compiler separately for each input file.  */
379627f7eb2Smrg   if (first_d_file != NULL && !saw_opt_o)
380627f7eb2Smrg     {
381627f7eb2Smrg       if (saw_opt_c || saw_opt_S)
382627f7eb2Smrg 	{
383627f7eb2Smrg 	  const char *base = lbasename (first_d_file);
384627f7eb2Smrg 	  int baselen = strlen (base) - 2;
385627f7eb2Smrg 	  char *out = XNEWVEC (char, baselen + 3);
386627f7eb2Smrg 
387627f7eb2Smrg 	  memcpy (out, base, baselen);
388627f7eb2Smrg 	  /* The driver will convert .o to some other suffix if appropriate.  */
389627f7eb2Smrg 	  out[baselen] = '.';
390627f7eb2Smrg 	  if (saw_opt_S)
391627f7eb2Smrg 	    out[baselen + 1] = 's';
392627f7eb2Smrg 	  else
393627f7eb2Smrg 	    out[baselen + 1] = 'o';
394627f7eb2Smrg 	  out[baselen + 2] = '\0';
395627f7eb2Smrg 	  generate_option (OPT_o, out, 1, CL_DRIVER,
396627f7eb2Smrg 			   &new_decoded_options[j]);
397627f7eb2Smrg 	}
398627f7eb2Smrg       else
399627f7eb2Smrg 	{
400627f7eb2Smrg 	  /* Wouldn't be necessary if the driver converted .out also.  */
401627f7eb2Smrg 	  const char *out = NULL;
402627f7eb2Smrg 
403627f7eb2Smrg #ifdef TARGET_EXECUTABLE_SUFFIX
404627f7eb2Smrg 	  if (TARGET_EXECUTABLE_SUFFIX[0] != 0)
405627f7eb2Smrg 	    out = "a" TARGET_EXECUTABLE_SUFFIX;
406627f7eb2Smrg #endif
407627f7eb2Smrg 	  if (out == NULL)
408627f7eb2Smrg 	    out = "a.out";
409627f7eb2Smrg 
410627f7eb2Smrg 	  generate_option (OPT_o, out, 1, CL_DRIVER,
411627f7eb2Smrg 			   &new_decoded_options[j]);
412627f7eb2Smrg 	}
413627f7eb2Smrg       j++;
414627f7eb2Smrg     }
415627f7eb2Smrg 
416627f7eb2Smrg   /* Add `-lgphobos' if we haven't already done so.  */
417*4c3eb207Smrg   if (phobos_library != PHOBOS_NOLINK)
418627f7eb2Smrg     {
419627f7eb2Smrg       /* Default to static linking.  */
420627f7eb2Smrg       if (phobos_library != PHOBOS_DYNAMIC)
421627f7eb2Smrg 	phobos_library = PHOBOS_STATIC;
422627f7eb2Smrg 
423627f7eb2Smrg #ifdef HAVE_LD_STATIC_DYNAMIC
424*4c3eb207Smrg       if (phobos_library == PHOBOS_STATIC && !static_link)
425627f7eb2Smrg 	{
426627f7eb2Smrg 	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
427*4c3eb207Smrg 			   &new_decoded_options[j++]);
428627f7eb2Smrg 	}
429627f7eb2Smrg #endif
430*4c3eb207Smrg       /* Order of precedence in determining what library to link against is:
431*4c3eb207Smrg 	 - `-l<lib>' from `-debuglib=<lib>' if `-g' was also seen.
432*4c3eb207Smrg 	 - `-l<lib>' from `-defaultlib=<lib>'.
433*4c3eb207Smrg 	 - `-lgphobos' unless `-nophoboslib' or `-fno-druntime' was seen.  */
434*4c3eb207Smrg       if (debuglib && saw_debug_flag)
435627f7eb2Smrg 	{
436627f7eb2Smrg 	  generate_option (OPT_l, debuglib, 1, CL_DRIVER,
437627f7eb2Smrg 			   &new_decoded_options[j++]);
438627f7eb2Smrg 	  added_libraries++;
439627f7eb2Smrg 	}
440627f7eb2Smrg       else if (defaultlib)
441627f7eb2Smrg 	{
442627f7eb2Smrg 	  generate_option (OPT_l, defaultlib, 1, CL_DRIVER,
443627f7eb2Smrg 			   &new_decoded_options[j++]);
444627f7eb2Smrg 	  added_libraries++;
445627f7eb2Smrg 	}
446*4c3eb207Smrg       else
447*4c3eb207Smrg 	{
448*4c3eb207Smrg 	  generate_option (OPT_l,
449*4c3eb207Smrg 			   saw_profile_flag ? LIBPHOBOS_PROFILE : LIBPHOBOS, 1,
450*4c3eb207Smrg 			   CL_DRIVER, &new_decoded_options[j++]);
451*4c3eb207Smrg 	  added_libraries++;
452*4c3eb207Smrg 	}
453627f7eb2Smrg 
454*4c3eb207Smrg #ifdef HAVE_LD_STATIC_DYNAMIC
455*4c3eb207Smrg       if (phobos_library == PHOBOS_STATIC && !static_link)
456*4c3eb207Smrg 	{
457*4c3eb207Smrg 	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
458*4c3eb207Smrg 			   &new_decoded_options[j++]);
459*4c3eb207Smrg 	}
460*4c3eb207Smrg #endif
461*4c3eb207Smrg     }
462*4c3eb207Smrg 
463*4c3eb207Smrg   if (saw_libcxx || need_stdcxx)
464*4c3eb207Smrg     {
465*4c3eb207Smrg #ifdef HAVE_LD_STATIC_DYNAMIC
466*4c3eb207Smrg       if (saw_static_libcxx && !static_link)
467*4c3eb207Smrg 	{
468*4c3eb207Smrg 	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
469*4c3eb207Smrg 			   &new_decoded_options[j++]);
470*4c3eb207Smrg 	}
471*4c3eb207Smrg #else
472*4c3eb207Smrg       /* Push the -static-libstdc++ option back onto the command so that
473*4c3eb207Smrg 	 a target without LD_STATIC_DYNAMIC can use outfile substitution.  */
474*4c3eb207Smrg       if (saw_static_libcxx && !static_link)
475*4c3eb207Smrg 	generate_option (OPT_static_libstdc__, NULL, 1, CL_DRIVER,
476*4c3eb207Smrg 			 &new_decoded_options[j++]);
477*4c3eb207Smrg #endif
478627f7eb2Smrg       if (saw_libcxx)
479627f7eb2Smrg 	new_decoded_options[j++] = *saw_libcxx;
480627f7eb2Smrg       else if (need_stdcxx)
481627f7eb2Smrg 	{
482627f7eb2Smrg 	  generate_option (OPT_l,
483627f7eb2Smrg 			   (saw_profile_flag
484627f7eb2Smrg 			    ? LIBSTDCXX_PROFILE
485627f7eb2Smrg 			    : LIBSTDCXX),
486627f7eb2Smrg 			   1, CL_DRIVER, &new_decoded_options[j++]);
487627f7eb2Smrg 	  added_libraries++;
488627f7eb2Smrg 	}
489*4c3eb207Smrg #ifdef HAVE_LD_STATIC_DYNAMIC
490*4c3eb207Smrg       if (saw_static_libcxx && !static_link)
491*4c3eb207Smrg 	{
492*4c3eb207Smrg 	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
493*4c3eb207Smrg 			   &new_decoded_options[j++]);
494*4c3eb207Smrg 	}
495*4c3eb207Smrg #endif
496*4c3eb207Smrg     }
497627f7eb2Smrg 
498627f7eb2Smrg   if (shared_libgcc && !static_link)
499627f7eb2Smrg     {
500627f7eb2Smrg       generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
501627f7eb2Smrg 		       &new_decoded_options[j++]);
502627f7eb2Smrg     }
503627f7eb2Smrg 
504627f7eb2Smrg   *in_decoded_options_count = j;
505627f7eb2Smrg   *in_decoded_options = new_decoded_options;
506627f7eb2Smrg   *in_added_libraries = added_libraries;
507627f7eb2Smrg }
508627f7eb2Smrg 
509627f7eb2Smrg /* Called before linking.  Returns 0 on success and -1 on failure.  */
510627f7eb2Smrg 
511627f7eb2Smrg int
lang_specific_pre_link(void)512627f7eb2Smrg lang_specific_pre_link (void)
513627f7eb2Smrg {
514*4c3eb207Smrg   if ((phobos_library != PHOBOS_NOLINK) || need_spec)
515627f7eb2Smrg     do_spec ("%:include(libgphobos.spec)");
516627f7eb2Smrg 
517627f7eb2Smrg   return 0;
518627f7eb2Smrg }
519627f7eb2Smrg 
520627f7eb2Smrg /* Number of extra output files that lang_specific_pre_link may generate.  */
521627f7eb2Smrg 
522627f7eb2Smrg int lang_specific_extra_outfiles = 0;  /* Not used for D.  */
523627f7eb2Smrg 
524