1#! /bin/sh 2# 3# %CopyrightBegin% 4# 5# Copyright Ericsson AB 2002-2020. All Rights Reserved. 6# 7# Licensed under the Apache License, Version 2.0 (the "License"); 8# you may not use this file except in compliance with the License. 9# You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an "AS IS" BASIS, 15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18# 19# %CopyrightEnd% 20# 21# Icky cl wrapper that does it's best to behave like a Unixish cc. 22# Made to work for Erlang builds and to make configure happy, not really 23# general I suspect. 24# set -x 25# Save the command line for debug outputs 26 27SAVE="$@" 28 29# Constants 30COMMON_CFLAGS="-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -D_CRT_SECURE_NO_DEPRECATE" 31 32# Variables 33# The stdout and stderr for the compiler 34MSG_FILE=/tmp/cl.exe.$$.1 35ERR_FILE=/tmp/cl.exe.$$.2 36 37# "Booleans" determined during "command line parsing" 38# If the stdlib option is explicitly passed to this program 39MD_FORCED=false 40# If we're preprocession (only) i.e. -E 41PREPROCESSING=false 42# If we're generating dependencies (implies preprocesing) 43DEPENDENCIES=false 44# If this is supposed to be a debug build 45DEBUG_BUILD=false 46# If this is supposed to be an optimized build (there can only be one...) 47OPTIMIZED_BUILD=false 48# If we're linking or only compiling 49LINKING=true 50 51# This data is accumulated during command line "parsing" 52# The stdlibrary option, default multithreaded dynamic 53MD=-MD 54# Flags for debug compilation 55DEBUG_FLAGS="" 56# Flags for optimization 57OPTIMIZE_FLAGS="" 58# The specified output filename (if any), may be either object or exe. 59OUTFILE="" 60# Unspecified command line options for the compiler 61CMD="" 62# All the c source files, in unix style 63SOURCES="" 64# All the options to pass to the linker, kept in Unix style 65LINKCMD="" 66 67 68# Loop through the parameters and set the above variables accordingly 69# Also convert some cygwin filenames to "mixed style" dito (understood by the 70# compiler very well), except for anything passed to the linker, that script 71# handles those and the sources, which are also kept unixish for now 72 73while test -n "$1" ; do 74 x="$1" 75 case "$x" in 76 -Wall) 77 ;; 78 -c) 79 LINKING=false;; 80 #CMD="$CMD -c";; 81 -MM) 82 PREPROCESSING=true; 83 LINKING=false; 84 DEPENDENCIES=true;; 85 -E) 86 PREPROCESSING=true; 87 LINKING=false;; # Obviously... 88 #CMD="$CMD -E";; 89 -Owx) 90 # Optimization hardcoded of wxErlang, needs to disable debugging too 91 OPTIMIZE_FLAGS="-Ob2ity -Gs -Zi"; 92 DEBUG_FLAGS=""; 93 DEBUG_BUILD=false; 94 if [ $MD_FORCED = false ]; then 95 MD=-MD; 96 fi 97 OPTIMIZED_BUILD=true;; 98 -O*) 99 # Optimization hardcoded, needs to disable debugging too 100 OPTIMIZE_FLAGS="-Ox -Zi"; 101 DEBUG_FLAGS=""; 102 DEBUG_BUILD=false; 103 if [ $MD_FORCED = false ]; then 104 MD=-MD; 105 fi 106 OPTIMIZED_BUILD=true;; 107 -g|-ggdb) 108 if [ $OPTIMIZED_BUILD = false ];then 109 # Hardcoded windows debug flags 110 DEBUG_FLAGS="-Z7"; 111 if [ $MD_FORCED = false ]; then 112 MD=-MDd; 113 fi 114 LINKCMD="$LINKCMD -g"; 115 DEBUG_BUILD=true; 116 fi;; 117 # Allow forcing of stdlib 118 -mt|-MT) 119 MD="-MT"; 120 MD_FORCED=true;; 121 -md|-MD) 122 MD="-MD"; 123 MD_FORCED=true;; 124 -ml|-ML) 125 MD="-ML"; 126 MD_FORCED=true;; 127 -mdd|-MDD|-MDd) 128 MD="-MDd"; 129 MD_FORCED=true;; 130 -mtd|-MTD|-MTd) 131 MD="-MTd"; 132 MD_FORCED=true;; 133 -mld|-MLD|-MLd) 134 MD="-MLd"; 135 MD_FORCED=true;; 136 -o) 137 shift; 138 OUTFILE="$1";; 139 -o*) 140 y=`echo $x | sed 's,^-[Io]\(.*\),\1,g'`; 141 OUTFILE="$y";; 142 -I/*) 143 y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; 144 z=`echo $x | sed 's,^-\([Io]\)\(/.*\),\1,g'`; 145 MPATH=`echo $y`; 146 CMD="$CMD -$z\"$MPATH\"";; 147 -I*) 148 y=`echo $x | sed 's,",\\\",g'`; 149 CMD="$CMD $y";; 150 -D*) 151 y=`echo $x | sed 's,",\\\",g'`; 152 CMD="$CMD $y";; 153 -EH*) 154 y=`echo $x | sed 's,",\\\",g'`; 155 CMD="$CMD $y";; 156 -TP|-Tp) 157 y=`echo $x | sed 's,",\\\",g'`; 158 CMD="$CMD $y";; 159 -l*) 160 y=`echo $x | sed 's,^-l\(.*\),\1,g'`; 161 LINKCMD="$LINKCMD $x";; 162 /*.c) 163 SOURCES="$SOURCES $x";; 164 *.c) 165 SOURCES="$SOURCES $x";; 166 /*.cc) 167 SOURCES="$SOURCES $x";; 168 *.cc) 169 SOURCES="$SOURCES $x";; 170 /*.cpp) 171 SOURCES="$SOURCES $x";; 172 *.cpp) 173 SOURCES="$SOURCES $x";; 174 /*.o) 175 LINKCMD="$LINKCMD $x";; 176 *.o) 177 LINKCMD="$LINKCMD $x";; 178 *) 179 # Try to quote uninterpreted options 180 y=`echo $x | sed 's,",\\\",g'`; 181 LINKCMD="$LINKCMD $y";; 182 esac 183 shift 184done 185 186#Return code from compiler, linker.sh and finally this script... 187RES=0 188 189# Accumulated object names 190ACCUM_OBJECTS="" 191 192# A temporary object file location 193TMPOBJDIR=/tmp/tmpobj$$ 194mkdir $TMPOBJDIR 195 196# Compile 197for x in $SOURCES; do 198 # Compile each source 199 if [ $LINKING = false ]; then 200 # We should have an output defined, which is a directory 201 # or an object file 202 case $OUTFILE in 203 /*.o) 204 # Simple output, SOURCES should be one single 205 n=`echo $SOURCES | wc -w`; 206 if [ $n -gt 1 ]; then 207 echo "cc.sh:Error, multiple sources, one object output."; 208 exit 1; 209 else 210 output_filename=`echo $OUTFILE`; 211 fi;; 212 *.o) 213 # Relative path needs no translation 214 n=`echo $SOURCES | wc -w` 215 if [ $n -gt 1 ]; then 216 echo "cc.sh:Error, multiple sources, one object output." 217 exit 1 218 else 219 output_filename=$OUTFILE 220 fi;; 221 /*) 222 # Absolute directory 223 o=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.o,'` 224 output_filename=`echo $OUTFILE` 225 output_filename="$output_filename/${o}";; 226 *) 227 # Relative_directory or empty string (.//x.o is valid) 228 o=`echo $x | sed 's,.*/,,' | sed 's,\.cp*$,.o,'` 229 output_filename="./${OUTFILE}/${o}";; 230 esac 231 else 232 # We are linking, which means we build objects in a temporary 233 # directory and link from there. We should retain the basename 234 # of each source to make examining the exe easier... 235 o=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.o,'` 236 output_filename=$TMPOBJDIR/$o 237 ACCUM_OBJECTS="$ACCUM_OBJECTS $output_filename" 238 fi 239 # Now we know enough, lets try a compilation... 240 MPATH=`echo $x` 241 if [ $PREPROCESSING = true ]; then 242 output_flag="-E" 243 else 244 output_flag="-FS -c -Fo`cmd //C echo ${output_filename}`" 245 fi 246 params="$COMMON_CFLAGS $MD $DEBUG_FLAGS $OPTIMIZE_FLAGS \ 247 $CMD ${output_flag} $MPATH" 248 if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then 249 echo cc.sh "$SAVE" >>$CC_SH_DEBUG_LOG 250 echo cl.exe $params >>$CC_SH_DEBUG_LOG 251 fi 252 # MSYS2 (currently) converts the paths wrong, avoid it 253 export MSYS2_ARG_CONV_EXCL=-FoC 254 eval cl.exe $params >$MSG_FILE 2>$ERR_FILE 255 RES=$? 256 if test $PREPROCESSING = false; then 257 cat $ERR_FILE >&2 258 tail -n +2 $MSG_FILE 259 else 260 tail -n +2 $ERR_FILE >&2 261 if test $DEPENDENCIES = true; then 262 perl -e ' 263my $file = "'$x'"; 264while (<>) { 265 next unless /^#line/; 266 next if /$file/o; 267 (undef,$_) = split(/\"/); 268 next if / /; 269 $all{$_} = 1; 270} 271foreach (sort keys %all) { 272 s@^([A-Za-z]):@/$1@; 273 s@\\\\@/@g; 274 push @f, "\\\n $_ "; 275} 276if (@f) { 277 my $oname = $file; 278 $oname =~ s@.*/@@; 279 $oname =~ s@[.]cp*@.o@; 280 print $oname, ":", @f; 281 print "\n\n"; 282 print STDERR "Made dependencies for $file\n"; 283}' $MSG_FILE 284 else 285 cat $MSG_FILE 286 fi 287 fi 288 rm -f $ERR_FILE $MSG_FILE 289 if [ $RES != 0 ]; then 290 echo Failed: cl.exe $params 291 rm -rf $TMPOBJDIR 292 exit $RES 293 fi 294done 295 296# If we got here, we succeeded in compiling (if there were anything to compile) 297# The output filename should name an executable if we're linking 298if [ $LINKING = true ]; then 299 case $OUTFILE in 300 "") 301 # Use the first source name to name the executable 302 first_source="" 303 for x in $SOURCES; do first_source=$x; break; done; 304 if [ -n "$first_source" ]; then 305 e=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.exe,'`; 306 out_spec="-o $e"; 307 else 308 out_spec=""; 309 fi;; 310 *) 311 out_spec="-o $OUTFILE";; 312 esac 313 # Descide which standard library to link against 314 case $MD in 315 -ML) 316 stdlib="-lLIBC";; 317 -MLd) 318 stdlib="-lLIBCD";; 319 -MD) 320 stdlib="-lMSVCRT";; 321 -MDd) 322 stdlib="-lMSVCRTD";; 323 -MT) 324 stdlib="-lLIBCMT";; 325 -MTd) 326 stdlib="-lLIBMTD";; 327 esac 328 # And finally call the next script to do the linking... 329 params="$out_spec $LINKCMD $stdlib" 330 if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then 331 echo ld.sh $ACCUM_OBJECTS $params 332 fi 333 eval ld.sh $ACCUM_OBJECTS $params 334 RES=$? 335fi 336rm -rf $TMPOBJDIR 337 338exit $RES 339