OSDN Git Service

c687537d70046e7d094e3281c85a87c127d3be2c
[pf3gnuchains/gcc-fork.git] / gcc / genmultilib
1 #!/bin/sh 
2 # Generates multilib.h.
3 #   Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
4
5 #This file is part of GCC.
6
7 #GCC is free software; you can redistribute it and/or modify it under
8 #the terms of the GNU General Public License as published by the Free
9 #Software Foundation; either version 2, or (at your option) any later
10 #version.
11
12 #GCC is distributed in the hope that it will be useful, but WITHOUT
13 #ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 #FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 #for more details.
16
17 #You should have received a copy of the GNU General Public License
18 #along with GCC; see the file COPYING.  If not, write to the Free
19 #Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 #02111-1307, USA.
21
22 # This shell script produces a header file which the gcc driver
23 # program uses to pick which library to use based on the machine
24 # specific options that it is given.
25
26 # The first argument is a list of sets of options.  The elements in
27 # the list are separated by spaces.  Within an element, the options
28 # are separated by slashes or pipes.  No leading dash is used on the
29 # options.
30 # Each option in a set separated by slashes is mutually incompatible
31 # with all other options
32 # in the set.
33 # Each option in a set separated by pipes will be used for the library
34 # compilation and any of the options in the set will be sufficient
35 # for it to be triggered.
36
37 # The optional second argument is a list of subdirectory names.  If
38 # the second argument is non-empty, there must be as many elements in
39 # the second argument as there are options in the first argument.  The
40 # elements in the second list are separated by spaces.  If the second
41 # argument is empty, the option names will be used as the directory
42 # names.
43
44 # The optional third argument is a list of options which are
45 # identical.  The elements in the list are separated by spaces.  Each
46 # element must be of the form OPTION=OPTION.  The first OPTION should
47 # appear in the first argument, and the second should be a synonym for
48 # it.  Question marks are replaced with equal signs in both options.
49
50 # The optional fourth argument is a list of multilib directory 
51 # combinations that should not be built.
52
53 # The optional fifth argument is a list of options that should be
54 # used whenever building multilib libraries.
55
56 # The optional sixth argument is a list of exclusions used internally by
57 # the compiler similar to exceptions. The difference being that exclusions
58 # allow matching default options that genmultilib does not know about and
59 # is done at runtime as opposed to being sorted out at compile time.
60 # Each element in the list is a separate exclusion rule. Each rule is
61 # a list of options (sans preceding '-') separated by a '/'. The options
62 # on the rule are grouped as an AND operation, and all options much match
63 # for the rule to exclude a set. Options can be preceded with a '!' to
64 # match a logical NOT.
65
66 # The optional sevenths argument is a list of OS subdirectory names.
67 # The format is the same as of the second argument.
68 # The difference is that second argument describes multilib directories
69 # in GCC conventions, while this one the OS multilib convention.
70
71 # The output looks like
72 #   #define MULTILIB_MATCHES "\
73 #   SUBDIRECTORY OPTIONS;\
74 #   ...
75 #   "
76 # The SUBDIRECTORY is the subdirectory to use.  The OPTIONS are
77 # multiple options separated by spaces.  Each option may start with an
78 # exclamation point.  gcc will consider each line in turn.  If none of
79 # the options beginning with an exclamation point are present, and all
80 # of the other options are present, that subdirectory will be used.
81 # The order of the subdirectories is such that they can be created in
82 # order; that is, a subdirectory is preceded by all its parents.
83
84 # Here is an example (this is from the actual sparc64 case):
85 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
86 #               'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
87 #               '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
88 #               '../lib64 ../lib32 alt'
89 # This produces:
90 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
91 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
92 #   "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;",
93 #   "alt !m64 !m32 mno-app-regs mcmodel=medany;",
94 #   "alt !m64 !m32 mno-app-regs !mcmodel=medany;",
95 #   "alt !m64 !m32 !mno-app-regs mcmodel=medany;",
96 #   "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;",
97 #   "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
98 #   "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
99 #
100 # The effect is that `gcc -mno-app-regs' (for example) will append "alt"
101 # to the directory name when searching for libraries or startup files and
102 # `gcc -m32 -mcmodel=medany' (for example) will append "32/alt". Also note
103 # that exclusion above is moot, unless the compiler had a default of -m32,
104 # which would mean that all of the "alt" directories (not the 64/alt ones)
105 # would be ignored (not generated, nor used) since the exclusion also
106 # matches the multilib_default args.
107
108 # Copy the positional parameters into variables.
109 options=$1
110 dirnames=$2
111 matches=$3
112 exceptions=$4
113 extra=$5
114 exclusions=$6
115 osdirnames=$7
116
117 echo "static const char *const multilib_raw[] = {"
118
119 # What we want to do is select all combinations of the sets in
120 # options.  Each combination which includes a set of mutually
121 # exclusive options must then be output multiple times, once for each
122 # item in the set.  Selecting combinations is a recursive process.
123 # Since not all versions of sh support functions, we achieve recursion
124 # by creating a temporary shell script which invokes itself.
125 rm -f tmpmultilib
126 cat >tmpmultilib <<\EOF
127 #!/bin/sh
128 # This recursive script basically outputs all combinations of its
129 # input arguments, handling mutually exclusive sets of options by
130 # repetition.  When the script is called, ${initial} is the list of
131 # options which should appear before all combinations this will
132 # output.  The output looks like a list of subdirectory names with
133 # leading and trailing slashes.
134 if [ "$#" != "0" ]; then
135   first=$1
136   shift
137   case "$first" in
138   *\|*)
139     all=${initial}`echo $first | sed -e 's_|_/_'g`
140     first=`echo $first | sed -e 's_|_ _'g`
141     echo ${all}/
142     initial="${initial}${all}/" ./tmpmultilib $@
143     ./tmpmultilib $first $@ | grep -v "^${all}"
144     ;;
145   *)
146     for opt in `echo $first | sed -e 's|/| |'g`; do
147       echo ${initial}${opt}/
148     done
149     ./tmpmultilib $@
150     for opt in `echo $first | sed -e 's|/| |'g`; do
151       initial="${initial}${opt}/" ./tmpmultilib $@
152     done
153   esac
154 fi
155 EOF
156 chmod +x tmpmultilib
157
158 combinations=`initial=/ ./tmpmultilib ${options}`
159
160 rm -f tmpmultilib
161
162 # If there exceptions, weed them out now
163 if [ -n "${exceptions}" ]; then
164   rm -f tmpmultilib2
165   cat >tmpmultilib2 <<\EOF
166 #!/bin/sh
167 # This recursive script weeds out any combination of multilib
168 # switches that should not be generated.  The output looks like
169 # a list of subdirectory names with leading and trailing slashes.
170
171   for opt in $@; do
172     case "$opt" in
173 EOF
174
175   for except in ${exceptions}; do
176     echo "      /${except}/) : ;;" >> tmpmultilib2
177   done
178
179 cat >>tmpmultilib2 <<\EOF
180       *) echo ${opt};;
181     esac
182   done
183 EOF
184   chmod +x tmpmultilib2
185   combinations=`./tmpmultilib2 ${combinations}`
186   rm -f ./tmpmultilib2
187 fi
188
189 # Construct a sed pattern which will convert option names to directory
190 # names.
191 todirnames=
192 if [ -n "${dirnames}" ]; then
193   set x ${dirnames}
194   shift
195   for set in ${options}; do
196     for opts in `echo ${set} | sed -e 's|/| |'g`; do
197       patt="/"
198       for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
199         if [ "$1" != "${opt}" ]; then
200           todirnames="${todirnames} -e s|/${opt}/|/${1}/|g"
201           patt="${patt}${1}/"
202           if [ "${patt}" != "/${1}/" ]; then
203             todirnames="${todirnames} -e s|${patt}|/${1}/|g"
204           fi
205         fi
206       done
207       shift
208     done
209   done
210 fi
211
212 # Construct a sed pattern which will convert option names to OS directory
213 # names.
214 toosdirnames=
215 if [ -n "${osdirnames}" ]; then
216   set x ${osdirnames}
217   shift
218   for set in ${options}; do
219     for opts in `echo ${set} | sed -e 's|/| |'g`; do
220       patt="/"
221       for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
222         if [ "$1" != "${opt}" ]; then
223           toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
224           patt="${patt}${1}/"
225           if [ "${patt}" != "/${1}/" ]; then
226             toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
227           fi
228         fi
229       done
230       shift
231     done
232   done
233 fi
234
235 # We need another recursive shell script to correctly handle positive
236 # matches.  If we are invoked as
237 #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
238 # we must output
239 #   opt1/opt2 opt1 opt2
240 #   opt1/opt2 nopt1 opt2
241 #   opt1/opt2 opt1 nopt2
242 #   opt1/opt2 nopt1 nopt2
243 # In other words, we must output all combinations of matches.
244 rm -f tmpmultilib2
245 cat >tmpmultilib2 <<\EOF
246 #!/bin/sh
247 # The positional parameters are a list of matches to consider.
248 # ${dirout} is the directory name and ${optout} is the current list of
249 # options.
250 if [ "$#" = "0" ]; then
251   echo "\"${dirout} ${optout};\","
252 else
253   first=$1
254   shift
255   dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@
256   l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'`
257   r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'`
258   if expr " ${optout} " : ".* ${l} .*" > /dev/null; then
259     newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'`
260     dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@
261   fi
262 fi
263 EOF
264 chmod +x tmpmultilib2
265
266 # Start with the current directory, which includes only negations.
267 optout=
268 for set in ${options}; do
269   for opt in `echo ${set} | sed -e 's_[/|]_ _g'`; do
270     optout="${optout} !${opt}"
271   done
272 done
273 optout=`echo ${optout} | sed -e 's/^ //'`
274 echo "\". ${optout};\","
275
276 # Work over the list of combinations.  We have to translate each one
277 # to use the directory names rather than the option names, we have to
278 # include the information in matches, and we have to generate the
279 # correct list of options and negations.
280 for combo in ${combinations}; do
281   # Use the directory names rather than the option names.
282   if [ -n "${todirnames}" ]; then
283     dirout=`echo ${combo} | sed ${todirnames}`
284   else
285     dirout=${combo}
286   fi
287   # Remove the leading and trailing slashes.
288   dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
289
290   # Use the OS directory names rather than the option names.
291   if [ -n "${toosdirnames}" ]; then
292     osdirout=`echo ${combo} | sed ${toosdirnames}`
293     # Remove the leading and trailing slashes.
294     osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
295     if [ "x${dirout}" != "x${osdirout}" ]; then
296       dirout="${dirout}:${osdirout}"
297     fi
298   fi
299
300   # Look through the options.  We must output each option that is
301   # present, and negate each option that is not present.
302   optout=
303   for set in ${options}; do
304     setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
305     for opt in ${setopts}; do
306       if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
307         optout="${optout} ${opt}"
308       else
309         optout="${optout} !${opt}"
310       fi
311     done
312   done
313   optout=`echo ${optout} | sed -e 's/^ //'`
314
315   # Output the line with all appropriate matches.
316   dirout="${dirout}" optout="${optout}" ./tmpmultilib2
317 done
318
319 # Terminate the list of string.
320 echo "NULL"
321 echo "};"
322
323 # Output all of the matches now as option and that is the same as that, with
324 # a semicolon trailer.  Include all of the normal options as well.
325 # Note, the format of the matches is reversed compared
326 # to what we want, so switch them around.
327 echo ""
328 echo "static const char *const multilib_matches_raw[] = {"
329 for match in ${matches}; do
330   l=`echo ${match} | sed -e 's/=.*$//' -e 's/?/=/g'`
331   r=`echo ${match} | sed -e 's/^.*=//' -e 's/?/=/g'`
332   echo "\"${r} ${l};\","
333 done
334 for set in ${options}; do
335   for opt in `echo ${set} | sed -e 's_[/|]_ _'g`; do
336     echo "\"${opt} ${opt};\","
337   done
338 done
339 echo "NULL"
340 echo "};"
341
342 # Output the default options now
343 echo ""
344 echo "static const char *multilib_extra = \"${extra}\";"
345
346 # Output the exclusion rules now
347 echo ""
348 echo "static const char *const multilib_exclusions_raw[] = {"
349 for rule in ${exclusions}; do
350   s=`echo ${rule} | sed -e 's,/, ,g'`
351   echo "\"${s};\","
352 done
353 echo "NULL"
354 echo "};"
355
356 # Output the options now
357 moptions=`echo ${options} | sed -e 's,[         ][      ]*, ,g'`
358 echo ""
359 echo "static const char *multilib_options = \"${moptions}\";"
360
361 rm -f tmpmultilib2
362
363 exit 0