1#!/bin/sh
2# script to set MCPP to be called from gcc
3# ./set_mcpp.sh $gcc_path $gcc_maj_ver $gcc_min_ver $cpp_call $CC
4#       $CXX x$CPPFLAGS x$EXEEXT $LN_S $inc_dir $host_system $cpu $target_cc
5
6gcc_maj_ver=$2
7gcc_min_ver=$3
8cpp_call=$4
9CC=$5
10CXX=$6
11CPPFLAGS=`echo $7 | sed 's/^x//'`
12LN_S=$9
13inc_dir=${10}
14host_system=${11}
15cpu=${12}
16if test $host_system = SYS_MAC; then
17    target_cc=${13}
18    target=`echo $target_cc | sed 's/-gcc.*$//'`
19fi
20cpp_name=`echo $cpp_call | sed 's,.*/,,'`
21cpp_path=`echo $cpp_call | sed "s,/$cpp_name,,"`
22gcc_path=`echo $1 | sed "s,/${CC}\$,,"`
23
24# remove ".exe" or such
25EXEEXT=`echo $8 | sed 's/^x//'`
26if test x$EXEEXT != x; then
27    cpp_base=`echo $cpp_name | sed "s/${EXEEXT}//"`
28else
29    cpp_base=$cpp_name
30fi
31
32if test $host_system = SYS_MINGW && test ! -f cc1$EXEEXT; then
33    ## cc1.exe has not yet compiled
34    echo "  first do 'make COMPILER=GNUC mcpp cc1'; then do 'make COMPILER=GNUC install'"
35    exit 1
36fi
37if test x$cpp_base = xcc1; then
38    # for GCC V.3.3 and later
39    no_m64=0
40else
41    no_m64=1
42fi
43
44gen_headers() {
45    echo "  mkdir -p $hdir"
46    mkdir -p $hdir
47    if test ! -f $hdir/gcc$gcc_maj_ver${gcc_min_ver}_predef_std.h; then
48        echo "  generating g*.h header files"
49        $CC $CPPFLAGS -E -xc $arg -dM /dev/null | sort |        \
50                grep ' *#define *_'                             \
51                > $hdir/gcc$gcc_maj_ver${gcc_min_ver}_predef_std.h
52        $CC $CPPFLAGS -E -xc $arg -dM /dev/null | sort |        \
53                grep -E ' *#define *[A-Za-z]+'                  \
54                > $hdir/gcc$gcc_maj_ver${gcc_min_ver}_predef_old.h
55        $CXX $CPPFLAGS -E -xc++ $arg -dM /dev/null | sort |     \
56                grep ' *#define *_'                             \
57                > $hdir/gxx$gcc_maj_ver${gcc_min_ver}_predef_std.h
58        $CXX $CPPFLAGS -E -xc++ $arg -dM /dev/null | sort |     \
59                grep -E ' *#define *[A-Za-z]+'                  \
60                > $hdir/gxx$gcc_maj_ver${gcc_min_ver}_predef_old.h
61    fi
62}
63
64cwd=`pwd`
65echo "  cd $inc_dir"
66cd $inc_dir
67
68if test $cpu = i386 || test $cpu = x86_64; then
69    cpu32=i386
70    cpu64=x86_64
71else
72    if test $cpu = ppc || $cpu = ppc64; then
73        cpu32=ppc
74        cpu64=ppc64
75    fi
76fi
77
78arch_headers() {
79    for arch in $cpu32 $cpu64
80    do                              ## generate headers for 2 architectures
81        hdir=${idir}-$arch
82        if test $host_system = SYS_MAC; then
83            arg="-arch $arch"
84        else
85            if test $arch = $cpu; then
86                arg="$ar"
87            else
88                if test $host_system = SYS_MINGW || test $no_m64; then
89                    continue;
90                fi
91                if test $cpu = $cpu64; then
92                    arg="$ar -m32"
93                else
94                    arg="$ar -m64"
95                fi
96                # Test if the architecture is supported.
97                $CC -E -xc $arg /dev/null > /dev/null
98                if test $? != 0; then
99                    continue
100                fi
101            fi
102        fi
103        gen_headers
104    done
105}
106
107idir=mcpp-gcc
108ar=
109arch_headers
110
111if test $host_system = SYS_CYGWIN; then
112    ## CYGWIN has 'mingw' include directory for '-mno-cygwin' option
113    idir=mingw/mcpp-gcc
114    ar="-mno-cygwin"
115    arch_headers
116fi
117
118# write shell-script so that call of 'cpp0', 'cc1 -E' or so is replaced to
119# call of mcpp
120echo "  cd $cpp_path"
121cd $cpp_path
122
123# other than MinGW
124if test $host_system != SYS_MINGW; then
125    echo '#!/bin/sh'                    >  mcpp.sh
126    # for GCC V.3.3 and later
127    if test x$cpp_base = xcc1; then
128        for cpp in cc1 cc1plus
129        do
130            if test $cpp = cc1; then
131                shname=mcpp
132            else
133                shname=mcpp_plus
134            fi
135            if test $cpp = cc1plus; then
136                echo '#!/bin/sh'        >  mcpp_plus.sh
137            fi
138            cat >> $shname.sh <<_EOF
139for i in \$@
140do
141    case \$i in
142        -fpreprocessed|-traditional*)
143            $cpp_path/${cpp}_gnuc "\$@"
144            exit ;;
145    esac
146done
147_EOF
148        done
149    fi
150
151    # for GCC V.2, V.3 and V.4
152    mcpp_name=mcpp
153    if test $host_system = SYS_MAC && test -f ${target}-mcpp; then
154        mcpp_name=${target}-mcpp    ## long name of Mac OS X cross-compiler
155    fi
156    echo $cpp_path/$mcpp_name '"$@"'    >>  mcpp.sh
157    chmod a+x mcpp.sh
158    if test x$cpp_base = xcc1; then
159        echo $cpp_path/$mcpp_name -+ '"$@"' >> mcpp_plus.sh
160        chmod a+x mcpp_plus.sh
161    fi
162fi
163
164# backup GCC / cpp or cc1, cc1plus
165mcpp_installed=`$cpp_call -v /dev/null 2>&1 | grep "MCPP"`
166if test "x$mcpp_installed" = x; then            # mcpp has not installed
167    sym_link=
168    if test $host_system = SYS_MINGW; then
169        if test -f cc1_gnuc$EXEEXT; then
170            sym_link=l          ## cc1.exe already moved to cc1_gnuc.exe
171        fi
172    else
173        if test -h $cpp_name; then
174            sym_link=l
175        fi
176    fi
177    if test x$sym_link != xl; then
178        echo "  mv $cpp_name ${cpp_base}_gnuc$EXEEXT"
179        mv -f $cpp_name ${cpp_base}_gnuc$EXEEXT
180        if test x$cpp_base = xcc1; then
181            echo "  mv cc1plus$EXEEXT cc1plus_gnuc$EXEEXT"
182            mv -f cc1plus$EXEEXT cc1plus_gnuc$EXEEXT
183        fi
184    fi
185fi
186if test -f $cpp_name; then
187    rm -f $cpp_name
188    if test x$cpp_base = xcc1; then
189        rm -f cc1plus$EXEEXT
190    fi
191fi
192
193# make symbolic link of mcpp.sh to 'cpp0' or 'cc1', 'cc1plus'
194if test $host_system = SYS_MINGW; then
195    echo "  cp $cwd/cc1$EXEEXT"
196    cp $cwd/cc1$EXEEXT .
197    strip cc1$EXEEXT
198else
199    echo "  $LN_S mcpp.sh $cpp_name"
200    $LN_S mcpp.sh $cpp_name
201fi
202
203if test x$cpp_base = xcc1; then
204    if test $host_system = SYS_MINGW; then
205        echo "  cp cc1$EXEEXT cc1plus$EXEEXT"
206        cp cc1$EXEEXT cc1plus$EXEEXT
207    else
208        echo "  $LN_S mcpp_plus.sh cc1plus$EXEEXT"
209        $LN_S mcpp_plus.sh cc1plus$EXEEXT
210    fi
211fi
212
213if test x$gcc_maj_ver = x2; then
214    exit 0
215fi
216
217# for GCC V.3 or V.4 make ${CC}.sh and ${CXX}.sh to add -no-integrated-cpp
218# option
219echo "  cd $gcc_path"
220cd $gcc_path
221
222if test $host_system = SYS_MAC && test x${target_cc} != x; then
223    # cross-compiler on Mac OS X
224    CC_=$target_cc
225    CXX_=`echo $target_cc | sed 's/gcc/g++/'`
226else
227    CC_=$CC
228    CXX_=$CXX
229fi
230
231for cc in $CC_ $CXX_
232do
233    entity=$cc$EXEEXT
234    if test $host_system != SYS_MINGW; then
235        ref=$cc$EXEEXT
236        while ref=`readlink $ref`
237        do
238            entity=$ref;
239        done
240        if test $entity = $cc.sh; then          # gcc.sh already installed
241            exit 0
242        fi
243    fi
244    ccache=`echo $entity | grep ccache`
245    if test x$ccache != x; then
246        ## CC (CXX) is a symbolic link to ccache
247        ## search the real $cc in $PATH
248        for path in `echo $PATH | sed 's/:/ /g'`
249        do
250            if test -f $path/$cc$EXEEXT && test $gcc_path != $path; then
251                break;
252            fi
253        done
254        gcc_path=$path
255        echo "  cd $gcc_path"
256        cd $gcc_path
257        entity=$cc
258        ref=$cc
259        while ref=`readlink $ref`
260        do
261            entity=$ref;
262        done
263        if test $entity = $cc.sh; then
264            exit 0
265        fi
266    fi
267    if test x$EXEEXT != x; then
268        entity_base=`echo $entity | sed "s/$EXEEXT//"`
269    else
270        entity_base=$entity
271    fi
272    if test $host_system != SYS_MINGW     \
273            || test ! -f ${entity_base}_proper$EXEEXT; then
274        echo "  mv $entity ${entity_base}_proper$EXEEXT"
275        mv -f $entity ${entity_base}_proper$EXEEXT
276    fi
277    if test x"`echo $entity | grep '^/'`" = x; then     # not absolute path
278        prefix_dir=$gcc_path/
279    else                                # absolute path
280        prefix_dir=
281    fi
282    echo '#! /bin/sh' > $cc.sh
283    echo $prefix_dir${entity_base}_proper -no-integrated-cpp '"$@"' >> $cc.sh
284    chmod a+x $cc.sh
285    echo "  $LN_S $cc.sh $cc"
286    $LN_S -f $cc.sh $cc
287    if test $cc != $entity; then
288        $LN_S -f $cc.sh $entity
289    fi
290done
291
292