gcc.c: Include multilib.h.
* gcc.c: Include multilib.h. (print_multi_lib, print_multi_directory, multilib_select, multilib_dir): New static variables. (option_map): Added --print-multi-lib and --print-multi-directory. (set_spec): Get multilib_select from specs file. (process_command): Dump multilib_select into specs file. Handle -print-multi-lib and -print-multi-directory. (do_spec_1): Try multilib_dir for %D case. (find_file): Try multilib_dir. (main): Call set_multilib_dir. Handle print_multi_lib and print_multi_directory. (used_arg, set_multilib_dir, print_multilib_info): New functions. From-SVN: r7491
This commit is contained in:
parent
f6cdc7ea0f
commit
60103a3482
306
gcc/gcc.c
306
gcc/gcc.c
@ -45,6 +45,9 @@ compilation is specified by a string called a "spec". */
|
|||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Include multi-lib information. */
|
||||||
|
#include "multilib.h"
|
||||||
|
|
||||||
#ifndef R_OK
|
#ifndef R_OK
|
||||||
#define R_OK 4
|
#define R_OK 4
|
||||||
#define W_OK 2
|
#define W_OK 2
|
||||||
@ -151,6 +154,16 @@ static char *print_file_name = NULL;
|
|||||||
|
|
||||||
static char *print_prog_name = NULL;
|
static char *print_prog_name = NULL;
|
||||||
|
|
||||||
|
/* Flag saying to print the relative path we'd use to
|
||||||
|
find libgcc.a given the current compiler flags. */
|
||||||
|
|
||||||
|
static int print_multi_directory;
|
||||||
|
|
||||||
|
/* Flag saying to print the list of subdirectories and
|
||||||
|
compiler flags used to select them in a standard form. */
|
||||||
|
|
||||||
|
static int print_multi_lib;
|
||||||
|
|
||||||
/* Flag indicating whether we should print the command and arguments */
|
/* Flag indicating whether we should print the command and arguments */
|
||||||
|
|
||||||
static int verbose_flag;
|
static int verbose_flag;
|
||||||
@ -224,6 +237,9 @@ static int is_directory PROTO((char *, char *, int));
|
|||||||
static void validate_switches PROTO((char *));
|
static void validate_switches PROTO((char *));
|
||||||
static void validate_all_switches PROTO((void));
|
static void validate_all_switches PROTO((void));
|
||||||
static void give_switch PROTO((int, int));
|
static void give_switch PROTO((int, int));
|
||||||
|
static int used_arg PROTO((char *, int));
|
||||||
|
static void set_multilib_dir PROTO((void));
|
||||||
|
static void print_multilib_info PROTO((void));
|
||||||
static void pfatal_with_name PROTO((char *));
|
static void pfatal_with_name PROTO((char *));
|
||||||
static void perror_with_name PROTO((char *));
|
static void perror_with_name PROTO((char *));
|
||||||
static void perror_exec PROTO((char *));
|
static void perror_exec PROTO((char *));
|
||||||
@ -304,6 +320,7 @@ or with constant text in a single argument.
|
|||||||
used here. This can be used to run a post-processor after the
|
used here. This can be used to run a post-processor after the
|
||||||
assembler has done it's job.
|
assembler has done it's job.
|
||||||
%D Dump out a -L option for each directory in startfile_prefix.
|
%D Dump out a -L option for each directory in startfile_prefix.
|
||||||
|
If multilib_dir is set, extra entries are generated with it affixed.
|
||||||
%l process LINK_SPEC as a spec.
|
%l process LINK_SPEC as a spec.
|
||||||
%L process LIB_SPEC as a spec.
|
%L process LIB_SPEC as a spec.
|
||||||
%S process STARTFILE_SPEC as a spec. A capital S is actually used here.
|
%S process STARTFILE_SPEC as a spec. A capital S is actually used here.
|
||||||
@ -433,6 +450,13 @@ proper position among the other output files. */
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* MULTILIB_SELECT comes from multilib.h. It gives a
|
||||||
|
string interpreted by set_multilib_dir to select a library
|
||||||
|
subdirectory based on the compiler options. */
|
||||||
|
#ifndef MULTILIB_SELECT
|
||||||
|
#define MULTILIB_SELECT ". ;"
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *cpp_spec = CPP_SPEC;
|
static char *cpp_spec = CPP_SPEC;
|
||||||
static char *cpp_predefines = CPP_PREDEFINES;
|
static char *cpp_predefines = CPP_PREDEFINES;
|
||||||
static char *cc1_spec = CC1_SPEC;
|
static char *cc1_spec = CC1_SPEC;
|
||||||
@ -445,6 +469,7 @@ static char *lib_spec = LIB_SPEC;
|
|||||||
static char *endfile_spec = ENDFILE_SPEC;
|
static char *endfile_spec = ENDFILE_SPEC;
|
||||||
static char *startfile_spec = STARTFILE_SPEC;
|
static char *startfile_spec = STARTFILE_SPEC;
|
||||||
static char *switches_need_spaces = SWITCHES_NEED_SPACES;
|
static char *switches_need_spaces = SWITCHES_NEED_SPACES;
|
||||||
|
static char *multilib_select = MULTILIB_SELECT;
|
||||||
|
|
||||||
/* This defines which switch letters take arguments. */
|
/* This defines which switch letters take arguments. */
|
||||||
|
|
||||||
@ -789,6 +814,8 @@ struct option_map option_map[] =
|
|||||||
{"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
|
{"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
|
||||||
{"--print-file-name", "-print-file-name=", "aj"},
|
{"--print-file-name", "-print-file-name=", "aj"},
|
||||||
{"--print-prog-name", "-print-prog-name=", "aj"},
|
{"--print-prog-name", "-print-prog-name=", "aj"},
|
||||||
|
{"--print-multi-lib", "-print-multi-lib", 0},
|
||||||
|
{"--print-multi-directory", "-print-multi-directory", 0},
|
||||||
{"--static", "-static", 0},
|
{"--static", "-static", 0},
|
||||||
{"--shared", "-shared", 0},
|
{"--shared", "-shared", 0},
|
||||||
{"--symbolic", "-symbolic", 0},
|
{"--symbolic", "-symbolic", 0},
|
||||||
@ -1144,6 +1171,8 @@ set_spec (name, spec)
|
|||||||
switches_need_spaces = sl->spec;
|
switches_need_spaces = sl->spec;
|
||||||
else if (! strcmp (name, "cross_compile"))
|
else if (! strcmp (name, "cross_compile"))
|
||||||
cross_compile = atoi (sl->spec);
|
cross_compile = atoi (sl->spec);
|
||||||
|
else if (! strcmp (name, "multilib"))
|
||||||
|
multilib_select = sl->spec;
|
||||||
/* Free the old spec */
|
/* Free the old spec */
|
||||||
if (old_spec)
|
if (old_spec)
|
||||||
free (old_spec);
|
free (old_spec);
|
||||||
@ -1269,6 +1298,11 @@ static char *standard_startfile_prefix_2 = "/usr/lib/";
|
|||||||
static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
|
static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
|
||||||
static char *tooldir_prefix;
|
static char *tooldir_prefix;
|
||||||
|
|
||||||
|
/* Subdirectory to use for locating libraries. Set by
|
||||||
|
set_multilib_dir based on the compilation options. */
|
||||||
|
|
||||||
|
static char *multilib_dir;
|
||||||
|
|
||||||
/* Clear out the vector of arguments (after a command is executed). */
|
/* Clear out the vector of arguments (after a command is executed). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2340,6 +2374,7 @@ process_command (argc, argv)
|
|||||||
printf ("*signed_char:\n%s\n\n", signed_char_spec);
|
printf ("*signed_char:\n%s\n\n", signed_char_spec);
|
||||||
printf ("*predefines:\n%s\n\n", cpp_predefines);
|
printf ("*predefines:\n%s\n\n", cpp_predefines);
|
||||||
printf ("*cross_compile:\n%d\n\n", cross_compile);
|
printf ("*cross_compile:\n%d\n\n", cross_compile);
|
||||||
|
printf ("*multilib:\n%s\n\n", multilib_select);
|
||||||
|
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
@ -2354,6 +2389,10 @@ process_command (argc, argv)
|
|||||||
print_file_name = argv[i] + 17;
|
print_file_name = argv[i] + 17;
|
||||||
else if (! strncmp (argv[i], "-print-prog-name=", 17))
|
else if (! strncmp (argv[i], "-print-prog-name=", 17))
|
||||||
print_prog_name = argv[i] + 17;
|
print_prog_name = argv[i] + 17;
|
||||||
|
else if (! strcmp (argv[i], "-print-multi-lib"))
|
||||||
|
print_multi_lib = 1;
|
||||||
|
else if (! strcmp (argv[i], "-print-multi-directory"))
|
||||||
|
print_multi_directory = 1;
|
||||||
else if (! strcmp (argv[i], "-Xlinker"))
|
else if (! strcmp (argv[i], "-Xlinker"))
|
||||||
{
|
{
|
||||||
/* Pass the argument of this option to the linker when we link. */
|
/* Pass the argument of this option to the linker when we link. */
|
||||||
@ -2597,6 +2636,10 @@ process_command (argc, argv)
|
|||||||
;
|
;
|
||||||
else if (! strncmp (argv[i], "-print-prog-name=", 17))
|
else if (! strncmp (argv[i], "-print-prog-name=", 17))
|
||||||
;
|
;
|
||||||
|
else if (! strcmp (argv[i], "-print-multi-lib"))
|
||||||
|
;
|
||||||
|
else if (! strcmp (argv[i], "-print-multi-directory"))
|
||||||
|
;
|
||||||
else if (argv[i][0] == '+' && argv[i][1] == 'e')
|
else if (argv[i][0] == '+' && argv[i][1] == 'e')
|
||||||
{
|
{
|
||||||
/* Compensate for the +e options to the C++ front-end;
|
/* Compensate for the +e options to the C++ front-end;
|
||||||
@ -2941,6 +2984,45 @@ do_spec_1 (spec, inswitch, soft_matched_part)
|
|||||||
if (pl->prefix[0] != '/')
|
if (pl->prefix[0] != '/')
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
/* Try subdirectory if there is one. */
|
||||||
|
if (multilib_dir != NULL)
|
||||||
|
{
|
||||||
|
if (machine_suffix)
|
||||||
|
{
|
||||||
|
if (strlen (pl->prefix) + strlen (machine_suffix)
|
||||||
|
>= bufsize)
|
||||||
|
bufsize = (strlen (pl->prefix)
|
||||||
|
+ strlen (machine_suffix)) * 2 + 1;
|
||||||
|
buffer = (char *) xrealloc (buffer, bufsize);
|
||||||
|
strcpy (buffer, pl->prefix);
|
||||||
|
strcat (buffer, machine_suffix);
|
||||||
|
if (is_directory (buffer, multilib_dir, 1))
|
||||||
|
{
|
||||||
|
do_spec_1 ("-L", 0, NULL_PTR);
|
||||||
|
#ifdef SPACE_AFTER_L_OPTION
|
||||||
|
do_spec_1 (" ", 0, NULL_PTR);
|
||||||
|
#endif
|
||||||
|
do_spec_1 (buffer, 1, NULL_PTR);
|
||||||
|
do_spec_1 (multilib_dir, 1, NULL_PTR);
|
||||||
|
/* Make this a separate argument. */
|
||||||
|
do_spec_1 (" ", 0, NULL_PTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pl->require_machine_suffix)
|
||||||
|
{
|
||||||
|
if (is_directory (pl->prefix, multilib_dir, 1))
|
||||||
|
{
|
||||||
|
do_spec_1 ("-L", 0, NULL_PTR);
|
||||||
|
#ifdef SPACE_AFTER_L_OPTION
|
||||||
|
do_spec_1 (" ", 0, NULL_PTR);
|
||||||
|
#endif
|
||||||
|
do_spec_1 (pl->prefix, 1, NULL_PTR);
|
||||||
|
do_spec_1 (multilib_dir, 1, NULL_PTR);
|
||||||
|
/* Make this a separate argument. */
|
||||||
|
do_spec_1 (" ", 0, NULL_PTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (machine_suffix)
|
if (machine_suffix)
|
||||||
{
|
{
|
||||||
if (is_directory (pl->prefix, machine_suffix, 1))
|
if (is_directory (pl->prefix, machine_suffix, 1))
|
||||||
@ -3836,6 +3918,24 @@ find_file (name)
|
|||||||
{
|
{
|
||||||
char *newname;
|
char *newname;
|
||||||
|
|
||||||
|
/* Try multilib_dir if it is defined. */
|
||||||
|
if (multilib_dir != NULL)
|
||||||
|
{
|
||||||
|
char *try;
|
||||||
|
|
||||||
|
try = (char *) alloca (strlen (multilib_dir) + strlen (name) + 2);
|
||||||
|
strcpy (try, multilib_dir);
|
||||||
|
strcat (try, "/");
|
||||||
|
strcat (try, name);
|
||||||
|
|
||||||
|
newname = find_a_file (&startfile_prefix, try, R_OK);
|
||||||
|
|
||||||
|
/* If we don't find it in the multi library dir, then fall
|
||||||
|
through and look for it in the normal places. */
|
||||||
|
if (newname != NULL)
|
||||||
|
return newname;
|
||||||
|
}
|
||||||
|
|
||||||
newname = find_a_file (&startfile_prefix, name, R_OK);
|
newname = find_a_file (&startfile_prefix, name, R_OK);
|
||||||
return newname ? newname : name;
|
return newname ? newname : name;
|
||||||
}
|
}
|
||||||
@ -4022,6 +4122,10 @@ main (argc, argv)
|
|||||||
|
|
||||||
validate_all_switches ();
|
validate_all_switches ();
|
||||||
|
|
||||||
|
/* Now that we have the switches and the specs, set
|
||||||
|
the subdirectory based on the options. */
|
||||||
|
set_multilib_dir ();
|
||||||
|
|
||||||
/* Warn about any switches that no pass was interested in. */
|
/* Warn about any switches that no pass was interested in. */
|
||||||
|
|
||||||
for (i = 0; i < n_switches; i++)
|
for (i = 0; i < n_switches; i++)
|
||||||
@ -4043,6 +4147,21 @@ main (argc, argv)
|
|||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (print_multi_lib)
|
||||||
|
{
|
||||||
|
print_multilib_info ();
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_multi_directory)
|
||||||
|
{
|
||||||
|
if (multilib_dir == NULL)
|
||||||
|
printf (".\n");
|
||||||
|
else
|
||||||
|
printf ("%s\n", multilib_dir);
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "gcc version %s\n", version_string);
|
fprintf (stderr, "gcc version %s\n", version_string);
|
||||||
@ -4585,3 +4704,190 @@ validate_switches (start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether a particular argument was used. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
used_arg (p, len)
|
||||||
|
char *p;
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_switches; i++)
|
||||||
|
if (! strncmp (switches[i].part1, p, len)
|
||||||
|
&& strlen (switches[i].part1) == len)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Work out the subdirectory to use based on the
|
||||||
|
options. The format of multilib_select is a list of elements.
|
||||||
|
Each element is a subdirectory name followed by a list of options
|
||||||
|
followed by a semicolon. gcc will consider each line in turn. If
|
||||||
|
none of the options beginning with an exclamation point are
|
||||||
|
present, and all of the other options are present, that
|
||||||
|
subdirectory will be used. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_multilib_dir ()
|
||||||
|
{
|
||||||
|
char *p = multilib_select;
|
||||||
|
int this_path_len;
|
||||||
|
char *this_path, *this_arg;
|
||||||
|
int failed;
|
||||||
|
|
||||||
|
while (*p != '\0')
|
||||||
|
{
|
||||||
|
/* Ignore newlines. */
|
||||||
|
if (*p == '\n')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the initial path. */
|
||||||
|
this_path = p;
|
||||||
|
while (*p != ' ')
|
||||||
|
{
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
this_path_len = p - this_path;
|
||||||
|
|
||||||
|
/* Check the arguments. */
|
||||||
|
failed = 0;
|
||||||
|
++p;
|
||||||
|
while (*p != ';')
|
||||||
|
{
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_arg = p;
|
||||||
|
while (*p != ' ' && *p != ';')
|
||||||
|
{
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*this_arg == '!')
|
||||||
|
failed = used_arg (this_arg + 1, p - (this_arg + 1));
|
||||||
|
else
|
||||||
|
failed = ! used_arg (this_arg, p - this_arg);
|
||||||
|
|
||||||
|
if (*p == ' ')
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! failed)
|
||||||
|
{
|
||||||
|
if (this_path_len != 1
|
||||||
|
|| this_path[0] != '.')
|
||||||
|
{
|
||||||
|
multilib_dir = xmalloc (this_path_len + 1);
|
||||||
|
strncpy (multilib_dir, this_path, this_path_len);
|
||||||
|
multilib_dir[this_path_len] = '\0';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out the multiple library subdirectory selection
|
||||||
|
information. This prints out a series of lines. Each line looks
|
||||||
|
like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
|
||||||
|
required. Only the desired options are printed out, the negative
|
||||||
|
matches. The options are print without a leading dash. There are
|
||||||
|
no spaces to make it easy to use the information in the shell.
|
||||||
|
Each subdirectory is printed only once. This assumes the ordering
|
||||||
|
generated by the genmultilib script. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_multilib_info ()
|
||||||
|
{
|
||||||
|
char *p = multilib_select;
|
||||||
|
char *last_path, *this_path;
|
||||||
|
int last_path_len, skip, use_arg;
|
||||||
|
|
||||||
|
while (*p != '\0')
|
||||||
|
{
|
||||||
|
/* Ignore newlines. */
|
||||||
|
if (*p == '\n')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the initial path. */
|
||||||
|
this_path = p;
|
||||||
|
while (*p != ' ')
|
||||||
|
{
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is a duplicate, skip it. */
|
||||||
|
skip = (p - this_path == last_path_len
|
||||||
|
&& ! strncmp (last_path, this_path, last_path_len));
|
||||||
|
|
||||||
|
last_path = this_path;
|
||||||
|
last_path_len = p - this_path;
|
||||||
|
|
||||||
|
if (! skip)
|
||||||
|
{
|
||||||
|
char *p1;
|
||||||
|
|
||||||
|
for (p1 = last_path; p1 < p; p1++)
|
||||||
|
putchar (*p1);
|
||||||
|
putchar (';');
|
||||||
|
}
|
||||||
|
|
||||||
|
++p;
|
||||||
|
while (*p != ';')
|
||||||
|
{
|
||||||
|
int use_arg;
|
||||||
|
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
use_arg = *p != '!';
|
||||||
|
|
||||||
|
if (use_arg)
|
||||||
|
putchar ('@');
|
||||||
|
|
||||||
|
while (*p != ' ' && *p != ';')
|
||||||
|
{
|
||||||
|
if (*p == '\0')
|
||||||
|
abort ();
|
||||||
|
if (use_arg)
|
||||||
|
putchar (*p);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == ' ')
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! skip)
|
||||||
|
putchar ('\n');
|
||||||
|
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user