genmultilib revision 18334
118334Speter#!/bin/sh 218334Speter# Generates multilib.h. 318334Speter# Copyright (C) 1994, 1995 Free Software Foundation, Inc. 418334Speter 518334Speter#This file is part of GNU CC. 618334Speter 718334Speter#GNU CC is free software; you can redistribute it and/or modify 818334Speter#it under the terms of the GNU General Public License as published by 918334Speter#the Free Software Foundation; either version 2, or (at your option) 1018334Speter#any later version. 1118334Speter 1218334Speter#GNU CC is distributed in the hope that it will be useful, 1318334Speter#but WITHOUT ANY WARRANTY; without even the implied warranty of 1418334Speter#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1518334Speter#GNU General Public License for more details. 1618334Speter 1718334Speter#You should have received a copy of the GNU General Public License 1818334Speter#along with GNU CC; see the file COPYING. If not, write to 1918334Speter#the Free Software Foundation, 59 Temple Place - Suite 330, 2018334Speter#Boston, MA 02111-1307, 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 2818334Speter# are separated by slashes. No leading dash is used on the options. 2918334Speter# Each option in a set is mutually incompatible with all other options 3018334Speter# in the set. 3118334Speter 3218334Speter# The optional second argument is a list of subdirectory names. If 3318334Speter# the second argument is non-empty, there must be as many elements in 3418334Speter# the second argument as there are options in the first argument. The 3518334Speter# elements in the second list are separated by spaces. If the second 3618334Speter# argument is empty, the option names will be used as the directory 3718334Speter# names. 3818334Speter 3918334Speter# The optional third argument is a list of options which are 4018334Speter# identical. The elements in the list are separated by spaces. Each 4118334Speter# element must be of the form OPTION=OPTION. The first OPTION should 4218334Speter# appear in the first argument, and the second should be a synonym for 4318334Speter# it. Question marks are replaced with equal signs in both options. 4418334Speter 4518334Speter# The output looks like 4618334Speter# #define MULTILIB_MATCHES "\ 4718334Speter# SUBDIRECTORY OPTIONS;\ 4818334Speter# ... 4918334Speter# " 5018334Speter# The SUBDIRECTORY is the subdirectory to use. The OPTIONS are 5118334Speter# multiple options separated by spaces. Each option may start with an 5218334Speter# exclamation point. gcc will consider each line in turn. If none of 5318334Speter# the options beginning with an exclamation point are present, and all 5418334Speter# of the other options are present, that subdirectory will be used. 5518334Speter# The order of the subdirectories is such that they can be created in 5618334Speter# order; that is, a subdirectory is preceded by all its parents. 5718334Speter 5818334Speter# Here is a example (this is simplified from the actual 680x0 case): 5918334Speter# genmultilib "m68000/m68020 msoft-float" "m68000 m68020 msoft-float" 6018334Speter# "m68000=mc68000" 6118334Speter# This produces: 6218334Speter# #define MULTILIB_SELECT "\ 6318334Speter# . !m68000 !mc68000 !m68020 !msoft-float;\ 6418334Speter# m68000 m68000 !m68020 !msoft-float;\ 6518334Speter# m68000 mc60000 !m68020 !msoft-float;\ 6618334Speter# m68020 !m68000 !mc68000 m68020 !msoft-float;\ 6718334Speter# msoft-float !m68000 !mc68000 !m68020 msoft-float;\ 6818334Speter# m68000/msoft-float m68000 !m68020 msoft-float;\ 6918334Speter# m68000/msoft-float mc68000 !m68020 msoft-float;\ 7018334Speter# m68020/msoft-float !m68000 !mc68000 m68020 msoft-float;\ 7118334Speter# " 7218334Speter# The effect is that `gcc -msoft-float' (for example) will append 7318334Speter# msoft-float to the directory name when searching for libraries or 7418334Speter# startup files, and `gcc -m68000 -msoft-float' (for example) will 7518334Speter# append m68000/msoft-float. 7618334Speter 7718334Speter# Copy the positional parameters into variables. 7818334Speteroptions=$1 7918334Speterdirnames=$2 8018334Spetermatches=$3 8118334Speter 8218334Speter# What we want to do is select all combinations of the sets in 8318334Speter# options. Each combination which includes a set of mutually 8418334Speter# exclusive options must then be output multiple times, once for each 8518334Speter# item in the set. Selecting combinations is a recursive process. 8618334Speter# Since not all versions of sh support functions, we achieve recursion 8718334Speter# by creating a temporary shell script which invokes itself. 8818334Speterrm -f tmpmultilib 8918334Spetercat >tmpmultilib <<\EOF 9018334Speter#!/bin/sh 9118334Speter# This recursive script basically outputs all combinations of its 9218334Speter# input arguments, handling mutually exclusive sets of options by 9318334Speter# repetition. When the script is called, ${initial} is the list of 9418334Speter# options which should appear before all combinations this will 9518334Speter# output. The output looks like a list of subdirectory names with 9618334Speter# leading and trailing slashes. 9718334Speterif [ "$#" != "0" ]; then 9818334Speter first=$1 9918334Speter shift 10018334Speter for opt in `echo $first | sed -e 's|/| |'g`; do 10118334Speter echo ${initial}${opt}/ 10218334Speter done 10318334Speter ./tmpmultilib $@ 10418334Speter for opt in `echo $first | sed -e 's|/| |'g`; do 10518334Speter initial="${initial}${opt}/" ./tmpmultilib $@ 10618334Speter done 10718334Speterfi 10818334SpeterEOF 10918334Speterchmod +x tmpmultilib 11018334Speter 11118334Spetercombinations=`initial=/ ./tmpmultilib ${options}` 11218334Speter 11318334Speterrm -f tmpmultilib 11418334Speter 11518334Speter# Construct a sed pattern which will convert option names to directory 11618334Speter# names. 11718334Spetertodirnames= 11818334Speterif [ -n "${dirnames}" ]; then 11918334Speter set x ${dirnames} 12018334Speter shift 12118334Speter for set in ${options}; do 12218334Speter for opt in `echo ${set} | sed -e 's|/| |'g`; do 12318334Speter if [ "$1" != "${opt}" ]; then 12418334Speter todirnames="${todirnames} -e s|/${opt}/|/${1}/|g" 12518334Speter fi 12618334Speter shift 12718334Speter done 12818334Speter done 12918334Speterfi 13018334Speter 13118334Speter# Construct a sed pattern which will add negations based on the 13218334Speter# matches. The semicolons are easier than getting the shell to accept 13318334Speter# quoted spaces when expanding a variable. 13418334Spetermatchnegations= 13518334Speterfor i in ${matches}; do 13618334Speter l=`echo $i | sed -e 's/=.*$//' -e 's/?/=/g'` 13718334Speter r=`echo $i | sed -e 's/^.*=//' -e 's/?/=/g'` 13818334Speter matchnegations="${matchnegations} -e s/;!${l};/;!${l};!${r};/" 13918334Speterdone 14018334Speter 14118334Speter# We need another recursive shell script to correctly handle positive 14218334Speter# matches. If we are invoked as 14318334Speter# genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2" 14418334Speter# we must output 14518334Speter# opt1/opt2 opt1 opt2 14618334Speter# opt1/opt2 nopt1 opt2 14718334Speter# opt1/opt2 opt1 nopt2 14818334Speter# opt1/opt2 nopt1 nopt2 14918334Speter# In other words, we must output all combinations of matches. 15018334Speterrm -f tmpmultilib2 15118334Spetercat >tmpmultilib2 <<\EOF 15218334Speter#!/bin/sh 15318334Speter# The positional parameters are a list of matches to consider. 15418334Speter# ${dirout} is the directory name and ${optout} is the current list of 15518334Speter# options. 15618334Speterif [ "$#" = "0" ]; then 15718334Speter echo "${dirout} ${optout};\\" 15818334Speterelse 15918334Speter first=$1 16018334Speter shift 16118334Speter dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@ 16218334Speter l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'` 16318334Speter r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'` 16418334Speter if expr " ${optout} " : ".* ${l} .*" > /dev/null; then 16518334Speter newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'` 16618334Speter dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@ 16718334Speter fi 16818334Speterfi 16918334SpeterEOF 17018334Speterchmod +x tmpmultilib2 17118334Speter 17218334Speter# We are ready to start output. 17318334Speterecho '#define MULTILIB_SELECT "\' 17418334Speter 17518334Speter# Start with the current directory, which includes only negations. 17618334Speteroptout= 17718334Speterfor set in ${options}; do 17818334Speter for opt in `echo ${set} | sed -e 's|/| |'g`; do 17918334Speter optout="${optout} !${opt}" 18018334Speter done 18118334Speterdone 18218334Speteroptout=`echo ${optout} | sed -e 's/^ //'` 18318334Speterif [ -n "${matchnegations}" ]; then 18418334Speter optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'` 18518334Speterfi 18618334Speterecho ". ${optout};\\" 18718334Speter 18818334Speter# Work over the list of combinations. We have to translate each one 18918334Speter# to use the directory names rather than the option names, we have to 19018334Speter# include the information in matches, and we have to generate the 19118334Speter# correct list of options and negations. 19218334Speterfor combo in ${combinations}; do 19318334Speter # Use the directory names rather than the option names. 19418334Speter if [ -n "${todirnames}" ]; then 19518334Speter dirout=`echo ${combo} | sed ${todirnames}` 19618334Speter else 19718334Speter dirout=${combo} 19818334Speter fi 19918334Speter # Remove the leading and trailing slashes. 20018334Speter dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'` 20118334Speter 20218334Speter # Look through the options. We must output each option that is 20318334Speter # present, and negate each option that is not present. 20418334Speter optout= 20518334Speter for set in ${options}; do 20618334Speter setopts=`echo ${set} | sed -e 's|/| |g'` 20718334Speter for opt in ${setopts}; do 20818334Speter if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then 20918334Speter optout="${optout} ${opt}" 21018334Speter else 21118334Speter optout="${optout} !${opt}" 21218334Speter fi 21318334Speter done 21418334Speter done 21518334Speter optout=`echo ${optout} | sed -e 's/^ //'` 21618334Speter 21718334Speter # Add any negations of matches. 21818334Speter if [ -n "${matchnegations}" ]; then 21918334Speter optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'` 22018334Speter fi 22118334Speter 22218334Speter # Output the line with all appropriate matches. 22318334Speter dirout="${dirout}" optout="${optout}" ./tmpmultilib2 ${matches} 22418334Speterdone 22518334Speter 22618334Speterrm -f tmpmultilib2 22718334Speter 22818334Speter# That's it. 22918334Speterecho '"' 23018334Speter 23118334Speterexit 0 232