aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/win32/cygwin_tools/vc
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /erts/etc/win32/cygwin_tools/vc
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'erts/etc/win32/cygwin_tools/vc')
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/ar.sh47
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/cc.sh321
-rw-r--r--erts/etc/win32/cygwin_tools/vc/cc_wrap.c864
-rw-r--r--erts/etc/win32/cygwin_tools/vc/coffix.c161
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/emu_cc.sh90
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/ld.sh192
-rw-r--r--erts/etc/win32/cygwin_tools/vc/ld_wrap.c796
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/mc.sh87
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/rc.sh86
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