[bib] Controlling the driver command line (using specs)

Richard Sandiford rsandifo@redhat.com
Fri Oct 11 08:00:00 GMT 2002


This patch is an attempt to make multilibs and specs easier
to define on ports like the MIPS, where there are several
interdependent target options.

At the moment, multilibs and specs are based on the command
line as the user originally wrote it.  So if you're interested
in some option X, you might have to cope with four cases:

   - X is specified and has an effect
   - X is specified but is redundant with other options
   - X is not specified but is implied by other options
   - X is not specified and is not active

For example, the MIPS -mabi option controls the size of longs,
but you can also specify their size separately using -mlong.
So there are dependencies like:

    -mabi=o64         implies -mlong32
    -mabi=64          implies -mlong64
    -mabi=eabi -mgp32 implies -mlong32
    -mabi=eabi -mgp64 implies -mlong64

We also support EABI combinations with the opposite long
size to normal, such as:

    -mabi=eabi -mgp32 -mlong64
    -mabi=eabi -mgp64 -mlong32

In general, the user might not use -mlong at all, might set it
to the value it would have had anyway, or use it select the
non-standard value.  It's not really possible to describe
these rules using the multilib macros, so if you try to build
-mlong multilibs, you'll often get many redundant ones.

And besides, on general principle, it doesn't seem a good
idea to try to duplicate this sort of logic every time we're
interested in -mlong*.

One way of simplifying things would be to standardise the
driver's command line first, before the multilib directory
is chosen, or any subcommands are run.  And what better way
to do that than specs? ;-)

The patch below adds a macro DRIVER_SELF_SPECS, which contains
a list of specs to apply the to driver's command line.  It
grew out of a discussion between Alex and myself (thanks Alex!)
and I think we've both found uses for it besides the one below.

Now I know there's a lot of specs-must-die sentiment out there.
But until someone comes up with a replacement, I hope this new
macro could be generally helpful.

Also included is a patch to the recently-contributed
mips64vr-elf config.  This config is supposed to have 36
multilibs, but as contributed, it builds 72.  The patch
removes the redundant ones.

(The definition of MULTILIB_REDUNDANT_DIRS was supposed
to avoid duplication, but it relied on Red-Hat-local
infrastructure.)

Tested on mips64vr-elf on bib.  OK to install?

In a way, this is a bug fix, since the mainline config wastes
several 100Mb of disk space when installed.  Is that enough
to qualify it for mainline?

Richard


	* doc/tm.texi (DRIVER_SELF_SPECS): Document.
	* gcc.c (no_driver_warning): New variable.
	(process_command): Set it when passed -B.
	(do_self_spec): New function.
	(main): If DRIVER_SELF_SPEC is defined, pass it to do_self_spec
	after calling process_command.  If DRIVER_WARNING_SPEC is defined,
	apply it after verifying the command line.

	* config/mips/vr.h (DRIVER_SELF_SPECS): Define.
	* config/mips/t-vr (MULTILIB_OPTIONS): Remove mlong32.
	(MULTILIB_DIRNAMES): Remove long32.
	(MULTILIB_EXCEPTIONS): Don't build -mabi=32 -mgp32 multilibs.
	(MULTILIB_REDUNDANT_DIRS): Remove.

Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.159.2.8
diff -c -d -p -r1.159.2.8 tm.texi
*** doc/tm.texi	3 Oct 2002 17:44:15 -0000	1.159.2.8
--- doc/tm.texi	11 Oct 2002 13:27:58 -0000
*************** multilibs.  Example nonsensical definiti
*** 163,168 ****
--- 163,185 ----
  @{ "-compat", "-EB -malign=4 -mspoo" @}
  @end smallexample
  
