diff options
Diffstat (limited to 'erts/etc/win32/cygwin_tools/vc')
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/ar.sh | 47 | ||||
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/cc.sh | 321 | ||||
-rw-r--r-- | erts/etc/win32/cygwin_tools/vc/cc_wrap.c | 864 | ||||
-rw-r--r-- | erts/etc/win32/cygwin_tools/vc/coffix.c | 161 | ||||
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/emu_cc.sh | 90 | ||||
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/ld.sh | 192 | ||||
-rw-r--r-- | erts/etc/win32/cygwin_tools/vc/ld_wrap.c | 796 | ||||
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/mc.sh | 87 | ||||
-rwxr-xr-x | erts/etc/win32/cygwin_tools/vc/rc.sh | 86 |
9 files changed, 2644 insertions, 0 deletions
diff --git a/erts/etc/win32/cygwin_tools/vc/ar.sh b/erts/etc/win32/cygwin_tools/vc/ar.sh new file mode 100755 index 0000000000..24d275b01a --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/ar.sh @@ -0,0 +1,47 @@ +#! /bin/sh +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +CMD="" +while test -n "$1" ; do + x="$1" + case "$x" in + -out:) + shift + case "$1" in + /*) + MPATH=`cygpath -m $1`;; + *) + MPATH=$1;; + esac + CMD="$CMD -out:\"$MPATH\"";; + -out:/*) + y=`echo $x | sed 's,^-out:\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -out:\"$MPATH\"";; + /*) + MPATH=`cygpath -m $x`; + CMD="$CMD \"$MPATH\"";; + *) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD \"$y\"";; + esac + shift +done + +eval lib.exe $CMD diff --git a/erts/etc/win32/cygwin_tools/vc/cc.sh b/erts/etc/win32/cygwin_tools/vc/cc.sh new file mode 100755 index 0000000000..4939465d08 --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/cc.sh @@ -0,0 +1,321 @@ +#! /bin/sh +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# Icky cl wrapper that does it's best to behave like a Unixish cc. +# Made to work for Erlang builds and to make configure happy, not really +# general I suspect. +# set -x +# Save the command line for debug outputs +SAVE="$@" + +# Constants +COMMON_CFLAGS="-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -D_CRT_SECURE_NO_DEPRECATE" + +# Variables +# The stdout and stderr for the compiler +MSG_FILE=/tmp/cl.exe.$$.1 +ERR_FILE=/tmp/cl.exe.$$.2 + +# "Booleans" determined during "command line parsing" +# If the stdlib option is explicitly passed to this program +MD_FORCED=false +# If we're preprocession (only) i.e. -E +PREPROCESSING=false +# If we're generating dependencies (implies preprocesing) +DEPENDENCIES=false +# If this is supposed to be a debug build +DEBUG_BUILD=false +# If this is supposed to be an optimized build (there can only be one...) +OPTIMIZED_BUILD=false +# If we're linking or only compiling +LINKING=true + +# This data is accumulated during command line "parsing" +# The stdlibrary option, default multithreaded dynamic +MD=-MD +# Flags for debug compilation +DEBUG_FLAGS="" +# Flags for optimization +OPTIMIZE_FLAGS="" +# The specified output filename (if any), may be either object or exe. +OUTFILE="" +# Unspecified command line options for the compiler +CMD="" +# All the c source files, in unix style +SOURCES="" +# All the options to pass to the linker, kept in Unix style +LINKCMD="" + + +# Loop through the parameters and set the above variables accordingly +# Also convert some cygwin filenames to "mixed style" dito (understood by the +# compiler very well), except for anything passed to the linker, that script +# handles those and the sources, which are also kept unixish for now + +while test -n "$1" ; do + x="$1" + case "$x" in + -Wall) + ;; + -c) + LINKING=false;; + #CMD="$CMD -c";; + -MM) + PREPROCESSING=true; + LINKING=false; + DEPENDENCIES=true;; + -E) + PREPROCESSING=true; + LINKING=false;; # Obviously... + #CMD="$CMD -E";; + -Owx) + # Optimization hardcoded of wxErlang, needs to disable debugging too + OPTIMIZE_FLAGS="-Ob2ity -Gs -Zi"; + DEBUG_FLAGS=""; + DEBUG_BUILD=false; + if [ $MD_FORCED = false ]; then + MD=-MD; + fi + OPTIMIZED_BUILD=true;; + -O*) + # Optimization hardcoded, needs to disable debugging too + OPTIMIZE_FLAGS="-Ox -Zi"; + DEBUG_FLAGS=""; + DEBUG_BUILD=false; + if [ $MD_FORCED = false ]; then + MD=-MD; + fi + OPTIMIZED_BUILD=true;; + -g|-ggdb) + if [ $OPTIMIZED_BUILD = false ];then + # Hardcoded windows debug flags + DEBUG_FLAGS="-Z7"; + if [ $MD_FORCED = false ]; then + MD=-MDd; + fi + LINKCMD="$LINKCMD -g"; + DEBUG_BUILD=true; + fi;; + # Allow forcing of stdlib + -mt|-MT) + MD="-MT"; + MD_FORCED=true;; + -md|-MD) + MD="-MD"; + MD_FORCED=true;; + -ml|-ML) + MD="-ML"; + MD_FORCED=true;; + -mdd|-MDD|-MDd) + MD="-MDd"; + MD_FORCED=true;; + -mtd|-MTD|-MTd) + MD="-MTd"; + MD_FORCED=true;; + -mld|-MLD|-MLd) + MD="-MLd"; + MD_FORCED=true;; + -o) + shift; + OUTFILE="$1";; + -o*) + y=`echo $x | sed 's,^-[Io]\(.*\),\1,g'`; + OUTFILE="$y";; + -I/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + z=`echo $x | sed 's,^-\([Io]\)\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -$z\"$MPATH\"";; + -I*) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD $y";; + -D*) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD $y";; + -EH*) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD $y";; + -l*) + y=`echo $x | sed 's,^-l\(.*\),\1,g'`; + LINKCMD="$LINKCMD $x";; + /*.c) + SOURCES="$SOURCES $x";; + *.c) + SOURCES="$SOURCES $x";; + /*.cc) + SOURCES="$SOURCES $x";; + *.cc) + SOURCES="$SOURCES $x";; + /*.cpp) + SOURCES="$SOURCES $x";; + *.cpp) + SOURCES="$SOURCES $x";; + /*.o) + LINKCMD="$LINKCMD $x";; + *.o) + LINKCMD="$LINKCMD $x";; + *) + # Try to quote uninterpreted options + y=`echo $x | sed 's,",\\\",g'`; + LINKCMD="$LINKCMD $y";; + esac + shift +done + +#Return code from compiler, linker.sh and finally this script... +RES=0 + +# Accumulated object names +ACCUM_OBJECTS="" + +# A temporary object file location +TMPOBJDIR=/tmp/tmpobj$$ +mkdir $TMPOBJDIR + +# Compile +for x in $SOURCES; do + start_time=`date '+%s'` + # Compile each source + if [ $LINKING = false ]; then + # We should have an output defined, which is a directory + # or an object file + case $OUTFILE in + /*.o) + # Simple output, SOURCES should be one single + n=`echo $SOURCES | wc -w`; + if [ $n -gt 1 ]; then + echo "cc.sh:Error, multiple sources, one object output."; + exit 1; + else + output_filename=`cygpath -m $OUTFILE`; + fi;; + *.o) + # Relative path needs no translation + n=`echo $SOURCES | wc -w` + if [ $n -gt 1 ]; then + echo "cc.sh:Error, multiple sources, one object output." + exit 1 + else + output_filename=$OUTFILE + fi;; + /*) + # Absolute directory + o=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.o,'` + output_filename=`cygpath -m $OUTFILE` + output_filename="$output_filename/${o}";; + *) + # Relative_directory or empty string (.//x.o is valid) + o=`echo $x | sed 's,.*/,,' | sed 's,\.cp*$,.o,'` + output_filename="./${OUTFILE}/${o}";; + esac + else + # We are linking, which means we build objects in a temporary + # directory and link from there. We should retain the basename + # of each source to make examining the exe easier... + o=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.o,'` + output_filename=$TMPOBJDIR/$o + ACCUM_OBJECTS="$ACCUM_OBJECTS $output_filename" + fi + # Now we know enough, lets try a compilation... + MPATH=`cygpath -m $x` + if [ $PREPROCESSING = true ]; then + output_flag="-E" + else + output_flag="-c -Fo`cygpath -m ${output_filename}`" + fi + params="$COMMON_CFLAGS $MD $DEBUG_FLAGS $OPTIMIZE_FLAGS \ + $CMD ${output_flag} $MPATH" + if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then + echo cc.sh "$SAVE" >>$CC_SH_DEBUG_LOG + echo cl.exe $params >>$CC_SH_DEBUG_LOG + fi + eval cl.exe $params >$MSG_FILE 2>$ERR_FILE + RES=$? + if test $PREPROCESSING = false; then + cat $ERR_FILE >&2 + tail -n +2 $MSG_FILE + else + tail -n +2 $ERR_FILE >&2 + if test $DEPENDENCIES = true; then + if test `grep -v $x $MSG_FILE | grep -c '#line'` != "0"; then + o=`echo $x | sed 's,.*/,,' | sed 's,\.cp*$,.o,'` + echo -n $o':' + # Some versions of cygpath does not read paths linewise + # but uses space as separator, why pathnames containing + # spaces need to be removed. To avoid different + # behaviours in different versions of cygwin, we would need to + # write our own cygpath replacement, but this will have to do + # for now... + cat $MSG_FILE | grep '#line' | grep -v $x | awk -F\" '{printf("%s\n",$2)}' | sort -u | grep -v " " | cygpath -f - -m -s | cygpath -f - | awk '{printf("\\\n %s ",$0)}' + echo + echo + after_sed=`date '+%s'` + echo Made dependencises for $x':' `expr $after_sed '-' $start_time` 's' >&2 + fi + else + cat $MSG_FILE + fi + fi + rm -f $ERR_FILE $MSG_FILE + if [ $RES != 0 ]; then + rm -rf $TMPOBJDIR + exit $RES + fi +done + +# If we got here, we succeeded in compiling (if there were anything to compile) +# The output filename should name an executable if we're linking +if [ $LINKING = true ]; then + case $OUTFILE in + "") + # Use the first source name to name the executable + first_source="" + for x in $SOURCES; do first_source=$x; break; done; + if [ -n "$first_source" ]; then + e=`echo $x | sed 's,.*/,,' | sed 's,\.c$,.exe,'`; + out_spec="-o $e"; + else + out_spec=""; + fi;; + *) + out_spec="-o $OUTFILE";; + esac + # Descide which standard library to link against + case $MD in + -ML) + stdlib="-lLIBC";; + -MLd) + stdlib="-lLIBCD";; + -MD) + stdlib="-lMSVCRT";; + -MDd) + stdlib="-lMSVCRTD";; + -MT) + stdlib="-lLIBCMT";; + -MTd) + stdlib="-lLIBMTD";; + esac + # And finally call the next script to do the linking... + params="$out_spec $LINKCMD $stdlib" + eval ld.sh $ACCUM_OBJECTS $params + RES=$? +fi +rm -rf $TMPOBJDIR + +exit $RES diff --git a/erts/etc/win32/cygwin_tools/vc/cc_wrap.c b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c new file mode 100644 index 0000000000..18ecc31c17 --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c @@ -0,0 +1,864 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <dirent.h> +#include <sys/cygwin.h> + + + +#ifdef CCP_POSIX_TO_WIN_A +#define NEW_CYGPATH_INTERFACE +#endif + +#ifdef NEW_CYGPATH_INTERFACE +#define GET_WIN32_SIZE(Posix) \ +cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), NULL, 0) +#define CONVERT_TO_WIN32(Posix,Win32,Size) \ +cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), \ + (Win32), (Size)) +#else +#define GET_WIN32_SIZE(Posix) PATH_MAX +#define CONVERT_TO_WIN32(Posix,Win32,Size) \ +((cygwin32_conv_to_full_win32_path((Posix),(Win32)) >= 0) ? 0 : -1) +#endif + +/*#define HARDDEBUG 1*/ + +#ifdef HARDDEBUG +#define DEBUGF(X) printf X +#else +#define DEBUGF(X) /* noop */ +#endif +char *tmpobjdir = ""; + +char *add_to(char *src,char *add) { + int len = strlen(src)+strlen(add)+1; + char *n; + + if (strlen(src) == 0) { + n = malloc(len); + strcpy(n,add); + return n; + } + n = realloc(src,len); + strcat(n,add); + return n; +} + +void maybe_cleanup(void) +{ + DIR *dir; + struct dirent *dent; + if (*tmpobjdir == '\0') { + return; + } + if (!(dir = opendir(tmpobjdir))) { + return; + } + while((dent = readdir(dir)) != NULL) { + char *fullname = add_to("",tmpobjdir); + fullname = add_to(fullname,"/"); + fullname = add_to(fullname,dent->d_name); + unlink(fullname); + free(fullname); + } + closedir(dir); + rmdir(tmpobjdir); +} + + + + +void error(char *str) +{ + fprintf(stderr,"%s\n",str); + maybe_cleanup(); + exit(1); +} + + +char **add_to_src(char **srcarr, char *add) +{ + int num; + if (srcarr == NULL) { + srcarr = malloc(sizeof(char *)*2); + srcarr[0]=malloc(strlen(add)+1); + strcpy(srcarr[0],add); + srcarr[1] = NULL; + } else { + for(num = 0; srcarr[num] != NULL; ++num) + ; + num +=1; + srcarr = realloc(srcarr,sizeof(char *)*(num+1)); + srcarr[num-1] = malloc(strlen(add)+1); + strcpy(srcarr[num-1],add); + srcarr[num] = NULL; + } + return srcarr; +} + + + +char *object_name(char *source) { + char *tmp = add_to("",source); + int j = strlen(tmp)-2; + if (j < 0) { + j = 0; + } + while(j>0 && tmp[j] != '.') { + --j; + } + if (tmp[j] == '.') { + ++j; + } + tmp[j++] = 'o'; + tmp[j] = '\0'; + return tmp; +} + +char *exe_name(char *source) { + char *tmp = add_to("",source); + int j = strlen(tmp)-2; + if (j < 0) { + j = 0; + } + while(j>0 && tmp[j] != '.') { + --j; + } + if (tmp[j] == '.') { + ++j; + } + tmp[j] = '\0'; + return add_to(tmp,"exe"); +} + +char *dyn_get_short(char *longp) +{ + int size; + char *shortp; + size = GetShortPathName(longp,NULL,0); + if (size <= 0) { + return NULL; + } + shortp = malloc(size); + if (GetShortPathName(longp,shortp,size) != size - 1) { + free(shortp); + return NULL; + } + return shortp; +} + +char *do_cyp(char *posix) +{ + ssize_t size; + char *win32; + size = GET_WIN32_SIZE(posix); + char *ret = NULL; + if (size < 0) { + fprintf(stderr,"Could not cygpath %s, errno = %d\n", + posix,errno); + } else { + win32 = (char *) malloc (size); + if (CONVERT_TO_WIN32(posix, + win32, size)) { + fprintf(stderr,"Could not cygpath %s, errno = %d\n", + posix,errno); + } else { + char *w32_short = dyn_get_short(win32); + DEBUGF(("win32 = %s, w32_short = %s\n",win32, (w32_short == NULL) ? "NULL" : w32_short)); + if (w32_short == NULL) { + char *rest = malloc(size); + char *first = malloc(size); + int x = 0; + int y = strlen(win32) - 1; + strcpy(first,win32); + while (w32_short == NULL) { + while ( y > 0 && first[y] != '\\') { + rest[x++] = first[y--]; + } + if (y > 0) { + rest[x++] = first[y]; + first[y--] = '\0'; + } else { + break; + } + w32_short = dyn_get_short(first); + DEBUGF(("first = %s, w32_short = %s\n",first, (w32_short == NULL) ? "NULL" : w32_short)); + } + if (w32_short != NULL) { + y = strlen(w32_short); + w32_short = realloc(w32_short,y+1+x); + /* spool back */ + while ( x > 0) { + w32_short[y++] = rest[--x]; + } + w32_short[y] = '\0'; + } else { + w32_short = malloc(strlen(win32)+1); + strcpy(w32_short,win32); /* last resort */ + } + free(first); + free(rest); + } + ret = w32_short; + while (*ret) { + if (*ret == '\\') { + *ret = '/'; + } + ++ret; + } + ret = w32_short; + } + free(win32); + } + return ret; +} + + + +char *save = ""; + +void save_args(int argc, char **argv) +{ + int i; + for(i = 0; i < argc; ++i) { + save = add_to(save,argv[i]); + save = add_to(save," "); + } +} + +char *progname="cc_wrap"; + +int my_create_pipe(HANDLE *read_p, HANDLE *write_p) +{ + char name_buff[1000]; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + static int counter = 0; + + ++counter; + + sprintf(name_buff,"\\\\.\\pipe\\%s_%d_%d",progname,getpid(),counter); + sa.bInheritHandle = FALSE; + if ((*read_p = CreateNamedPipe(name_buff, + PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + 1, + 0, + 0, + 2000, + &sa)) == INVALID_HANDLE_VALUE || + *read_p == NULL) { + return 0; + } + sa.bInheritHandle = TRUE; + if ((*write_p = CreateFile(name_buff, + GENERIC_WRITE, + 0, /* No sharing */ + &sa, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE || + *write_p == NULL) { + CloseHandle(*read_p); + return 0; + } + return 1; +} + +void forwardenv(void) +{ + char *(envs[]) = {"LIB","INCLUDE","LIBPATH", "LD_SH_DEBUG_LOG", NULL}; + char **p = envs; + while (*p != NULL) { + char *val = getenv(*p); + if (val != NULL) { + SetEnvironmentVariable(*p,val); + } + ++p; + } +} + +HANDLE do_run(char *commandline, HANDLE *out, HANDLE *err) +{ + STARTUPINFO start; + HANDLE write_pipe_stdout = NULL, read_pipe_stdout = NULL; + HANDLE write_pipe_stderr = NULL, read_pipe_stderr = NULL; + SECURITY_ATTRIBUTES pipe_security; + SECURITY_ATTRIBUTES attr; + PROCESS_INFORMATION info; + + memset(&start,0,sizeof(start)); + memset(&pipe_security,0,sizeof(pipe_security)); + memset(&attr,0,sizeof(attr)); + memset(&info,0,sizeof(info)); + + pipe_security.nLength = sizeof(pipe_security); + pipe_security.lpSecurityDescriptor = NULL; + pipe_security.bInheritHandle = TRUE; + + if(!my_create_pipe(&read_pipe_stdout,&write_pipe_stdout)){ + error("Could not create stdout pipes!"); + } + if(!my_create_pipe(&read_pipe_stderr,&write_pipe_stderr)){ + error("Could not create stderr pipes!"); + } + start.cb = sizeof (start); + start.dwFlags = STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + start.hStdOutput = write_pipe_stdout; + start.hStdError = write_pipe_stderr; + start.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + start.dwFlags |= STARTF_USESTDHANDLES; + + attr.nLength = sizeof(attr); + attr.lpSecurityDescriptor = NULL; + attr.bInheritHandle = TRUE; + forwardenv(); /* Cygwin and windows environment variables... sigh... */ + if(!CreateProcess(NULL, + commandline, + &attr, + NULL, + TRUE, + CREATE_DEFAULT_ERROR_MODE, + NULL, + NULL, + &start, + &info)){ + fprintf(stderr,"Could not run %s, last error: %d\n",commandline,GetLastError()); + error("Could not create process"); + } + *out = read_pipe_stdout; + *err = read_pipe_stderr; + CloseHandle(write_pipe_stdout); + CloseHandle(write_pipe_stderr); + return info.hProcess; +} +#define HANDLE_STDOUT 0 +#define HANDLE_STDERR 1 +#define HANDLE_PROC 2 + +#ifdef HARDDEBUG +char *prefix = ""; +#endif + +int handle_overlapped(HANDLE fd, OVERLAPPED *ovp, char *buffer, + int bufflen, int get_old, FILE *whereto, int *skip) +{ + DWORD res,read,err; + char *ptr; + + DEBUGF(("In handle_overlapped(%d,0x%08x,0x%08x,%d,%d), prefix = %s\n", + fd,ovp,buffer,bufflen,get_old,prefix)); + /* h�mta resultat av gamla f�rst */ + if (get_old) { + res = GetOverlappedResult(fd,ovp,&read,TRUE); + DEBUGF(("read = %d, res = %d, GetLastError() = %d\n",read,res,GetLastError())); + if (!res) { + return 0; + } + buffer[read] = '\0'; + ptr = buffer; + while(*skip && *ptr != '\0') { + if (*ptr == '\n') { + --(*skip); + } + ++ptr; + } + if(*ptr != '\0') { + fprintf(whereto,"%s",ptr); + } + } + + ResetEvent(ovp->hEvent); + + for(;;) { + res = ReadFile(fd,buffer,bufflen-1,&read,ovp); + + if (!res) { + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + DEBUGF(("Error I/O Pending\n")); + return 1; + } + DEBUGF(("ReadFileFailed for %s, %d\n",prefix,err)); + return 0; + } + buffer[read] = '\0'; + ptr = buffer; + while(*skip && *ptr != '\0') { + if (*ptr == '\n') { + --(*skip); + } + ++ptr; + } + if(*ptr != '\0') { + fprintf(whereto,"%s",ptr); + } + } +} + + +int run(char *commandline,int skipout,int skiperr) +{ + HANDLE harr[3]; + HANDLE real_stdout,real_stderr; + OVERLAPPED ov_out,ov_err; + char outbuff[1024],errbuff[1024]; + DWORD ret,exitcode; + HANDLE wait[3]; + int map[3]; + DWORD nwait = 3; + int i,j; + unsigned living_handles = 0x7; + + harr[HANDLE_STDOUT] = CreateEvent(NULL, + TRUE, + FALSE, /*not signalled */ + NULL); + harr[HANDLE_STDERR] = CreateEvent(NULL, + TRUE, + FALSE,/*not signalled */ + NULL); + + memset(&ov_out,0,sizeof(ov_out)); + memset(&ov_err,0,sizeof(ov_err)); + + ov_out.hEvent = harr[HANDLE_STDOUT]; + ov_err.hEvent = harr[HANDLE_STDERR]; + + harr[HANDLE_PROC] = do_run(commandline,&real_stdout,&real_stderr); + +#ifdef HARDDEBUG + prefix = "STDOUT"; +#endif + handle_overlapped(real_stdout,&ov_out,outbuff,1024,0,stdout,&skipout); +#ifdef HARDDEBUG + prefix = "STDERR"; +#endif + handle_overlapped(real_stderr,&ov_err,errbuff,1024,0,stderr,&skiperr); + + for(;;) { + nwait = 0; + for(i=0;i<3;++i) { + if ((living_handles & (1U << i))) { + map[nwait] = i; + wait[nwait++] = harr[i]; + } + } + + ret = WaitForMultipleObjects(nwait, + wait, + FALSE, + INFINITE); + DEBUGF(("Wait returned %d\n",ret)); + + if (ret == WAIT_FAILED) { + error("Wait failed"); + } + + ret -= WAIT_OBJECT_0; + + switch (map[ret]) { + case HANDLE_PROC: + + DEBUGF(("Process died!\n")); + GetExitCodeProcess(harr[HANDLE_PROC],&exitcode); + if ((living_handles &= (~(1U<<HANDLE_PROC))) == 0) { + goto done; + } + --nwait; + break; + case HANDLE_STDOUT: +#ifdef HARDDEBUG + prefix = "STDOUT"; +#endif + if (!handle_overlapped(real_stdout,&ov_out, outbuff,1024,1,stdout,&skipout)) { + if ((living_handles &= (~(1U<<HANDLE_STDOUT))) == 0) { + goto done; + } + } + break; + case HANDLE_STDERR: +#ifdef HARDDEBUG + prefix = "STDERR"; +#endif + if (!handle_overlapped(real_stderr,&ov_err, errbuff,1024,1,stderr,&skiperr)){ + if ((living_handles &= (~(1U<<HANDLE_STDERR))) == 0) { + goto done; + } + } + break; + default: + error("Unexpected wait result"); + } + } + done: + CloseHandle(harr[HANDLE_PROC]); + CloseHandle(harr[HANDLE_STDOUT]); + CloseHandle(harr[HANDLE_STDERR]); + CloseHandle(real_stdout); + CloseHandle(real_stderr); + return (int) exitcode; +} + +int main(int argc, char **argv) +{ + int i; + int x; + char *s; + char *mpath; + char *debuglog; + FILE *debugfile; + + char *common_cflags="-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -D_CRT_SECURE_NO_DEPRECATE"; + char *md = "-MD"; + char *debug_flags = ""; + char *optimize_flags = ""; + char *outfile = ""; + char *cmd = ""; + char **sources = NULL; + char *accum_objects = ""; + char *linkcmd = ""; + + int md_forced = 0; + int preprocessing = 0; + int debug_build = 0; + int optimized_build = 0; + int linking = 1; + int retval; + + save_args(argc,argv); + + for(i = 1; i < argc; ++i) { + if (argv[i][0] == '-') { + char *opt = argv[i]+1; + switch(*opt) { + case 'W': + if(strcmp(opt,"Wall")) { + goto filename; + } + break; + case 'c': + if(strlen(opt) > 1) { + goto filename; + } + linking = 0; + break; + case 'E': + if(strlen(opt) > 1) { + if (opt[1] == 'H') { + cmd = add_to(cmd," "); + cmd = add_to(cmd,opt); + } else { + goto filename; + } + } + preprocessing = 1; + linking = 0; + break; + case 'O': + /* ignore what opt is requested, set hard */ + optimize_flags = "-Ox -Zi"; + debug_flags = ""; + debug_build = 0; + if (!md_forced) { + md = "-MD"; + } + optimized_build = 1; + break; + case 'g': + if (strcmp(opt,"g") && strcmp(opt,"ggdb")) { + goto filename; + } + if (!optimized_build) { + debug_flags = "-Z7"; + if (!md_forced) { + md = "-MDd"; + } + linkcmd = add_to(linkcmd," -g"); + debug_build = 1; + } + break; + case 'm': + case 'M': + if(!strcmp(opt,"mt") || !strcmp(opt,"MT")) { + md = "-MT"; + } else if (!strcmp(opt,"md") || !strcmp(opt,"MD")) { + md = "-MD"; + } else if (!strcmp(opt,"ml") || !strcmp(opt,"ML")) { + md = "-ML"; + } else if (!strcmp(opt,"mdd") || !strcmp(opt,"MDd") || + !strcmp(opt,"MDD")) { + md = "-MDd"; + } else if (!strcmp(opt,"mtd") || !strcmp(opt,"MTd") || + !strcmp(opt,"MTD")) { + md = "-MTd"; + } else if (!strcmp(opt,"mld") || !strcmp(opt,"MLd") || + !strcmp(opt,"MLD")) { + md = "-MLd"; + } else { + goto filename; + } + md_forced = 1; + break; + case 'o': + if (!strcmp(opt,"o")) { + ++i; + if (i >= argc) { + error("-o without filename"); + } + outfile = argv[i]; + } else { + outfile = opt+1; + } + break; + case 'I': + if(opt[1] == '/') { + mpath = do_cyp(opt+1); + cmd = add_to(cmd," -I\""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + } else { + cmd = add_to(cmd," "); + cmd = add_to(cmd,opt); + } + break; + case 'D': + cmd = add_to(cmd," -"); + cmd = add_to(cmd,opt); + case 'l': + linkcmd = add_to(linkcmd," -"); + linkcmd = add_to(linkcmd,opt); + break; + default: + goto filename; + } + continue; + } + filename: + s = argv[i]; + x = strlen(s); + if (x > 1 && s[x-1] == 'c' && s[x-2] == '.') { + /* C source */ + sources = add_to_src(sources,s); + } else if (x > 3 && !strcmp(s + (x - 4),".cpp")) { + /* C++ */ + sources = add_to_src(sources,s); + } else if (x > 1 && s[x-1] == 'o' && s[x-2] == '.') { + linkcmd = add_to(linkcmd," "); + linkcmd = add_to(linkcmd,s); + } else { + /* Pass rest to linker */ + linkcmd = add_to(linkcmd," "); + linkcmd = add_to(linkcmd,s); + } + } + if ((debuglog = getenv("CC_SH_DEBUG_LOG")) != NULL) { + debugfile = fopen(debuglog,"wb+"); + if (debugfile) { + fprintf(debugfile,"----------------\n"); + } + } else { + debugfile = NULL; + } + + tmpobjdir = add_to("","/tmp/tmpobj"); + { + char pidstr[100]; + pid_t pid = getpid(); + sprintf(pidstr,"%d",pid); + tmpobjdir = add_to(tmpobjdir,pidstr); + } + mkdir(tmpobjdir,0777); + if (sources != NULL) { + char *output_filename; + char *output_flag; + char *params; + for (i=0;sources[i] != NULL; ++i) { + if (!linking) { + int x = strlen(outfile); + if (x > 1 && outfile[x-1] == 'o' && outfile[x-2] == '.') { + if (*outfile != '/') { + /* non absolute object */ + if (i > 0) { + error("Single object multiple sources"); + } + output_filename = add_to("",outfile); + } else { + if (i > 0) { + error("Single object multiple sources"); + } + output_filename = do_cyp(outfile); + } + } else { + char *tmp = object_name(sources[i]); + + /*fprintf(stderr,"sources[i] = %s\ntmp = %s\n", + sources[i],tmp);*/ + + if (!x || outfile[0] != '/') { + /* non absolute directory */ + output_filename = add_to("",outfile); + } else { + output_filename = do_cyp(outfile); + } + /*fprintf(stderr,"output_filename = %s\n",output_filename);*/ + if (*output_filename != '\0') { + output_filename = add_to(output_filename,"/"); + } + output_filename = add_to(output_filename,tmp); + free(tmp); + } + } else { + char *tmp = object_name(sources[i]); + output_filename = add_to("",tmpobjdir); + output_filename = add_to(output_filename,"/"); + output_filename = add_to(output_filename,tmp); + accum_objects = add_to(accum_objects," "); + accum_objects = add_to(accum_objects,output_filename); + /* reform to dos path */ + free(output_filename); + output_filename = do_cyp(tmpobjdir); + output_filename = add_to(output_filename,"/"); + output_filename = add_to(output_filename,tmp); + } + mpath = do_cyp(sources[i]); + if (preprocessing) { + output_flag = add_to("","-E"); + } else { + output_flag = add_to("","-c -Fo"); + output_flag = add_to(output_flag,output_filename); + } + params = add_to("","cl.exe "); + params = add_to(params,common_cflags); + params = add_to(params," "); + params = add_to(params,md); + params = add_to(params," "); + params = add_to(params,debug_flags); + params = add_to(params," "); + params = add_to(params,optimize_flags); + params = add_to(params," "); + params = add_to(params,cmd); + params = add_to(params," "); + params = add_to(params,output_flag); + params = add_to(params," "); + params = add_to(params,mpath); + free(output_filename); + free(output_flag); + free(mpath); + + if (debugfile) { + fprintf(debugfile,"%s\n",save); + fprintf(debugfile,"%s\n",params); + } + if (preprocessing) { + retval = run(params,0,1); + } else { + retval = run(params,1,0); + } + if (retval != 0) { + maybe_cleanup(); + return retval; + } + free(params); + } + } + if (linking) { + char *out_spec; + char *stdlib; + char *params; + if (strlen(outfile) == 0) { + if (sources != NULL && sources[0] != NULL) { + char *tmp = exe_name(sources[0]); + out_spec = add_to("","-o "); + out_spec = add_to(out_spec,tmp); + free(tmp); + } else { + out_spec = add_to("",""); + } + } else { + out_spec = add_to("","-o "); + out_spec = add_to(out_spec,outfile); + } + if (!strcmp(md,"-ML")) { + stdlib="-lLIBC"; + } else if (!strcmp(md,"-MLd")) { + stdlib="-lLIBCD"; + } else if (!strcmp(md,"-MD")) { + stdlib="-lMSVCRT"; + } else if (!strcmp(md,"-MDd")) { + stdlib="-lMSVCRTD"; + } else if (!strcmp(md,"-MT")) { + stdlib="-lLIBCMT"; + } else if (!strcmp(md,"-MTd")) { + stdlib="-lLIBMTD"; + } else { + stdlib = ""; + } +#if 0 + params = add_to("","bash ld.sh "); +#else + params = add_to("","ld_wrap.exe "); +#endif + params = add_to(params,accum_objects); + params = add_to(params," "); + params = add_to(params,out_spec); + params = add_to(params," "); + params = add_to(params,linkcmd); + params = add_to(params," "); + params = add_to(params,stdlib); + free(out_spec); + free(accum_objects); + if (debugfile) { + fprintf(debugfile,"%s\n",params); + } + if (retval = run(params,0,0) != 0) { + maybe_cleanup(); + return retval; + } + free(params); + } + maybe_cleanup(); + return 0; +} + + + + + + + + + + + + + + + + + + diff --git a/erts/etc/win32/cygwin_tools/vc/coffix.c b/erts/etc/win32/cygwin_tools/vc/coffix.c new file mode 100644 index 0000000000..dee0132a61 --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/coffix.c @@ -0,0 +1,161 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1999-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* +** This mini tool fixes an incompatibility between +** Microsoft's tools, who dont like the virtual size being put in +** the physical address field, but rely on the raw size field for +** sizing the ".bss" section. +** This fixes some of the problems with linking gcc compiled objects +** together with MSVC dito. +** +** Courtesy DJ Delorie for describing the COFF file format on +** http://www.delorie.com/djgpp/doc/coff/ +** The coff structures are fetched from Microsofts headers though. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include <windows.h> +#include <winnt.h> /* Structure definitions for PE (COFF) */ + +static int dump_edit(char *filename, int edit); +static int v_printf(char *format, ...); + + +char *progname; +int verbouse = 0; + +int main(int argc, char **argv) +{ + int findex = 1; + int edit = 0; + int ret; + + progname = argv[0]; + if (argc == 1) { + fprintf(stderr,"Format : %s [-e] [-v] <filename>\n", progname); + return 1; + } + for (findex = 1; + findex < argc && (*argv[findex] == '-' || *argv[findex] == '/'); + ++findex) + switch (argv[findex][1]) { + case 'e': + case 'E': + edit = 1; + break; + case 'v': + case 'V': + verbouse = 1; + default: + fprintf(stderr, "%s: unknown option %s\n", progname, argv[findex]); + break; + } + if (findex == argc) { + fprintf(stderr,"%s: No filenames given.\n", progname); + return 1; + } + for(; findex < argc; ++findex) + if ((ret = dump_edit(argv[findex],edit)) != 0) + return ret; + return 0; +} + +int dump_edit(char *filename, int edit) +{ + FILE *f = fopen(filename, (edit) ? "r+b" : "rb"); + IMAGE_FILE_HEADER filhdr; + IMAGE_SECTION_HEADER scnhdr; + int i; + + if (f == NULL) { + fprintf(stderr, "%s: cannot open %s.\n", progname, filename); + return 1; + } + + if (fread(&filhdr, sizeof(filhdr), 1, f) == 0) { + fprintf(stderr,"%s: Could not read COFF header from %s," + " is this a PE (COFF) file?\n", progname, filename); + fclose(f); + return 1; + } + v_printf("File: %s\n", filename); + v_printf("Magic number: 0x%08x\n", filhdr.Machine); + v_printf("Number of sections: %d\n",filhdr.NumberOfSections); + + if (fseek(f, (long) filhdr.SizeOfOptionalHeader, SEEK_CUR) != 0) { + fprintf(stderr,"%s: Could not read COFF optional header from %s," + " is this a PE (COFF) file?\n", progname, filename); + fclose(f); + return 1; + } + + for (i = 0; i < filhdr.NumberOfSections; ++i) { + if (fread(&scnhdr, sizeof(scnhdr), 1, f) == 0) { + fprintf(stderr,"%s: Could not read section header from %s," + " is this a PE (COFF) file?\n", progname, filename); + fclose(f); + return 1; + } + v_printf("Section %s:\n", scnhdr.Name); + v_printf("Physical address: 0x%08x\n", scnhdr.Misc.PhysicalAddress); + v_printf("Size: 0x%08x\n", scnhdr.SizeOfRawData); + if (scnhdr.Misc.PhysicalAddress != 0 && + scnhdr.SizeOfRawData == 0) { + printf("Section header %s in file %s will confuse MSC linker, " + "virtual size is 0x%08x and raw size is 0\n", + scnhdr.Name, filename, scnhdr.Misc.PhysicalAddress, + scnhdr.SizeOfRawData); + if (edit) { + scnhdr.SizeOfRawData = scnhdr.Misc.PhysicalAddress; + scnhdr.Misc.PhysicalAddress = 0; + if (fseek(f, (long) -((long)sizeof(scnhdr)), SEEK_CUR) != 0 || + fwrite(&scnhdr, sizeof(scnhdr), 1, f) == 0) { + fprintf(stderr,"%s: could not edit file %s.\n", + progname, filename); + fclose(f); + return 1; + } + printf("Edited object, virtual size is now 0, and " + "raw size is 0x%08x.\n", scnhdr.SizeOfRawData); + } else { + printf("Specify option '-e' to correct the problem.\n"); + } + } + } + fclose(f); + return 0; +} + + +static int v_printf(char *format, ...) +{ + va_list ap; + int ret = 0; + if (verbouse) { + va_start(ap, format); + ret = vfprintf(stdout, format, ap); + va_end(ap); + } + return ret; +} + diff --git a/erts/etc/win32/cygwin_tools/vc/emu_cc.sh b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh new file mode 100755 index 0000000000..c74c35111b --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh @@ -0,0 +1,90 @@ +#! /bin/sh +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +TOOLDIR=$ERL_TOP/erts/etc/win32/cygwin_tools/vc +COFFIX=$TOOLDIR/coffix +WTOOLDIR=`(cygpath -d $TOOLDIR 2>/dev/null || cygpath -w $TOOLDIR)` + +# Do primitive 'make' +newer_exe=`find $TOOLDIR -newer $COFFIX.c -name coffix.exe -print` +if [ -z $newer_exe ]; then + echo recompiling $COFFIX.exe + cl.exe -Fe${WTOOLDIR}\\coffix.exe ${WTOOLDIR}\\coffix.c + rm -f $COFFIX.obj coffix.obj $COFFIX.pdb coffix.pdb +fi + +# Try to find out the output filename and remove it from command line +CMD="" +OUTFILE="" +INFILE="" +SKIP_COFFIX=false +while test -n "$1" ; do + x="$1" + case "$x" in + -o/*) + OUTFILE=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`;; + -o) + shift + OUTFILE=$1;; + -MM) + SKIP_COFFIX=true + CMD="$CMD \"$x\"";; + *.c) + INFILE="$INFILE $x"; + CMD="$CMD \"$x\"";; + *) + CMD="$CMD \"$x\"";; + esac + shift +done +if [ -z "$INFILE" ]; then + echo 'emu_cc.sh: please give an input filename for the compiler' >&2 + exit 1 +fi +if [ -z "$OUTFILE" ]; then + OUTFILE=`echo $INFILE | sed 's,\.c$,.o,'` +fi + +if [ $SKIP_COFFIX = false ]; then + n=`echo $INFILE | wc -w`; + if [ $n -gt 1 ]; then + echo "emu_cc.sh:Error, multiple sources, one object output."; + exit 1; + fi + TEMPFILE=/tmp/tmp_emu_cc$$.o + if [ "X$EMU_CC_SH_DEBUG_LOG" != "X" ]; then + echo "gcc -o $TEMPFILE -D__WIN32__ -DWIN32 -DWINDOWS -fomit-frame-pointer $CMD" >> $EMU_CC_SH_DEBUG_LOG 2>&1 + fi + eval gcc -o $TEMPFILE -D__WIN32__ -DWIN32 -DWINDOWS -fomit-frame-pointer $CMD + RES=$? + if [ $RES = 0 ]; then + $COFFIX.exe -e `(cygpath -d $TEMPFILE 2>/dev/null || cygpath -w $TEMPFILE)` + RES=$? + if [ $RES = 0 ]; then + cp $TEMPFILE $OUTFILE + else + echo "emu_cc.sh: fatal: coffix failed!" >&2 + fi + fi + rm -f $TEMPFILE + exit $RES +else + eval gcc -D__WIN32__ -DWIN32 -DWINDOWS -fomit-frame-pointer -fno-tree-copyrename $CMD 2>/dev/null + exit $? +fi diff --git a/erts/etc/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh new file mode 100755 index 0000000000..ac39bf871c --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/ld.sh @@ -0,0 +1,192 @@ +#! /bin/sh +# set -x +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# Save the command line for debug outputs +SAVE="$@" +kernel_libs="kernel32.lib advapi32.lib" +gdi_libs="gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib" +DEFAULT_LIBRARIES="$kernel_libs $gdi_libs" + +CMD="" +STDLIB=MSVCRT.LIB +DEBUG_BUILD=false +STDLIB_FORCED=false +BUILD_DLL=false +OUTPUT_FILENAME="" + +while test -n "$1" ; do + x="$1" + case "$x" in + -dll| -DLL) + BUILD_DLL=true;; + -L/*|-L.*) + y=`echo $x | sed 's,^-L\(.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -libpath:\"$MPATH\"";; + -lMSVCRT|-lmsvcrt) + STDLIB_FORCED=true; + STDLIB=MSVCRT.LIB;; + -lMSVCRTD|-lmsvcrtd) + STDLIB_FORCED=true; + STDLIB=MSVCRTD.LIB;; + -lLIBCMT|-llibcmt) + STDLIB_FORCED=true; + STDLIB=LIBCMT.LIB;; + -lLIBCMTD|-llibcmtd) + STDLIB_FORCED=true; + STDLIB=LIBCMTD.LIB;; + -lsocket) + DEFAULT_LIBRARIES="$DEFAULT_LIBRARIES WS2_32.LIB";; + -l*) + y=`echo $x | sed 's,^-l\(.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD \"${MPATH}.lib\"";; + -g) + DEBUG_BUILD=true;; + -pdb:none|-incremental:no) + ;; + -implib:*) + y=`echo $x | sed 's,^-implib:\(.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -implib:\"${MPATH}\"";; + -def:*) + y=`echo $x | sed 's,^-def:\(.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -def:\"${MPATH}\"";; + -o) + shift + MPATH=`cygpath -m $1`; + OUTPUT_FILENAME="$MPATH";; + -o/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + OUTPUT_FILENAME="$MPATH";; + /*) + MPATH=`cygpath -m $x`; + CMD="$CMD \"$MPATH\"";; + *) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD \"$y\"";; + esac + shift +done +if [ $DEBUG_BUILD = true ]; then + linktype="-debug -pdb:none" + if [ $STDLIB_FORCED = false ]; then + STDLIB=MSVCRTD.LIB + fi +fi +# Generate a PDB +linkadd_pdb="" +case "$OUTPUT_FILENAME" in + *.exe|*.EXE) + fn=`echo "$OUTPUT_FILENAME" | sed 's,[eE][xX][eE]$,,g'`; + linkadd_pdb="-pdb:\"${fn}pdb\"";; + *.dll|*.DLL) + fn=`echo "$OUTPUT_FILENAME" | sed 's,[dD][lL][lL]$,,g'`; + linkadd_pdb="-pdb:\"${fn}pdb\"";; + "") + linkadd_pdb="-pdb:\"a.pdb\"";; + *) + linkadd_pdb="-pdb:\"${OUTPUT_FILENAME}.pdb\"";; +esac + + linktype="-debug $linkadd_pdb" + +CHMOD_FILE="" + +if [ $BUILD_DLL = true ];then + case "$OUTPUT_FILENAME" in + *.exe|*.EXE) + echo "Warning, output set to .exe when building DLL" >&2 + CHMOD_FILE="$OUTPUT_FILENAME"; + CMD="-dll -out:\"$OUTPUT_FILENAME\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}\;2"; + MANIFEST="${OUTPUT_FILENAME}.manifest";; + *.dll|*.DLL) + CMD="-dll -out:\"$OUTPUT_FILENAME\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}\;2"; + MANIFEST="${OUTPUT_FILENAME}.manifest";; + "") + CMD="-dll -out:\"a.dll\" $CMD"; + OUTPUTRES="a.dll\;2"; + MANIFEST="a.dll.manifest";; + *) + CMD="-dll -out:\"${OUTPUT_FILENAME}.dll\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}.dll\;2"; + MANIFEST="${OUTPUT_FILENAME}.dll.manifest";; + esac +else + case "$OUTPUT_FILENAME" in + *.exe|*.EXE) + CHMOD_FILE="$OUTPUT_FILENAME"; + CMD="-out:\"$OUTPUT_FILENAME\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}\;1" + MANIFEST="${OUTPUT_FILENAME}.manifest";; + *.dll|*.DLL) + echo "Warning, output set to .dll when building EXE" >&2 + CMD="-out:\"$OUTPUT_FILENAME\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}\;1"; + MANIFEST="${OUTPUT_FILENAME}.manifest";; + "") + CHMOD_FILE="a.exe"; + CMD="-out:\"a.exe\" $CMD"; + OUTPUTRES="a.exe\;1"; + MANIFEST="a.exe.manifest";; + *) + CMD="-out:\"${OUTPUT_FILENAME}.exe\" $CMD"; + OUTPUTRES="${OUTPUT_FILENAME}.exe\;1"; + MANIFEST="${OUTPUT_FILENAME}.exe.manifest";; + esac +fi + +p=$$ +CMD="$linktype -nologo -incremental:no $CMD $STDLIB $DEFAULT_LIBRARIES" +if [ "X$LD_SH_DEBUG_LOG" != "X" ]; then + echo ld.sh "$SAVE" >>$LD_SH_DEBUG_LOG + echo link.exe $CMD >>$LD_SH_DEBUG_LOG +fi +eval link.exe "$CMD" >/tmp/link.exe.${p}.1 2>/tmp/link.exe.${p}.2 +RES=$? +CMANIFEST=`cygpath $MANIFEST` +if [ "$RES" = "0" -a -f "$CMANIFEST" ]; then + eval mt.exe -nologo -manifest "$MANIFEST" -outputresource:"$OUTPUTRES" >>/tmp/link.exe.${p}.1 2>>/tmp/link.exe.${p}.2 + RES=$? + if [ "$RES" != "0" ]; then + REMOVE=`echo "$OUTPUTRES" | sed 's,\\\;[12]$,,g'` + CREMOVE=`cygpath $REMOVE` + rm -f "$CREMOVE" + fi + rm -f "$CMANIFEST" +fi + +# This works around some strange behaviour +# in cygwin 1.7 Beta on Windows 7 with samba drive. +# Configure will think the compiler failed if test -x fails, +# which it might do as we might not be the owner of the +# file. +if [ '!' -z "$CHMOD_FILE" -a -s "$CHMOD_FILE" -a '!' -x "$CHMOD_FILE" ]; then + chmod +x $CHMOD_FILE +fi + +tail -n +2 /tmp/link.exe.${p}.2 >&2 +cat /tmp/link.exe.${p}.1 +rm -f /tmp/link.exe.${p}.2 /tmp/link.exe.${p}.1 +exit $RES diff --git a/erts/etc/win32/cygwin_tools/vc/ld_wrap.c b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c new file mode 100644 index 0000000000..7fb3c145ee --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c @@ -0,0 +1,796 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <dirent.h> +#include <sys/cygwin.h> + + + +#ifdef CCP_POSIX_TO_WIN_A +#define NEW_CYGPATH_INTERFACE +#endif + +#ifdef NEW_CYGPATH_INTERFACE +#define GET_WIN32_SIZE(Posix) \ +cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), NULL, 0) +#define CONVERT_TO_WIN32(Posix,Win32,Size) \ +cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), \ + (Win32), (Size)) +#else +#define GET_WIN32_SIZE(Posix) PATH_MAX +#define CONVERT_TO_WIN32(Posix,Win32,Size) \ +((cygwin32_conv_to_full_win32_path((Posix),(Win32)) >= 0) ? 0 : -1) +#endif + +/*#define HARDDEBUG 1*/ + +#ifdef HARDDEBUG +#define DEBUGF(X) printf X +#else +#define DEBUGF(X) /* noop */ +#endif +char *tmpobjdir = ""; + +char *add_to(char *src,char *add) { + int len = strlen(src)+strlen(add)+1; + char *n; + + if (strlen(src) == 0) { + n = malloc(len); + strcpy(n,add); + return n; + } + n = realloc(src,len); + strcat(n,add); + return n; +} + +void error(char *str) +{ + fprintf(stderr,"%s\n",str); + exit(1); +} + + +char *dyn_get_short(char *longp) +{ + int size; + char *shortp; + size = GetShortPathName(longp,NULL,0); + if (size <= 0) { + return NULL; + } + shortp = malloc(size); + if (GetShortPathName(longp,shortp,size) != size - 1) { + free(shortp); + return NULL; + } + return shortp; +} + +char *do_cyp(char *posix) +{ + ssize_t size; + char *win32; + size = GET_WIN32_SIZE(posix); + char *ret = NULL; + if (size < 0) { + fprintf(stderr,"Could not cygpath %s, errno = %d\n", + posix,errno); + } else { + win32 = (char *) malloc (size); + if (CONVERT_TO_WIN32(posix, + win32, size)) { + fprintf(stderr,"Could not cygpath %s, errno = %d\n", + posix,errno); + } else { + char *w32_short = dyn_get_short(win32); + DEBUGF(("win32 = %s, w32_short = %s\n",win32, (w32_short == NULL) ? "NULL" : w32_short)); + if (w32_short == NULL) { + char *rest = malloc(size); + char *first = malloc(size); + int x = 0; + int y = strlen(win32) - 1; + strcpy(first,win32); + while (w32_short == NULL) { + while ( y > 0 && first[y] != '\\') { + rest[x++] = first[y--]; + } + if (y > 0) { + rest[x++] = first[y]; + first[y--] = '\0'; + } else { + break; + } + w32_short = dyn_get_short(first); + DEBUGF(("first = %s, w32_short = %s\n",first, (w32_short == NULL) ? "NULL" : w32_short)); + } + if (w32_short != NULL) { + y = strlen(w32_short); + w32_short = realloc(w32_short,y+1+x); + /* spool back */ + while ( x > 0) { + w32_short[y++] = rest[--x]; + } + w32_short[y] = '\0'; + } else { + w32_short = malloc(strlen(win32)+1); + strcpy(w32_short,win32); /* last resort */ + } + free(first); + free(rest); + } + ret = w32_short; + while (*ret) { + if (*ret == '\\') { + *ret = '/'; + } + ++ret; + } + ret = w32_short; + } + free(win32); + } + return ret; +} + + + +char *save = ""; + +void save_args(int argc, char **argv) +{ + int i; + for(i = 0; i < argc; ++i) { + save = add_to(save,argv[i]); + save = add_to(save," "); + } +} + +char *progname="ld_wrap"; + +int my_create_pipe(HANDLE *read_p, HANDLE *write_p) +{ + char name_buff[1000]; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + static int counter = 0; + + ++counter; + + sprintf(name_buff,"\\\\.\\pipe\\%s_%d_%d",progname,getpid(),counter); + sa.bInheritHandle = FALSE; + if ((*read_p = CreateNamedPipe(name_buff, + PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + 1, + 0, + 0, + 2000, + &sa)) == INVALID_HANDLE_VALUE || + *read_p == NULL) { + return 0; + } + sa.bInheritHandle = TRUE; + if ((*write_p = CreateFile(name_buff, + GENERIC_WRITE, + 0, /* No sharing */ + &sa, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE || + *write_p == NULL) { + CloseHandle(*read_p); + return 0; + } + return 1; +} + +void forwardenv(void) +{ + char *(envs[]) = {"LIB","INCLUDE","LIBPATH", NULL}; + char **p = envs; + while (*p != NULL) { + char *val = getenv(*p); + if (val != NULL) { + SetEnvironmentVariable(*p,val); + } + ++p; + } +} + +HANDLE do_run(char *commandline, HANDLE *out, HANDLE *err) +{ + STARTUPINFO start; + HANDLE write_pipe_stdout = NULL, read_pipe_stdout = NULL; + HANDLE write_pipe_stderr = NULL, read_pipe_stderr = NULL; + SECURITY_ATTRIBUTES pipe_security; + SECURITY_ATTRIBUTES attr; + PROCESS_INFORMATION info; + + + memset(&start,0,sizeof(start)); + memset(&pipe_security,0,sizeof(pipe_security)); + memset(&attr,0,sizeof(attr)); + memset(&info,0,sizeof(info)); + + + pipe_security.nLength = sizeof(pipe_security); + pipe_security.lpSecurityDescriptor = NULL; + pipe_security.bInheritHandle = TRUE; + + if(!my_create_pipe(&read_pipe_stdout,&write_pipe_stdout)){ + error("Could not create stdout pipes!"); + } + if(!my_create_pipe(&read_pipe_stderr,&write_pipe_stderr)){ + error("Could not create stderr pipes!"); + } + start.cb = sizeof (start); + start.dwFlags = STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + start.hStdOutput = write_pipe_stdout; + start.hStdError = write_pipe_stderr; + start.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + start.dwFlags |= STARTF_USESTDHANDLES; + + attr.nLength = sizeof(attr); + attr.lpSecurityDescriptor = NULL; + attr.bInheritHandle = TRUE; + forwardenv(); /* Cygwin and windows environment variables... sigh... */ + if(!CreateProcess(NULL, + commandline, + &attr, + NULL, + TRUE, + CREATE_DEFAULT_ERROR_MODE, + NULL, + NULL, + &start, + &info)){ + error("Could not create process"); + } + *out = read_pipe_stdout; + *err = read_pipe_stderr; + CloseHandle(write_pipe_stdout); + CloseHandle(write_pipe_stderr); + return info.hProcess; +} +#define HANDLE_STDOUT 0 +#define HANDLE_STDERR 1 +#define HANDLE_PROC 2 + +#ifdef HARDDEBUG +char *prefix = ""; +#endif + +int handle_overlapped(HANDLE fd, OVERLAPPED *ovp, char *buffer, + int bufflen, int get_old, FILE *whereto, int *skip) +{ + DWORD res,read,err; + char *ptr; + + DEBUGF(("In handle_overlapped(%d,0x%08x,0x%08x,%d,%d), prefix = %s\n", + fd,ovp,buffer,bufflen,get_old,prefix)); + /* h�mta resultat av gamla f�rst */ + if (get_old) { + res = GetOverlappedResult(fd,ovp,&read,TRUE); + DEBUGF(("read = %d, res = %d, GetLastError() = %d\n",read,res,GetLastError())); + if (!res) { + return 0; + } + buffer[read] = '\0'; + ptr = buffer; + while(*skip && *ptr != '\0') { + if (*ptr == '\n') { + --(*skip); + } + ++ptr; + } + if(*ptr != '\0') { + fprintf(whereto,"%s",ptr); + } + } + + ResetEvent(ovp->hEvent); + + for(;;) { + res = ReadFile(fd,buffer,bufflen-1,&read,ovp); + + if (!res) { + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + DEBUGF(("Error I/O Pending\n")); + return 1; + } + DEBUGF(("ReadFileFailed for %s, %d\n",prefix,err)); + return 0; + } + buffer[read] = '\0'; + ptr = buffer; + while(*skip && *ptr != '\0') { + if (*ptr == '\n') { + --(*skip); + } + ++ptr; + } + if(*ptr != '\0') { + fprintf(whereto,"%s",ptr); + } + } +} + + +int run(char *commandline,int skipout,int skiperr) +{ + HANDLE harr[3]; + HANDLE real_stdout,real_stderr; + OVERLAPPED ov_out,ov_err; + char outbuff[1024],errbuff[1024]; + DWORD ret,exitcode; + HANDLE wait[3]; + int map[3]; + DWORD nwait = 3; + int i,j; + unsigned living_handles = 0x7; + + harr[HANDLE_STDOUT] = CreateEvent(NULL, + TRUE, + FALSE, /*not signalled */ + NULL); + harr[HANDLE_STDERR] = CreateEvent(NULL, + TRUE, + FALSE,/*not signalled */ + NULL); + + memset(&ov_out,0,sizeof(ov_out)); + memset(&ov_err,0,sizeof(ov_err)); + + ov_out.hEvent = harr[HANDLE_STDOUT]; + ov_err.hEvent = harr[HANDLE_STDERR]; + + harr[HANDLE_PROC] = do_run(commandline,&real_stdout,&real_stderr); + +#ifdef HARDDEBUG + prefix = "STDOUT"; +#endif + handle_overlapped(real_stdout,&ov_out,outbuff,1024,0,stdout,&skipout); +#ifdef HARDDEBUG + prefix = "STDERR"; +#endif + handle_overlapped(real_stderr,&ov_err,errbuff,1024,0,stderr,&skiperr); + + for(;;) { + nwait = 0; + for(i=0;i<3;++i) { + if ((living_handles & (1U << i))) { + map[nwait] = i; + wait[nwait++] = harr[i]; + } + } + + ret = WaitForMultipleObjects(nwait, + wait, + FALSE, + INFINITE); + DEBUGF(("Wait returned %d\n",ret)); + + if (ret == WAIT_FAILED) { + error("Wait failed"); + } + + ret -= WAIT_OBJECT_0; + + switch (map[ret]) { + case HANDLE_PROC: + + DEBUGF(("Process died!\n")); + GetExitCodeProcess(harr[HANDLE_PROC],&exitcode); + if ((living_handles &= (~(1U<<HANDLE_PROC))) == 0) { + goto done; + } + --nwait; + break; + case HANDLE_STDOUT: +#ifdef HARDDEBUG + prefix = "STDOUT"; +#endif + if (!handle_overlapped(real_stdout,&ov_out, outbuff,1024,1,stdout,&skipout)) { + if ((living_handles &= (~(1U<<HANDLE_STDOUT))) == 0) { + goto done; + } + } + break; + case HANDLE_STDERR: +#ifdef HARDDEBUG + prefix = "STDERR"; +#endif + if (!handle_overlapped(real_stderr,&ov_err, errbuff,1024,1,stderr,&skiperr)){ + if ((living_handles &= (~(1U<<HANDLE_STDERR))) == 0) { + goto done; + } + } + break; + default: + error("Unexpected wait result"); + } + } + done: + CloseHandle(harr[HANDLE_PROC]); + CloseHandle(harr[HANDLE_STDOUT]); + CloseHandle(harr[HANDLE_STDERR]); + CloseHandle(real_stdout); + CloseHandle(real_stderr); + return (int) exitcode; +} + +int main(int argc, char **argv) +{ + int i; + int x; + char *s; + char *mpath; + char *debuglog; + char *remove; + FILE *debugfile; + FILE *tmpfile; + int filefound; + int retval = 0; + + char *kernel_libs="kernel32.lib advapi32.lib"; + char *gdi_libs="gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib"; + char *default_libraries = ""; + char *cmd = ""; + char *stdlib = "MSVCRT.LIB"; + int debug_build = 0; + int stdlib_forced = 0; + int build_dll = 0; + char *output_filename = ""; + char *linkadd_pdb = ""; + char *linktype = ""; + char *manifest = ""; + char *outputres = ""; + + save_args(argc,argv); + //fprintf(stderr,"ld_wrap!\n"); + + default_libraries = add_to(default_libraries,kernel_libs); + default_libraries = add_to(default_libraries," "); + default_libraries = add_to(default_libraries,gdi_libs); + + for(i = 1; i < argc; ++i) { + if (argv[i][0] == '-') { + char *opt = argv[i]+1; + switch(*opt) { + case 'D': + if(strcmp(opt,"DLL")) { + goto filename; + } + build_dll = 1; + break; + case 'd': + if(!strncmp(opt,"def:",4)) { + mpath = do_cyp(opt+4); + cmd = add_to(cmd," -def:\""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + } else if(strcmp(opt,"dll")) { + goto filename; + } else { + build_dll = 1; + } + break; + case 'L': + mpath = do_cyp(opt+1); + cmd = add_to(cmd," -libpath:\""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + break; + case 'l': + if(!strcmp(opt,"lMSVCRT") || !strcmp(opt,"lmsvcrt")) { + stdlib = "MSVCRT.LIB"; + stdlib_forced = 1; + } else if(!strcmp(opt,"lMSVCRTD") || !strcmp(opt,"lmsvcrtd")) { + stdlib = "MSVCRTD.LIB"; + stdlib_forced = 1; + } else if(!strcmp(opt,"lLIBCMT") || !strcmp(opt,"llibcmt")) { + stdlib = "LIBCMT.LIB"; + stdlib_forced = 1; + } else if(!strcmp(opt,"lLIBCMTD") || !strcmp(opt,"llibcmtd")) { + stdlib = "LIBCMTD.LIB"; + stdlib_forced = 1; + } else if(!strcmp(opt,"lsocket")) { + default_libraries = add_to(default_libraries," "); + default_libraries = add_to(default_libraries,"WS2_32.LIB"); + } else { + mpath = do_cyp(opt+1); + cmd = add_to(cmd," \""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + } + break; + case 'g': + debug_build = 1; + break; + case 'p': + if (strcmp(opt,"pdb:none")) { + goto filename; + } + break; + case 'i': + if (!strncmp(opt,"implib:",7)) { + mpath = do_cyp(opt+7); + cmd = add_to(cmd," -implib:\""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + } else if (strcmp(opt,"incremental:no")) { + goto filename; + } + break; + case 'o': + if (!strcmp(opt,"o")) { + ++i; + if (i >= argc) { + error("-o without filename"); + } + output_filename = do_cyp(argv[i]); + } else { + output_filename = do_cyp(opt+1); + } + break; + default: + goto filename; + } + continue; + } + filename: + s = argv[i]; + if (*s == '/') { + mpath = do_cyp(s); + cmd = add_to(cmd," \""); + cmd = add_to(cmd,mpath); + cmd = add_to(cmd,"\""); + free(mpath); + } else { + cmd = add_to(cmd," \""); + cmd = add_to(cmd,s); + cmd = add_to(cmd,"\""); + } + } + if ((debuglog = getenv("LD_SH_DEBUG_LOG")) != NULL) { + debugfile = fopen(debuglog,"wb+"); + if (debugfile) { + fprintf(debugfile,"----------------\n"); + } + } else { + debugfile = NULL; + } + + if (debug_build) { + if (!stdlib_forced) { + stdlib = "MSVCRTD.LIB"; + } + } + + s = add_to("",output_filename); + x = strlen(s); + + if (x >= 4 && (!strcmp(s+x-4,".exe") || !strcmp(s+x-4,".EXE") || + !strcmp(s+x-4,".dll") || !strcmp(s+x-4,".DLL"))) { + *(s+x-3) = '\0'; + linkadd_pdb = add_to(linkadd_pdb,"-pdb:\""); + linkadd_pdb = add_to(linkadd_pdb,s); + linkadd_pdb = add_to(linkadd_pdb,"pdb\""); + } else if (!x) { + linkadd_pdb = add_to(linkadd_pdb,"-pdb:\"a.pdb\""); + } else { + linkadd_pdb = add_to(linkadd_pdb,"-pdb:\""); + linkadd_pdb = add_to(linkadd_pdb,s); + linkadd_pdb = add_to(linkadd_pdb,".pdb\""); + } + free(s); + + + linktype = add_to(linktype,"-debug "); + linktype = add_to(linktype,linkadd_pdb); + + free(linkadd_pdb); + + s = add_to("",output_filename); + x = strlen(s); + + if (build_dll) { + if (x >= 4 && (!strcmp(s+x-4,".exe") || !strcmp(s+x-4,".EXE") || + !strcmp(s+x-4,".dll") || !strcmp(s+x-4,".DLL"))) { + + if (!strcmp(s+x-4,".exe") || !strcmp(s+x-4,".EXE")) { + fprintf(stderr,"Warning, output set to .exe when building DLL"); + } + mpath = cmd; + cmd = add_to("","-dll -out:\""); + cmd = add_to(cmd,s); + cmd = add_to(cmd,"\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,output_filename); + outputres = add_to(outputres,";2"); + manifest = add_to(manifest,output_filename); + manifest = add_to(manifest,".manifest"); + } else if (x == 0) { + mpath = cmd; + cmd = add_to("","-dll -out:\"a.dll\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,"a.dll;2"); + manifest = add_to(manifest,"a.dll.manifest"); + } else { + mpath = cmd; + cmd = add_to("","-dll -out:\""); + cmd = add_to(cmd,s); + cmd = add_to(cmd,".dll\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,output_filename); + outputres = add_to(outputres,".dll;2"); + manifest = add_to(manifest,output_filename); + manifest = add_to(manifest,".dll.manifest"); + } + } else { + if (x >= 4 && (!strcmp(s+x-4,".exe") || !strcmp(s+x-4,".EXE") || + !strcmp(s+x-4,".dll") || !strcmp(s+x-4,".DLL"))) { + + if (!strcmp(s+x-4,".dll") || !strcmp(s+x-4,".DLL")) { + fprintf(stderr,"Warning, output set to .exe when building DLL"); + } + mpath = cmd; + cmd = add_to("","-out:\""); + cmd = add_to(cmd,s); + cmd = add_to(cmd,"\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,output_filename); + outputres = add_to(outputres,";1"); + manifest = add_to(manifest,output_filename); + manifest = add_to(manifest,".manifest"); + } else if (x == 0) { + mpath = cmd; + cmd = add_to("","-out:\"a.exe\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,"a.exe;1"); + manifest = add_to(manifest,"a.exe.manifest"); + } else { + mpath = cmd; + cmd = add_to("","-out:\""); + cmd = add_to(cmd,s); + cmd = add_to(cmd,".exe\" "); + cmd = add_to(cmd,mpath); + if (*mpath) { + free(mpath); + } + + outputres = add_to(outputres,output_filename); + outputres = add_to(outputres,".exe;1"); + manifest = add_to(manifest,output_filename); + manifest = add_to(manifest,".exe.manifest"); + } + } + + s = cmd; + cmd = add_to("","link.exe "); + cmd = add_to(cmd,linktype); + cmd = add_to(cmd," -nologo -incremental:no "); + cmd = add_to(cmd,s); + cmd = add_to(cmd," "); + cmd = add_to(cmd,stdlib); + cmd = add_to(cmd," "); + cmd = add_to(cmd,default_libraries); + + if (*s) { + free(s); + } + + + if (debugfile) { + fprintf(debugfile,"%s\n",save); + fprintf(debugfile,"%s\n",cmd); + } + + retval = run(cmd,0,0); + + + mpath = do_cyp(manifest); + filefound = 0; + tmpfile = fopen(mpath,"rb"); + if (tmpfile != NULL) { + filefound = 1; + fclose(tmpfile); + } + if (retval == 0 && filefound) { + s = add_to("","mt.exe -nologo -manifest \""); + s = add_to(s,manifest); + s = add_to(s,"\" -outputresource:\""); + s = add_to(s,outputres); + s = add_to(s,"\""); + if (debugfile) { + fprintf(debugfile,"%s\n",s); + } + retval = run(s,0,0); + if (*s) { + free(s); + } + if (retval) { + /* cleanup needed */ + remove = add_to("",outputres); + x = strlen(remove); + remove[x-2] = '\0'; + if (debugfile) { + fprintf(debugfile,"remove %s\n",remove); + } + DeleteFile(remove); + free(remove); + } + if (debugfile) { + fprintf(debugfile,"remove %s\n",manifest); + } + DeleteFile(manifest); + } + return retval; +} + + + + + + + + + + + + + + + + + + diff --git a/erts/etc/win32/cygwin_tools/vc/mc.sh b/erts/etc/win32/cygwin_tools/vc/mc.sh new file mode 100755 index 0000000000..813b59947b --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/mc.sh @@ -0,0 +1,87 @@ +#! /bin/sh +# set -x +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# Save the command line for debug outputs +SAVE="$@" +CMD="" +OUTPUT_DIRNAME="" + +# Find the correct mc.exe. This could be done by the configure script, +# But as we seldom use the resource compiler, it might as well be done here... +MCC="" +save_ifs=$IFS +IFS=: +for p in $PATH; do + if [ -f $p/mc.exe ]; then + if [ -n "`$p/mc.exe -? 2>&1 >/dev/null </dev/null \ + | grep -i \"message compiler\"`" ]; then + MCC=$p/mc.exe + fi + fi +done +IFS=$save_ifs + +if [ -z "$MCC" ]; then + echo 'mc.exe not found!' >&2 + exit 1 +fi + +while test -n "$1" ; do + x="$1" + case "$x" in + -o) + shift + OUTPUT_DIRNAME="$1";; + -o/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + OUTPUT_DIRNAME="$y";; + -I) + shift + MPATH=`cygpath -m $1`; + CMD="$CMD -I\"$MPATH\"";; + -I/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -I\"$MPATH\"";; + *) + MPATH=`cygpath -m -a $x`; + CMD="$CMD \"$MPATH\"";; + esac + shift +done +p=$$ +if [ "X$MC_SH_DEBUG_LOG" != "X" ]; then + echo rc.sh "$SAVE" >>$MC_SH_DEBUG_LOG + echo rc.exe $CMD >>$MC_SH_DEBUG_LOG +fi +if [ -n "$OUTPUT_DIRNAME" ]; then + cd $OUTPUT_DIRNAME + RES=$? + if [ "$RES" != "0" ]; then + echo "mc.sh: Error: could not cd to $OUTPUT_DIRNAME">&2 + exit $RES + fi +fi +eval $MCC "$CMD" >/tmp/mc.exe.${p}.1 2>/tmp/mc.exe.${p}.2 +RES=$? +tail +2 /tmp/mc.exe.${p}.2 >&2 +cat /tmp/mc.exe.${p}.1 +rm -f /tmp/mc.exe.${p}.2 /tmp/mc.exe.${p}.1 +exit $RES diff --git a/erts/etc/win32/cygwin_tools/vc/rc.sh b/erts/etc/win32/cygwin_tools/vc/rc.sh new file mode 100755 index 0000000000..748de48890 --- /dev/null +++ b/erts/etc/win32/cygwin_tools/vc/rc.sh @@ -0,0 +1,86 @@ +#! /bin/sh +# set -x +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# Save the command line for debug outputs +SAVE="$@" +CMD="" +OUTPUT_FILENAME="" + +# Find the correct rc.exe. This could be done by the configure script, +# But as we seldom use the resource compiler, it might as well be done here... +RCC="" +save_ifs=$IFS +IFS=: +for p in $PATH; do + if [ -f $p/rc.exe ]; then + if [ -n "`$p/rc.exe -? 2>&1 | grep -i "resource compiler"`" ]; then + RCC=$p/rc.exe + fi + fi +done +IFS=$save_ifs + +if [ -z "$RCC" ]; then + echo 'rc.exe not found!' >&2 + exit 1 +fi + +while test -n "$1" ; do + x="$1" + case "$x" in + -o) + shift + MPATH=`cygpath -m $1`; + OUTPUT_FILENAME="$MPATH";; + -o/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + OUTPUT_FILENAME="$MPATH";; + -I) + shift + MPATH=`cygpath -m $1`; + CMD="$CMD -I\"$MPATH\"";; + -I/*) + y=`echo $x | sed 's,^-[Io]\(/.*\),\1,g'`; + MPATH=`cygpath -m $y`; + CMD="$CMD -I\"$MPATH\"";; + /*) + MPATH=`cygpath -m $x`; + CMD="$CMD \"$MPATH\"";; + *) + y=`echo $x | sed 's,",\\\",g'`; + CMD="$CMD \"$y\"";; + esac + shift +done +p=$$ +if [ -n "$OUTPUT_FILENAME" ]; then + CMD="-Fo$OUTPUT_FILENAME $CMD" +fi +if [ "X$RC_SH_DEBUG_LOG" != "X" ]; then + echo rc.sh "$SAVE" >>$RC_SH_DEBUG_LOG + echo rc.exe $CMD >>$RC_SH_DEBUG_LOG +fi +eval $RCC "$CMD" >/tmp/rc.exe.${p}.1 2>/tmp/rc.exe.${p}.2 +RES=$? +tail +2 /tmp/rc.exe.${p}.2 >&2 +cat /tmp/rc.exe.${p}.1 +rm -f /tmp/rc.exe.${p}.2 /tmp/rc.exe.${p}.1 +exit $RES |