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