118334Speter#!/bin/sh 218334Speter# Generates multilib.h. 3132718Skan# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002 Free Software Foundation, Inc. 418334Speter 590075Sobrien#This file is part of GCC. 618334Speter 790075Sobrien#GCC is free software; you can redistribute it and/or modify it under 890075Sobrien#the terms of the GNU General Public License as published by the Free 990075Sobrien#Software Foundation; either version 2, or (at your option) any later 1090075Sobrien#version. 1118334Speter 1290075Sobrien#GCC is distributed in the hope that it will be useful, but WITHOUT 1390075Sobrien#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075Sobrien#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrien#for more details. 1618334Speter 1718334Speter#You should have received a copy of the GNU General Public License 1890075Sobrien#along with GCC; see the file COPYING. If not, write to the Free 19169689Skan#Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan#02110-1301, USA. 2118334Speter 2218334Speter# This shell script produces a header file which the gcc driver 2318334Speter# program uses to pick which library to use based on the machine 2418334Speter# specific options that it is given. 2518334Speter 2618334Speter# The first argument is a list of sets of options. The elements in 2718334Speter# the list are separated by spaces. Within an element, the options 2890075Sobrien# are separated by slashes or pipes. No leading dash is used on the 2990075Sobrien# options. 3090075Sobrien# Each option in a set separated by slashes is mutually incompatible 3190075Sobrien# with all other options 3218334Speter# in the set. 3390075Sobrien# Each option in a set separated by pipes will be used for the library 3490075Sobrien# compilation and any of the options in the set will be sufficient 3590075Sobrien# for it to be triggered. 3618334Speter 3718334Speter# The optional second argument is a list of subdirectory names. If 3818334Speter# the second argument is non-empty, there must be as many elements in 3918334Speter# the second argument as there are options in the first argument. The 4018334Speter# elements in the second list are separated by spaces. If the second 4118334Speter# argument is empty, the option names will be used as the directory 4218334Speter# names. 4318334Speter 4418334Speter# The optional third argument is a list of options which are 4518334Speter# identical. The elements in the list are separated by spaces. Each 4618334Speter# element must be of the form OPTION=OPTION. The first OPTION should 4718334Speter# appear in the first argument, and the second should be a synonym for 4818334Speter# it. Question marks are replaced with equal signs in both options. 4918334Speter 5051899Sobrien# The optional fourth argument is a list of multilib directory 5151899Sobrien# combinations that should not be built. 5251899Sobrien 5351899Sobrien# The optional fifth argument is a list of options that should be 5451899Sobrien# used whenever building multilib libraries. 5551899Sobrien 5690075Sobrien# The optional sixth argument is a list of exclusions used internally by 5790075Sobrien# the compiler similar to exceptions. The difference being that exclusions 5890075Sobrien# allow matching default options that genmultilib does not know about and 5990075Sobrien# is done at runtime as opposed to being sorted out at compile time. 6090075Sobrien# Each element in the list is a separate exclusion rule. Each rule is 6190075Sobrien# a list of options (sans preceding '-') separated by a '/'. The options 6290075Sobrien# on the rule are grouped as an AND operation, and all options much match 6390075Sobrien# for the rule to exclude a set. Options can be preceded with a '!' to 6490075Sobrien# match a logical NOT. 6590075Sobrien 66132718Skan# The optional seventh argument is a list of OS subdirectory names. 67132718Skan# The format is either the same as of the second argument, or a set of 68132718Skan# mappings. When it is the same as the second argument, it describes 69132718Skan# the multilib directories using OS conventions, rather than GCC 70132718Skan# conventions. When it is a set of mappings of the form gccdir=osdir, 71132718Skan# the left side gives the GCC convention and the right gives the 72132718Skan# equivalent OS defined location. If the osdir part begins with a !, 73132718Skan# the os directory names are used exclusively. Use the mapping when 74132718Skan# there is no one-to-one equivalence between GCC levels and the OS. 75104752Skan 76104752Skan# The last option should be "yes" if multilibs are enabled. If it is not 77104752Skan# "yes", all GCC multilib dir names will be ".". 78104752Skan 7918334Speter# The output looks like 8018334Speter# #define MULTILIB_MATCHES "\ 8118334Speter# SUBDIRECTORY OPTIONS;\ 8218334Speter# ... 8318334Speter# " 8418334Speter# The SUBDIRECTORY is the subdirectory to use. The OPTIONS are 8518334Speter# multiple options separated by spaces. Each option may start with an 8618334Speter# exclamation point. gcc will consider each line in turn. If none of 8718334Speter# the options beginning with an exclamation point are present, and all 8818334Speter# of the other options are present, that subdirectory will be used. 8918334Speter# The order of the subdirectories is such that they can be created in 9018334Speter# order; that is, a subdirectory is preceded by all its parents. 9118334Speter 9290075Sobrien# Here is an example (this is from the actual sparc64 case): 9390075Sobrien# genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt' 9490075Sobrien# 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*' 95104752Skan# '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany' 96104752Skan# '../lib64 ../lib32 alt' yes 9718334Speter# This produces: 9890075Sobrien# ". !m64 !m32 !mno-app-regs !mcmodel=medany;", 99104752Skan# "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;", 100104752Skan# "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;", 10190075Sobrien# "alt !m64 !m32 mno-app-regs mcmodel=medany;", 10290075Sobrien# "alt !m64 !m32 mno-app-regs !mcmodel=medany;", 10390075Sobrien# "alt !m64 !m32 !mno-app-regs mcmodel=medany;", 104104752Skan# "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;", 105104752Skan# "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;", 106104752Skan# "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;", 10751899Sobrien# 10890075Sobrien# The effect is that `gcc -mno-app-regs' (for example) will append "alt" 10990075Sobrien# to the directory name when searching for libraries or startup files and 11090075Sobrien# `gcc -m32 -mcmodel=medany' (for example) will append "32/alt". Also note 11190075Sobrien# that exclusion above is moot, unless the compiler had a default of -m32, 11290075Sobrien# which would mean that all of the "alt" directories (not the 64/alt ones) 11390075Sobrien# would be ignored (not generated, nor used) since the exclusion also 11490075Sobrien# matches the multilib_default args. 11518334Speter 11618334Speter# Copy the positional parameters into variables. 11718334Speteroptions=$1 11818334Speterdirnames=$2 11918334Spetermatches=$3 12051899Sobrienexceptions=$4 12151899Sobrienextra=$5 12290075Sobrienexclusions=$6 123104752Skanosdirnames=$7 124104752Skanenable_multilib=$8 12518334Speter 12690075Sobrienecho "static const char *const multilib_raw[] = {" 12751899Sobrien 128132718Skanmkdir tmpmultilib.$$ || exit 1 129132718Skan# Use cd ./foo to avoid CDPATH output. 130132718Skancd ./tmpmultilib.$$ || exit 1 131132718Skan 13218334Speter# What we want to do is select all combinations of the sets in 13318334Speter# options. Each combination which includes a set of mutually 13418334Speter# exclusive options must then be output multiple times, once for each 13518334Speter# item in the set. Selecting combinations is a recursive process. 13618334Speter# Since not all versions of sh support functions, we achieve recursion 13718334Speter# by creating a temporary shell script which invokes itself. 13818334Speterrm -f tmpmultilib 13918334Spetercat >tmpmultilib <<\EOF 14018334Speter#!/bin/sh 14118334Speter# This recursive script basically outputs all combinations of its 14218334Speter# input arguments, handling mutually exclusive sets of options by 14318334Speter# repetition. When the script is called, ${initial} is the list of 14418334Speter# options which should appear before all combinations this will 14518334Speter# output. The output looks like a list of subdirectory names with 14618334Speter# leading and trailing slashes. 14718334Speterif [ "$#" != "0" ]; then 14818334Speter first=$1 14918334Speter shift 15090075Sobrien case "$first" in 15190075Sobrien *\|*) 15290075Sobrien all=${initial}`echo $first | sed -e 's_|_/_'g` 15390075Sobrien first=`echo $first | sed -e 's_|_ _'g` 15490075Sobrien echo ${all}/ 15590075Sobrien initial="${initial}${all}/" ./tmpmultilib $@ 15690075Sobrien ./tmpmultilib $first $@ | grep -v "^${all}" 15790075Sobrien ;; 15890075Sobrien *) 15990075Sobrien for opt in `echo $first | sed -e 's|/| |'g`; do 16090075Sobrien echo ${initial}${opt}/ 16190075Sobrien done 16290075Sobrien ./tmpmultilib $@ 16390075Sobrien for opt in `echo $first | sed -e 's|/| |'g`; do 16490075Sobrien initial="${initial}${opt}/" ./tmpmultilib $@ 16590075Sobrien done 16690075Sobrien esac 16718334Speterfi 16818334SpeterEOF 16918334Speterchmod +x tmpmultilib 17018334Speter 17118334Spetercombinations=`initial=/ ./tmpmultilib ${options}` 17218334Speter 17351899Sobrien# If there exceptions, weed them out now 17451899Sobrienif [ -n "${exceptions}" ]; then 17551899Sobrien cat >tmpmultilib2 <<\EOF 17651899Sobrien#!/bin/sh 17751899Sobrien# This recursive script weeds out any combination of multilib 17851899Sobrien# switches that should not be generated. The output looks like 17951899Sobrien# a list of subdirectory names with leading and trailing slashes. 18051899Sobrien 18151899Sobrien for opt in $@; do 18251899Sobrien case "$opt" in 18351899SobrienEOF 18451899Sobrien 18551899Sobrien for except in ${exceptions}; do 18651899Sobrien echo " /${except}/) : ;;" >> tmpmultilib2 18751899Sobrien done 18851899Sobrien 18951899Sobriencat >>tmpmultilib2 <<\EOF 19051899Sobrien *) echo ${opt};; 19151899Sobrien esac 19251899Sobrien done 19351899SobrienEOF 19451899Sobrien chmod +x tmpmultilib2 19551899Sobrien combinations=`./tmpmultilib2 ${combinations}` 19651899Sobrienfi 19751899Sobrien 19818334Speter# Construct a sed pattern which will convert option names to directory 19918334Speter# names. 20018334Spetertodirnames= 20118334Speterif [ -n "${dirnames}" ]; then 20218334Speter set x ${dirnames} 20318334Speter shift 20418334Speter for set in ${options}; do 20590075Sobrien for opts in `echo ${set} | sed -e 's|/| |'g`; do 20690075Sobrien patt="/" 20790075Sobrien for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 20890075Sobrien if [ "$1" != "${opt}" ]; then 20990075Sobrien todirnames="${todirnames} -e s|/${opt}/|/${1}/|g" 21090075Sobrien patt="${patt}${1}/" 21190075Sobrien if [ "${patt}" != "/${1}/" ]; then 21290075Sobrien todirnames="${todirnames} -e s|${patt}|/${1}/|g" 21390075Sobrien fi 21490075Sobrien fi 21590075Sobrien done 21618334Speter shift 21718334Speter done 21818334Speter done 21918334Speterfi 22018334Speter 221104752Skan# Construct a sed pattern which will convert option names to OS directory 222104752Skan# names. 223104752Skantoosdirnames= 224132718Skandefaultosdirname= 225104752Skanif [ -n "${osdirnames}" ]; then 226104752Skan set x ${osdirnames} 227104752Skan shift 228132718Skan while [ $# != 0 ] ; do 229132718Skan case "$1" in 230132718Skan .=*) 231132718Skan defaultosdirname=`echo $1 | sed 's|^.=|:|'` 232132718Skan shift 233132718Skan ;; 234132718Skan *=*) 235132718Skan patt=`echo $1 | sed -e 's|=|/$=/|'` 236132718Skan toosdirnames="${toosdirnames} -e s=^/${patt}/=" 237132718Skan shift 238132718Skan ;; 239132718Skan *) 240132718Skan break 241132718Skan ;; 242132718Skan esac 243132718Skan done 244132718Skan 245132718Skan if [ $# != 0 ]; then 246132718Skan for set in ${options}; do 247132718Skan for opts in `echo ${set} | sed -e 's|/| |'g`; do 248132718Skan patt="/" 249132718Skan for opt in `echo ${opts} | sed -e 's_|_ _'g`; do 250132718Skan if [ "$1" != "${opt}" ]; then 251132718Skan toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g" 252132718Skan patt="${patt}${1}/" 253132718Skan if [ "${patt}" != "/${1}/" ]; then 254132718Skan toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g" 255132718Skan fi 256104752Skan fi 257132718Skan done 258132718Skan shift 259104752Skan done 260104752Skan done 261132718Skan fi 262104752Skanfi 263104752Skan 26418334Speter# We need another recursive shell script to correctly handle positive 26518334Speter# matches. If we are invoked as 26618334Speter# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2" 26718334Speter# we must output 26818334Speter# opt1/opt2 opt1 opt2 26918334Speter# opt1/opt2 nopt1 opt2 27018334Speter# opt1/opt2 opt1 nopt2 27118334Speter# opt1/opt2 nopt1 nopt2 27218334Speter# In other words, we must output all combinations of matches. 27318334Speterrm -f tmpmultilib2 27418334Spetercat >tmpmultilib2 <<\EOF 27518334Speter#!/bin/sh 27618334Speter# The positional parameters are a list of matches to consider. 27718334Speter# ${dirout} is the directory name and ${optout} is the current list of 27818334Speter# options. 27918334Speterif [ "$#" = "0" ]; then 28051899Sobrien echo "\"${dirout} ${optout};\"," 28118334Speterelse 28218334Speter first=$1 28318334Speter shift 28418334Speter dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@ 28518334Speter l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'` 28618334Speter r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'` 28718334Speter if expr " ${optout} " : ".* ${l} .*" > /dev/null; then 28818334Speter newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'` 28918334Speter dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@ 29018334Speter fi 29118334Speterfi 29218334SpeterEOF 29318334Speterchmod +x tmpmultilib2 29418334Speter 29518334Speter# Start with the current directory, which includes only negations. 29618334Speteroptout= 29718334Speterfor set in ${options}; do 29890075Sobrien for opt in `echo ${set} | sed -e 's_[/|]_ _g'`; do 29918334Speter optout="${optout} !${opt}" 30018334Speter done 30118334Speterdone 30218334Speteroptout=`echo ${optout} | sed -e 's/^ //'` 303132718Skanecho "\".${defaultosdirname} ${optout};\"," 30418334Speter 30518334Speter# Work over the list of combinations. We have to translate each one 30618334Speter# to use the directory names rather than the option names, we have to 30718334Speter# include the information in matches, and we have to generate the 30818334Speter# correct list of options and negations. 30918334Speterfor combo in ${combinations}; do 31018334Speter # Use the directory names rather than the option names. 31118334Speter if [ -n "${todirnames}" ]; then 31218334Speter dirout=`echo ${combo} | sed ${todirnames}` 31318334Speter else 314169689Skan dirout=`echo ${combo} | sed -e 's/=/-/g'` 31518334Speter fi 31618334Speter # Remove the leading and trailing slashes. 31718334Speter dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'` 31818334Speter 319104752Skan # Use the OS directory names rather than the option names. 320104752Skan if [ -n "${toosdirnames}" ]; then 321104752Skan osdirout=`echo ${combo} | sed ${toosdirnames}` 322104752Skan # Remove the leading and trailing slashes. 323104752Skan osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'` 324104752Skan if [ "x${enable_multilib}" != xyes ]; then 325104752Skan dirout=".:${osdirout}" 326132718Skan disable_multilib=yes 327104752Skan else 328132718Skan case "${osdirout}" in 329132718Skan !*) 330132718Skan dirout=`echo ${osdirout} | sed 's/^!//'` 331132718Skan ;; 332132718Skan *) 333132718Skan dirout="${dirout}:${osdirout}" 334132718Skan ;; 335132718Skan esac 336104752Skan fi 337104752Skan else 338104752Skan if [ "x${enable_multilib}" != xyes ]; then 339104752Skan # genmultilib with --disable-multilib should be 340104752Skan # called with '' '' '' '' '' '' '' no 341104752Skan # if MULTILIB_OSDIRNAMES is empty. 342104752Skan exit 1 343104752Skan fi 344104752Skan fi 345104752Skan 34618334Speter # Look through the options. We must output each option that is 34718334Speter # present, and negate each option that is not present. 34818334Speter optout= 34918334Speter for set in ${options}; do 35090075Sobrien setopts=`echo ${set} | sed -e 's_[/|]_ _g'` 35118334Speter for opt in ${setopts}; do 35218334Speter if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then 35318334Speter optout="${optout} ${opt}" 35418334Speter else 35518334Speter optout="${optout} !${opt}" 35618334Speter fi 35718334Speter done 35818334Speter done 35918334Speter optout=`echo ${optout} | sed -e 's/^ //'` 36018334Speter 36118334Speter # Output the line with all appropriate matches. 36251899Sobrien dirout="${dirout}" optout="${optout}" ./tmpmultilib2 36318334Speterdone 36418334Speter 36551899Sobrien# Terminate the list of string. 36651899Sobrienecho "NULL" 36751899Sobrienecho "};" 36851899Sobrien 36951899Sobrien# Output all of the matches now as option and that is the same as that, with 37051899Sobrien# a semicolon trailer. Include all of the normal options as well. 37151899Sobrien# Note, the format of the matches is reversed compared 37251899Sobrien# to what we want, so switch them around. 37351899Sobrienecho "" 37490075Sobrienecho "static const char *const multilib_matches_raw[] = {" 37551899Sobrienfor match in ${matches}; do 37651899Sobrien l=`echo ${match} | sed -e 's/=.*$//' -e 's/?/=/g'` 37751899Sobrien r=`echo ${match} | sed -e 's/^.*=//' -e 's/?/=/g'` 37851899Sobrien echo "\"${r} ${l};\"," 37951899Sobriendone 38051899Sobrienfor set in ${options}; do 38190075Sobrien for opt in `echo ${set} | sed -e 's_[/|]_ _'g`; do 38251899Sobrien echo "\"${opt} ${opt};\"," 38351899Sobrien done 38451899Sobriendone 38551899Sobrienecho "NULL" 38651899Sobrienecho "};" 38751899Sobrien 38851899Sobrien# Output the default options now 38951899Sobrienecho "" 39090075Sobrienecho "static const char *multilib_extra = \"${extra}\";" 39190075Sobrien 39290075Sobrien# Output the exclusion rules now 39390075Sobrienecho "" 39490075Sobrienecho "static const char *const multilib_exclusions_raw[] = {" 39590075Sobrienfor rule in ${exclusions}; do 39690075Sobrien s=`echo ${rule} | sed -e 's,/, ,g'` 39790075Sobrien echo "\"${s};\"," 39890075Sobriendone 39990075Sobrienecho "NULL" 40090075Sobrienecho "};" 40190075Sobrien 402104752Skan# Output the options now 403104752Skanmoptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'` 404104752Skanecho "" 405104752Skanecho "static const char *multilib_options = \"${moptions}\";" 406104752Skan 407132718Skan# Finally output the disable flag if specified 408132718Skanif [ "x${disable_multilib}" = xyes ]; then 409132718Skan echo "" 410132718Skan echo "#define DISABLE_MULTILIB 1" 411132718Skanfi 41218334Speter 413132718Skancd .. 414132718Skanrm -r tmpmultilib.$$ 415132718Skan 41618334Speterexit 0 417