1#!/bin/sh 2# Generates multilib.h. 3# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002 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, 51 Franklin Street, Fifth Floor, Boston, MA 20#02110-1301, 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 seventh argument is a list of OS subdirectory names. 67# The format is either the same as of the second argument, or a set of 68# mappings. When it is the same as the second argument, it describes 69# the multilib directories using OS conventions, rather than GCC 70# conventions. When it is a set of mappings of the form gccdir=osdir, 71# the left side gives the GCC convention and the right gives the 72# equivalent OS defined location. If the osdir part begins with a !, 73# the os directory names are used exclusively. Use the mapping when 74# there is no one-to-one equivalence between GCC levels and the OS. 75 76# The last option should be "yes" if multilibs are enabled. If it is not 77# "yes", all GCC multilib dir names will be ".". 78 79# The output looks like 80# #define MULTILIB_MATCHES "\ 81# SUBDIRECTORY OPTIONS;\ 82# ... 83# " 84# The SUBDIRECTORY is the subdirectory to use. The OPTIONS are 85# multiple options separated by spaces. Each option may start with an 86# exclamation point. gcc will consider each line in turn. If none of 87# the options beginning with an exclamation point are present, and all 88# of the other options are present, that subdirectory will be used. 89# The order of the subdirectories is such that they can be created in 90# order; that is, a subdirectory is preceded by all its parents. 91 92# Here is an example (this is from the actual sparc64 case): 93# genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt' 94# 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*' 95# '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany' 96# '../lib64 ../lib32 alt' yes 97# This produces: 98# ". !m64 !m32 !mno-app-regs !mcmodel=medany;", 99# "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;", 100# "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;", 101# "alt !m64 !m32 mno-app-regs mcmodel=medany;", 102# "alt !m64 !m32 mno-app-regs !mcmodel=medany;", 103# "alt !m64 !m32 !mno-app-regs mcmodel=medany;", 104# "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;", 105# "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;", 106# "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;", 107# 108# The effect is that `gcc -mno-app-regs' (for example) will append "alt" 109# to the directory name when searching for libraries or startup files and 110# `gcc -m32 -mcmodel=medany' (for example) will append "32/alt". Also note 111# that exclusion above is moot, unless the compiler had a default of -m32, 112# which would mean that all of the "alt" directories (not the 64/alt ones) 113# would be ignored (not generated, nor used) since the exclusion also 114# matches the multilib_default args. 115 116# Copy the positional parameters into variables. 117options=$1 118dirnames=$2 119matches=$3 120exceptions=$4 121extra=$5 122exclusions=$6 123osdirnames=$7 124enable_multilib=$8 125 126echo "static const char *const multilib_raw[] = {" 127 128mkdir tmpmultilib.$$ || exit 1 129# Use cd ./foo to avoid CDPATH output. 130cd ./tmpmultilib.$$ || exit 1 131 132# What we want to do is select all combinations of the sets in 133# options. Each combination which includes a set of mutually 134# exclusive options must then be output multiple times, once for each 135# item in the set. Selecting combinations is a recursive process. 136# Since not all versions of sh support functions, we achieve recursion 137# by creating a temporary shell script which invokes itself. 138rm -f tmpmultilib 139cat >tmpmultilib <<\EOF 140#!/bin/sh 141# This recursive script basically outputs all combinations of its 142# input arguments, handling mutually exclusive sets of options by 143# repetition. When the script is called, ${initial} is the list of 144# options which should appear before all combinations this will 145# output. The output looks like a list of subdirectory names with 146# leading and trailing slashes. 147if [ "$#" != "0" ]; then 148 first=$1 149 shift 150 case "$first" in 151 *\|*) 152 all=${initial}`echo $first | sed -e 's_|_/_'g` 153 first=`echo $first | sed -e 's_|_ _'g` 154 echo ${all}/ 155 initial="${initial}${all}/" ./tmpmultilib $@ 156 ./tmpmultilib $first $@ | grep -v "^${all}" 157 ;; 158 *) 159 for opt in `echo $first | sed -e 's|/| |'g`; do 160 echo ${initial}${opt}/ 161 done 162 ./tmpmultilib $@ 163 for opt in `echo $first | sed -e 's|/| |'g`; do 164 initial="${initial}${opt}/" ./tmpmultilib $@ 165 done 166 esac 167fi 168EOF 169chmod +x tmpmultilib 170 171combinations=`initial=/ ./tmpmultilib ${options}` 172 173# If there exceptions, weed them out now 174if [ -n "${exceptions}" ]; then 175 cat >tmpmultilib2 <<\EOF 176#!/bin/sh 177# This recursive script weeds out any combination of multilib 178# switches that should not be generated. The output looks like 179# a list of subdirectory names with leading and trailing slashes. 180 181 for opt in $@; do 182 case "$opt" in 183EOF 184 185 for except in ${exceptions}; do 186 echo " /${except}/) : ;;" >> tmpmultilib2 187 done 188 189cat >>tmpmultilib2 <<\EOF 190 *) echo ${opt};; 191 esac 192 done 193EOF 194 chmod +x tmpmultilib2 195 combinations=`./tmpmultilib2 ${combinations}` 196fi 197 198# Construct a sed pattern which will convert option names to directory 199# names. 200todirnames= 201if [ -n "${dirnames}" ]; then 202 set x ${dirnames} 203 shift 204 for set in ${options}; do 205 for opts in `echo ${set} | sed -e 's|/| |'g`; do 206 patt="/" 207 for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 208 if [ "$1" != "${opt}" ]; then 209 todirnames="${todirnames} -e s|/${opt}/|/${1}/|g" 210 patt="${patt}${1}/" 211 if [ "${patt}" != "/${1}/" ]; then 212 todirnames="${todirnames} -e s|${patt}|/${1}/|g" 213 fi 214 fi 215 done 216 shift 217 done 218 done 219fi 220 221# Construct a sed pattern which will convert option names to OS directory 222# names. 223toosdirnames= 224defaultosdirname= 225if [ -n "${osdirnames}" ]; then 226 set x ${osdirnames} 227 shift 228 while [ $# != 0 ] ; do 229 case "$1" in 230 .=*) 231 defaultosdirname=`echo $1 | sed 's|^.=|:|'` 232 shift 233 ;; 234 *=*) 235 patt=`echo $1 | sed -e 's|=|/$=/|'` 236 toosdirnames="${toosdirnames} -e s=^/${patt}/=" 237 shift 238 ;; 239 *) 240 break 241 ;; 242 esac 243 done 244 245 if [ $# != 0 ]; then 246 for set in ${options}; do 247 for opts in `echo ${set} | sed -e 's|/| |'g`; do 248 patt="/" 249 for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 250 if [ "$1" != "${opt}" ]; then 251 toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g" 252 patt="${patt}${1}/" 253 if [ "${patt}" != "/${1}/" ]; then 254 toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g" 255 fi 256 fi 257 done 258 shift 259 done 260 done 261 fi 262fi 263 264# We need another recursive shell script to correctly handle positive 265# matches. If we are invoked as 266# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2" 267# we must output 268# opt1/opt2 opt1 opt2 269# opt1/opt2 nopt1 opt2 270# opt1/opt2 opt1 nopt2 271# opt1/opt2 nopt1 nopt2 272# In other words, we must output all combinations of matches. 273rm -f tmpmultilib2 274cat >tmpmultilib2 <<\EOF 275#!/bin/sh 276# The positional parameters are a list of matches to consider. 277# ${dirout} is the directory name and ${optout} is the current list of 278# options. 279if [ "$#" = "0" ]; then 280 echo "\"${dirout} ${optout};\"," 281else 282 first=$1 283 shift 284 dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@ 285 l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'` 286 r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'` 287 if expr " ${optout} " : ".* ${l} .*" > /dev/null; then 288 newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'` 289 dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@ 290 fi 291fi 292EOF 293chmod +x tmpmultilib2 294 295# Start with the current directory, which includes only negations. 296optout= 297for set in ${options}; do 298 for opt in `echo ${set} | sed -e 's_[/|]_ _g'`; do 299 optout="${optout} !${opt}" 300 done 301done 302optout=`echo ${optout} | sed -e 's/^ //'` 303echo "\".${defaultosdirname} ${optout};\"," 304 305# Work over the list of combinations. We have to translate each one 306# to use the directory names rather than the option names, we have to 307# include the information in matches, and we have to generate the 308# correct list of options and negations. 309for combo in ${combinations}; do 310 # Use the directory names rather than the option names. 311 if [ -n "${todirnames}" ]; then 312 dirout=`echo ${combo} | sed ${todirnames}` 313 else 314 dirout=`echo ${combo} | sed -e 's/=/-/g'` 315 fi 316 # Remove the leading and trailing slashes. 317 dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'` 318 319 # Use the OS directory names rather than the option names. 320 if [ -n "${toosdirnames}" ]; then 321 osdirout=`echo ${combo} | sed ${toosdirnames}` 322 # Remove the leading and trailing slashes. 323 osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'` 324 if [ "x${enable_multilib}" != xyes ]; then 325 dirout=".:${osdirout}" 326 disable_multilib=yes 327 else 328 case "${osdirout}" in 329 !*) 330 dirout=`echo ${osdirout} | sed 's/^!//'` 331 ;; 332 *) 333 dirout="${dirout}:${osdirout}" 334 ;; 335 esac 336 fi 337 else 338 if [ "x${enable_multilib}" != xyes ]; then 339 # genmultilib with --disable-multilib should be 340 # called with '' '' '' '' '' '' '' no 341 # if MULTILIB_OSDIRNAMES is empty. 342 exit 1 343 fi 344 fi 345 346 # Look through the options. We must output each option that is 347 # present, and negate each option that is not present. 348 optout= 349 for set in ${options}; do 350 setopts=`echo ${set} | sed -e 's_[/|]_ _g'` 351 for opt in ${setopts}; do 352 if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then 353 optout="${optout} ${opt}" 354 else 355 optout="${optout} !${opt}" 356 fi 357 done 358 done 359 optout=`echo ${optout} | sed -e 's/^ //'` 360 361 # Output the line with all appropriate matches. 362 dirout="${dirout}" optout="${optout}" ./tmpmultilib2 363done 364 365# Terminate the list of string. 366echo "NULL" 367echo "};" 368 369# Output all of the matches now as option and that is the same as that, with 370# a semicolon trailer. Include all of the normal options as well. 371# Note, the format of the matches is reversed compared 372# to what we want, so switch them around. 373echo "" 374echo "static const char *const multilib_matches_raw[] = {" 375for match in ${matches}; do 376 l=`echo ${match} | sed -e 's/=.*$//' -e 's/?/=/g'` 377 r=`echo ${match} | sed -e 's/^.*=//' -e 's/?/=/g'` 378 echo "\"${r} ${l};\"," 379done 380for set in ${options}; do 381 for opt in `echo ${set} | sed -e 's_[/|]_ _'g`; do 382 echo "\"${opt} ${opt};\"," 383 done 384done 385echo "NULL" 386echo "};" 387 388# Output the default options now 389echo "" 390echo "static const char *multilib_extra = \"${extra}\";" 391 392# Output the exclusion rules now 393echo "" 394echo "static const char *const multilib_exclusions_raw[] = {" 395for rule in ${exclusions}; do 396 s=`echo ${rule} | sed -e 's,/, ,g'` 397 echo "\"${s};\"," 398done 399echo "NULL" 400echo "};" 401 402# Output the options now 403moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'` 404echo "" 405echo "static const char *multilib_options = \"${moptions}\";" 406 407# Finally output the disable flag if specified 408if [ "x${disable_multilib}" = xyes ]; then 409 echo "" 410 echo "#define DISABLE_MULTILIB 1" 411fi 412 413cd .. 414rm -r tmpmultilib.$$ 415 416exit 0 417