genmultilib revision 1.1.1.1.8.2
1#!/bin/sh 2# Generates multilib.h. 3# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2007 4# Free Software Foundation, Inc. 5 6#This file is part of GCC. 7 8#GCC is free software; you can redistribute it and/or modify it under 9#the terms of the GNU General Public License as published by the Free 10#Software Foundation; either version 3, or (at your option) any later 11#version. 12 13#GCC is distributed in the hope that it will be useful, but WITHOUT 14#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16#for more details. 17 18#You should have received a copy of the GNU General Public License 19#along with GCC; see the file COPYING3. If not see 20#<http://www.gnu.org/licenses/>. 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#!${CONFIG_SHELL:-/bin/sh} 141EOF 142cat >>tmpmultilib <<\EOF 143# This recursive script basically outputs all combinations of its 144# input arguments, handling mutually exclusive sets of options by 145# repetition. When the script is called, ${initial} is the list of 146# options which should appear before all combinations this will 147# output. The output looks like a list of subdirectory names with 148# leading and trailing slashes. 149if [ "$#" != "0" ]; then 150 first=$1 151 shift 152 case "$first" in 153 *\|*) 154 all=${initial}`echo $first | sed -e 's_|_/_'g` 155 first=`echo $first | sed -e 's_|_ _'g` 156 echo ${all}/ 157 initial="${initial}${all}/" ./tmpmultilib $@ 158 ./tmpmultilib $first $@ | grep -v "^${all}" 159 ;; 160 *) 161 for opt in `echo $first | sed -e 's|/| |'g`; do 162 echo ${initial}${opt}/ 163 done 164 ./tmpmultilib $@ 165 for opt in `echo $first | sed -e 's|/| |'g`; do 166 initial="${initial}${opt}/" ./tmpmultilib $@ 167 done 168 esac 169fi 170EOF 171chmod +x tmpmultilib 172 173combinations=`initial=/ ./tmpmultilib ${options}` 174 175# If there exceptions, weed them out now 176if [ -n "${exceptions}" ]; then 177 cat >tmpmultilib2 <<EOF 178#!${CONFIG_SHELL:-/bin/sh} 179EOF 180 cat >>tmpmultilib2 <<\EOF 181# This recursive script weeds out any combination of multilib 182# switches that should not be generated. The output looks like 183# a list of subdirectory names with leading and trailing slashes. 184 185 for opt in $@; do 186 case "$opt" in 187EOF 188 189 for except in ${exceptions}; do 190 echo " /${except}/) : ;;" >> tmpmultilib2 191 done 192 193cat >>tmpmultilib2 <<\EOF 194 *) echo ${opt};; 195 esac 196 done 197EOF 198 chmod +x tmpmultilib2 199 combinations=`./tmpmultilib2 ${combinations}` 200fi 201 202# Construct a sed pattern which will convert option names to directory 203# names. 204todirnames= 205if [ -n "${dirnames}" ]; then 206 set x ${dirnames} 207 shift 208 for set in ${options}; do 209 for opts in `echo ${set} | sed -e 's|/| |'g`; do 210 patt="/" 211 for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 212 if [ "$1" != "${opt}" ]; then 213 todirnames="${todirnames} -e s|/${opt}/|/${1}/|g" 214 patt="${patt}${1}/" 215 if [ "${patt}" != "/${1}/" ]; then 216 todirnames="${todirnames} -e s|${patt}|/${1}/|g" 217 fi 218 fi 219 done 220 shift 221 done 222 done 223fi 224 225# Construct a sed pattern which will convert option names to OS directory 226# names. 227toosdirnames= 228defaultosdirname= 229if [ -n "${osdirnames}" ]; then 230 set x ${osdirnames} 231 shift 232 while [ $# != 0 ] ; do 233 case "$1" in 234 .=*) 235 defaultosdirname=`echo $1 | sed 's|^.=|:|'` 236 shift 237 ;; 238 *=*) 239 patt=`echo $1 | sed -e 's|=|/$=/|'` 240 toosdirnames="${toosdirnames} -e s=^/${patt}/=" 241 shift 242 ;; 243 *) 244 break 245 ;; 246 esac 247 done 248 249 if [ $# != 0 ]; then 250 for set in ${options}; do 251 for opts in `echo ${set} | sed -e 's|/| |'g`; do 252 patt="/" 253 for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 254 if [ "$1" != "${opt}" ]; then 255 toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g" 256 patt="${patt}${1}/" 257 if [ "${patt}" != "/${1}/" ]; then 258 toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g" 259 fi 260 fi 261 done 262 shift 263 done 264 done 265 fi 266fi 267 268# We need another recursive shell script to correctly handle positive 269# matches. If we are invoked as 270# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2" 271# we must output 272# opt1/opt2 opt1 opt2 273# opt1/opt2 nopt1 opt2 274# opt1/opt2 opt1 nopt2 275# opt1/opt2 nopt1 nopt2 276# In other words, we must output all combinations of matches. 277rm -f tmpmultilib2 278cat >tmpmultilib2 <<EOF 279#!${CONFIG_SHELL:-/bin/sh} 280EOF 281cat >>tmpmultilib2 <<\EOF 282# The positional parameters are a list of matches to consider. 283# ${dirout} is the directory name and ${optout} is the current list of 284# options. 285if [ "$#" = "0" ]; then 286 echo "\"${dirout} ${optout};\"," 287else 288 first=$1 289 shift 290 dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@ 291 l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'` 292 r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'` 293 if expr " ${optout} " : ".* ${l} .*" > /dev/null; then 294 newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'` 295 dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@ 296 fi 297fi 298EOF 299chmod +x tmpmultilib2 300 301# Start with the current directory, which includes only negations. 302optout= 303for set in ${options}; do 304 for opt in `echo ${set} | sed -e 's_[/|]_ _g'`; do 305 optout="${optout} !${opt}" 306 done 307done 308optout=`echo ${optout} | sed -e 's/^ //'` 309echo "\".${defaultosdirname} ${optout};\"," 310 311# Work over the list of combinations. We have to translate each one 312# to use the directory names rather than the option names, we have to 313# include the information in matches, and we have to generate the 314# correct list of options and negations. 315for combo in ${combinations}; do 316 # Use the directory names rather than the option names. 317 if [ -n "${todirnames}" ]; then 318 dirout=`echo ${combo} | sed ${todirnames}` 319 else 320 dirout=`echo ${combo} | sed -e 's/=/-/g'` 321 fi 322 # Remove the leading and trailing slashes. 323 dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'` 324 325 # Use the OS directory names rather than the option names. 326 if [ -n "${toosdirnames}" ]; then 327 osdirout=`echo ${combo} | sed ${toosdirnames}` 328 # Remove the leading and trailing slashes. 329 osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'` 330 if [ "x${enable_multilib}" != xyes ]; then 331 dirout=".:${osdirout}" 332 disable_multilib=yes 333 else 334 case "${osdirout}" in 335 !*) 336 dirout=`echo ${osdirout} | sed 's/^!//'` 337 ;; 338 *) 339 dirout="${dirout}:${osdirout}" 340 ;; 341 esac 342 fi 343 else 344 if [ "x${enable_multilib}" != xyes ]; then 345 # genmultilib with --disable-multilib should be 346 # called with '' '' '' '' '' '' '' no 347 # if MULTILIB_OSDIRNAMES is empty. 348 exit 1 349 fi 350 fi 351 352 # Look through the options. We must output each option that is 353 # present, and negate each option that is not present. 354 optout= 355 for set in ${options}; do 356 setopts=`echo ${set} | sed -e 's_[/|]_ _g'` 357 for opt in ${setopts}; do 358 if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then 359 optout="${optout} ${opt}" 360 else 361 optout="${optout} !${opt}" 362 fi 363 done 364 done 365 optout=`echo ${optout} | sed -e 's/^ //'` 366 367 # Output the line with all appropriate matches. 368 dirout="${dirout}" optout="${optout}" ./tmpmultilib2 369done 370 371# Terminate the list of string. 372echo "NULL" 373echo "};" 374 375# Output all of the matches now as option and that is the same as that, with 376# a semicolon trailer. Include all of the normal options as well. 377# Note, the format of the matches is reversed compared 378# to what we want, so switch them around. 379echo "" 380echo "static const char *const multilib_matches_raw[] = {" 381for match in ${matches}; do 382 l=`echo ${match} | sed -e 's/=.*$//' -e 's/?/=/g'` 383 r=`echo ${match} | sed -e 's/^.*=//' -e 's/?/=/g'` 384 echo "\"${r} ${l};\"," 385done 386for set in ${options}; do 387 for opt in `echo ${set} | sed -e 's_[/|]_ _'g`; do 388 echo "\"${opt} ${opt};\"," 389 done 390done 391echo "NULL" 392echo "};" 393 394# Output the default options now 395echo "" 396echo "static const char *multilib_extra = \"${extra}\";" 397 398# Output the exclusion rules now 399echo "" 400echo "static const char *const multilib_exclusions_raw[] = {" 401for rule in ${exclusions}; do 402 s=`echo ${rule} | sed -e 's,/, ,g'` 403 echo "\"${s};\"," 404done 405echo "NULL" 406echo "};" 407 408# Output the options now 409moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'` 410echo "" 411echo "static const char *multilib_options = \"${moptions}\";" 412 413# Finally output the disable flag if specified 414if [ "x${disable_multilib}" = xyes ]; then 415 echo "" 416 echo "#define DISABLE_MULTILIB 1" 417fi 418 419cd .. 420rm -r tmpmultilib.$$ 421 422exit 0 423