+ @findex DRIVER_SELF_SPECS
+ @item DRIVER_SELF_SPECS
+ A list of specs for the driver itself.  It should be a suitable
+ initializer for an array of strings, with no surrounding braces.
+ 
+ The driver applies these specs to its own command line before choosing
+ the multilib directory or running any subcommands.  It applies them in
+ the order given, so each spec can depend on the options added by
+ earlier ones.  It is also possible to remove options using
+ @samp{%<@var{option}} in the usual way.
+ 
+ This macro can be useful when a port has several interdependent target
+ options.  It provides a way of standardizing the command line so
+ that the other specs are easier to write.
+ 
+ Do not define this macro if it does not need to do anything.
+ 
  @findex CPP_SPEC
  @item CPP_SPEC
  A C string constant that tells the GCC driver program options to
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.336.4.7
diff -c -d -p -r1.336.4.7 gcc.c
*** gcc.c	4 Oct 2002 19:45:51 -0000	1.336.4.7
--- gcc.c	11 Oct 2002 13:27:58 -0000
*************** static char *save_string	PARAMS ((const 
*** 304,309 ****
--- 304,310 ----
  static void set_collect_gcc_options PARAMS ((void));
  static int do_spec_1		PARAMS ((const char *, int, const char *));
  static int do_spec_2		PARAMS ((const char *));
+ static void do_self_spec	PARAMS ((const char *));
  static const char *find_file	PARAMS ((const char *));
  static int is_directory		PARAMS ((const char *, const char *, int));
  static const char *validate_switches	PARAMS ((const char *));
*************** static const char *multilib_exclusions;
*** 766,771 ****
--- 767,778 ----
  
  static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
  
+ #ifndef DRIVER_SELF_SPECS
+ #define DRIVER_SELF_SPECS ""
+ #endif
+ 
+ static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
+ 
  struct user_specs
  {
    struct user_specs *next;
*************** do_spec_2 (spec)
*** 4278,4283 ****
--- 4285,4329 ----
    return do_spec_1 (spec, 0, NULL);
  }
  
+ 
+ /* Process the given spec string and add any new options to the end
+    of the switches/n_switches array.  */
+ 
+ static void
+ do_self_spec (spec)
+      const char *spec;
+ {
+   do_spec_2 (spec);
+   do_spec_1 (" ", 0, NULL);
+ 
+   if (argbuf_index > 0)
+     {
+       int i, first;
+ 
+       first = n_switches;
+       n_switches += argbuf_index;
+       switches = xrealloc (switches,
+ 			   sizeof (struct switchstr) * (n_switches + 1));
+ 
+       switches[n_switches] = switches[first];
+       for (i = 0; i < argbuf_index; i++)
+ 	{
+ 	  struct switchstr *sw;
+ 
+ 	  /* Each switch should start with '-'.  */
+ 	  if (argbuf[i][0] != '-')
+ 	    abort ();
+ 
+ 	  sw = &switches[i + first];
+ 	  sw->part1 = &argbuf[i][1];
+ 	  sw->args = 0;
+ 	  sw->live_cond = SWITCH_OK;
+ 	  sw->validated = 0;
+ 	  sw->ordering = 0;
+ 	}
+     }
+ }
+ 
  /* Process the sub-spec SPEC as a portion of a larger spec.
     This is like processing a whole spec except that we do
     not initialize at the beginning and we do not supply a
*************** main (argc, argv)
*** 5994,5999 ****
--- 6040,6051 ----
       Decode switches that are handled locally.  */
  
    process_command (argc, argv);
+ 
+   /* Process DRIVER_SELF_SPECS, adding any new options to the end
+      of the command line.  */
+ 
+   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+     do_self_spec (driver_self_specs[i]);
  
    /* Initialize the vector of specs to just the default.
       This means one element containing 0s, as a terminator.  */




Index: config/mips/vr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/vr.h,v
retrieving revision 1.1
diff -c -d -p -r1.1 vr.h
*** config/mips/vr.h	20 Aug 2002 21:53:28 -0000	1.1
--- config/mips/vr.h	11 Oct 2002 13:28:43 -0000
*************** the Free Software Foundation, 675 Mass A
*** 22,24 ****
--- 22,31 ----
  #define MIPS_CPU_STRING_DEFAULT "vr4100"
  #define MULTILIB_DEFAULTS \
  	{ MULTILIB_ENDIAN_DEFAULT, MULTILIB_ABI_DEFAULT, "march=vr4100" }
+ 
+ /* Make sure that -mlong64 always appears on the command line when
+    64-bit longs are needed.  Also make sure that -mgp32 doesn't appear
+    if it is redundant.  */
+ #define DRIVER_SELF_SPECS \
+ 	"%{mabi=eabi:%{!mlong*:%{!mgp32:-mlong64}}}", \
+ 	"%{mabi=32:%<mgp32}"
Index: config/mips/t-vr
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/t-vr,v
retrieving revision 1.1
diff -c -d -p -r1.1 t-vr
*** config/mips/t-vr	20 Aug 2002 21:53:28 -0000	1.1
--- config/mips/t-vr	11 Oct 2002 13:28:43 -0000
*************** MULTILIB_OPTIONS =			\
*** 39,45 ****
  	EL/EB				\
  	mabi=32/mabi=o64/mabi=eabi	\
  	mgp32				\
! 	mlong32/mlong64			\
  	mips16				\
  	march=vr5400/march=vr4100
  
--- 39,45 ----
  	EL/EB				\
  	mabi=32/mabi=o64/mabi=eabi	\
  	mgp32				\
! 	mlong64				\
  	mips16				\
  	march=vr5400/march=vr4100
  
*************** MULTILIB_DIRNAMES =	\
*** 47,53 ****
  	el eb		\
  	o32 o64 eabi	\
  	gp32		\
! 	long32 long64	\
  	mips16		\
  	vr5400 vr4100
  
--- 47,53 ----
  	el eb		\
  	o32 o64 eabi	\
  	gp32		\
! 	long64		\
  	mips16		\
  	vr5400 vr4100
  
*************** MULTILIB_MATCHES = EL=mel EB=meb
*** 59,96 ****
  # without a -mabi flag.
  MULTILIB_EXCEPTIONS =				\
  	*mabi=32/mlong64*			\
! 	*mabi=32/mgp32/mlong64*			\
  	*mabi=o64/mgp32*			\
  	*mabi=o64/mlong64*			\
  	mgp32* E[LB]/mgp32*			\
  	mlong64* E[LB]/mlong64*			\
  	*mips16/march=vr5*
- 
- # The real value of this macro is very long, so generate it using a
- # shell fragment.  The idea is to tell the GCC driver how -mabi,
- # -mgp32, -mlong32 and -mlong64 interact, so that it choses the right
- # library when some options are specified redundantly (for example,
- # -mabi=32 -mgp32).
- 
- # The core equalities are listed after "for changes in ".  The first
- # entry assumes o64 is the default ABI.
- MULTILIB_REDUNDANT_DIRS=` \
- 	for endian in '' 'el' 'eb'; do					\
- 	  for arch in '' 'vr5400' 'vr4100'				\
- 		      'mips16' 'mips16/vr100'; do			\
- 	    for changes in long32=					\
- 			   o32/gp32=o32					\
- 			   o32/gp32/long32=o32				\
- 			   o32/long32=o32				\
- 			   o64/long32=o64				\
- 			   eabi/gp32/long32=eabi/gp32			\
- 			   eabi/long64=eabi; do				\
- 	      from=\`echo \$${changes} | sed 's/=.*//'\`;		\
- 	      to=\`echo \$${changes} | sed 's/.*=//'\`;			\
- 	      echo \$$endian \$$from \$$arch=\$$endian \$$to \$$arch	\
- 		| sed -e 's: *= *:=:'					\
- 		      -e 's:  *:/:g'					\
- 		      -e 's:=$$:=.:';					\
- 	    done;							\
- 	  done;								\
- 	done`
--- 59,67 ----
  # without a -mabi flag.
  MULTILIB_EXCEPTIONS =				\
  	*mabi=32/mlong64*			\
! 	*mabi=32/mgp32*				\
  	*mabi=o64/mgp32*			\
  	*mabi=o64/mlong64*			\
  	mgp32* E[LB]/mgp32*			\
  	mlong64* E[LB]/mlong64*			\
  	*mips16/march=vr5*



More information about the Gcc-patches mailing list