win32: support MinGW build

A MinGW build is the same shape as a MSVC build (but without
MzCOM), unlike a Cygwin build.
This commit is contained in:
Matthew Flatt 2012-12-07 07:58:40 -06:00
parent 8907daf65f
commit 5b016b4c32
36 changed files with 624 additions and 234 deletions

View File

@ -418,6 +418,13 @@
(printf "xform-cpp: ~a\n" args)
(apply f args))))
(define (maybe-add-exe p)
(cond
[(and (eq? 'windows (system-type))
(not (regexp-match? #rx"[.]exe$" p)))
(format "~a.exe" p)]
[else p]))
;; To run cpp:
(define process2
(if (eq? (system-type) 'windows)
@ -427,7 +434,7 @@
(if m
(cons (cadr m) (loop (caddr m)))
(list s))))])
(apply (verbose process*) (find-executable-path (car split) #f)
(apply (verbose process*) (find-executable-path (maybe-add-exe (car split)) #f)
(cdr split))))
(verbose process)))
@ -875,7 +882,8 @@
__get_errno_ptr ; QNX preprocesses errno to __get_errno_ptr
strlen cos sin exp pow log sqrt atan2
isnan isinf fpclass _fpclass _isnan __isfinited __isnanl __isnan
isnan isinf fpclass _fpclass __fpclassify __fpclassifyf __fpclassifyl
_isnan __isfinited __isnanl __isnan
__isinff __isinfl isnanf isinff __isinfd __isnanf __isnand __isinf
floor ceil round fmod modf fabs __maskrune _errno __errno
isalpha isdigit isspace tolower toupper
@ -1646,24 +1654,29 @@
;; recognize a function prototype:
(define (proc-prototype? e)
(let ([l (length e)])
(let loop ([l (length e)])
(and (> l 2)
;; Ends in semicolon
(eq? semi (tok-n (list-ref e (sub1 l))))
(or (and
;; next-to-last is parens
(parens? (list-ref e (- l 2)))
;; Symbol before parens, not '=
(let ([s (tok-n (list-ref e (- l 3)))])
(and (symbol? s)
(not (eq? '= s)))))
(and
;; next-to-last is 0, then =, then parens
(eq? 0 (tok-n (list-ref e (- l 2))))
(eq? '= (tok-n (list-ref e (- l 3))))
(parens? (list-ref e (- l 4)))
;; Symbol before parens
(symbol? (tok-n (list-ref e (- l 5)))))))))
(let loop ([l l])
(or (and
(> l 2)
;; next-to-last is parens
(parens? (list-ref e (- l 2)))
;; Symbol before parens, not '= or '__attribute__
(let ([s (tok-n (list-ref e (- l 3)))])
(and (symbol? s)
(not (eq? '= s))
(not (eq? '__attribute__ s)))))
(and
;; next-to-last is 0, then =, then parens
(eq? 0 (tok-n (list-ref e (- l 2))))
(eq? '= (tok-n (list-ref e (- l 3))))
(loop (- l 2)))
(and
;; next-to-last is 0, then =, then parens
(eq? '__attribute__ (tok-n (list-ref e (- l 3))))
(loop (- l 2))))))))
;; recognize a typedef:
(define (typedef? e)
@ -1790,8 +1803,13 @@
(cond
[(eq? '__declspec (tok-n (car e)))
(loop (cddr e) type)]
[(eq? '__attribute__ (tok-n (car e)))
(loop (cddr e) type)]
[(parens? (cadr e))
(let ([name (tok-n (car e))]
(let ([name (tok-n (let ([p (car e)])
(if (parens? p)
(car (seq->list (seq-in p)))
p)))]
[type (let loop ([t (reverse type)])
(if (pair? t)
(if (or (memq (tok-n (car t)) '(extern static virtual __stdcall __cdecl

View File

@ -119,19 +119,21 @@
(define wind-proc-ptr (function-ptr wind-proc _WndProc))
(define-user32 CallWindowProcW (_wfun _fpointer _HWND _UINT _WPARAM _LPARAM -> _LRESULT))
(define (control-proc w msg wParam lParam)
(let ([default-ctlproc (hwnd->ctlproc w)])
(let ([default-ctlproc (hwnd->ctlproc-fptr w)])
(if (= msg WM_DESTROY)
(begin
(SetWindowLongPtrW w GWLP_WNDPROC (hwnd->ctlproc-fptr w))
(unregister-hwnd! w)
(default-ctlproc w msg wParam lParam))
(CallWindowProcW default-ctlproc w msg wParam lParam))
(let ([wx (hwnd->wx w)])
(if wx
(send wx ctlproc w msg wParam lParam
(lambda (w msg wParam lParam)
(default-ctlproc w msg wParam lParam)))
(default-ctlproc w msg wParam lParam))))))
(CallWindowProcW default-ctlproc w msg wParam lParam)))
(CallWindowProcW default-ctlproc w msg wParam lParam))))))
(define control_proc (function-ptr control-proc _WndProc))

View File

@ -115,7 +115,7 @@
(test "(1234567890 1 2 3 4)" pretty-format '(1234567890 1 2 3 4))
(test "(1234567890xx\n 1\n 2\n 3\n 4)" pretty-format '(1234567890xx 1 2 3 4))
(test "#(1234567890xx\n 1\n 2\n 3\n 4)" pretty-format (vector '1234567890xx 1 2 3 4))
(test "#fx(1234567890\n 1\n 2\n 3\n 4)" pretty-format (fxvector 1234567890 1 2 3 4))
(test "#fx(123456789\n 1\n 2\n 3\n 4)" pretty-format (fxvector 123456789 1 2 3 4))
(test "#fl(1234567890.0\n 1.0\n 2.0\n 3.0\n 4.0)" pretty-format (flvector 1234567890.0 1.0 2.0 3.0 4.0))
(test "#s(apple\n 1234567890xx\n 1\n 2\n 3\n 4)" pretty-format #s(apple 1234567890xx 1 2 3 4))
(test "#(struct:a\n 1234567890xx\n 1)" pretty-format (make-a '1234567890xx 1))
@ -177,7 +177,7 @@
(parameterize ([pretty-print-columns 20]
[print-as-expression #t])
(test "(fxvector\n 1234567890\n 1\n 2\n 3\n 4)" pretty-format (fxvector 1234567890 1 2 3 4))
(test "(fxvector\n 123456789\n 1\n 2\n 3\n 4)" pretty-format (fxvector 123456789 1 2 3 4))
(test "(flvector\n 1234567890.0\n 1.0\n 2.0\n 3.0\n 4.0)" pretty-format (flvector 1234567890.0 1.0 2.0 3.0 4.0)))
(parameterize ([pretty-print-exact-as-decimal #t])

View File

@ -81,7 +81,10 @@ plain-install:
install-common-first:
mkdir -p $(ALLDIRINFO)
@RUN_RACKET_CGC@ -c "$(srcdir)/get-libs.rkt" core "$(DESTDIR)$(libpltdir)"
@RUN_RACKET_CGC@ -c "$(srcdir)/get-libs.rkt" math "$(DESTDIR)$(libpltdir)"
@RUN_RACKET_CGC@ -c "$(srcdir)/get-libs.rkt" db "$(DESTDIR)$(libpltdir)"
@RUN_RACKET_CGC@ -c "$(srcdir)/get-libs.rkt" com "$(DESTDIR)$(libpltdir)"
install-common-middle:
$(MAKE) @MAKE_COPYTREE@-run

View File

@ -25,6 +25,12 @@ Please report bugs via one of the following:
To compile with Microsoft Visual C, read the instructions in
"racket\src\worksp\README".
To compile with MinGW tools, follow the Unix instructions below; do not
use `--enable-shared', because DLLs will be generated automatically.
The result is a Windows-style build, but without MzCOM. If you are using
a variant of MinGW without "libdelayimp.a", get the implementation of
"delayimp.c" from MinGW-w64 and compile it to "libdelayimp.a".
To compile with Cygwin tools, follow the Unix instructions below, and be
sure to configure with `--enable-shared'. The result is a Unix-style
build, not a Windows-style build (e.g., Racket's `system-type' procedure
@ -77,7 +83,7 @@ but note the following:
use `--disable-mac64'.
========================================================================
Compiling for supported Unix variants (including Linux) or Cygwin
Compiling for supported Unix variants (including Linux) or Cygwin/MinGW
========================================================================
Quick instructions:

58
src/configure vendored
View File

@ -703,10 +703,13 @@ GCDIR
XFORMFLAGS
MZBINTARGET
MZINSTALLTARGET
MZINSTALLBINDIR
EXTRA_GMP_OBJ
EXTRA_GMP_DEP
OSX
NOT_OSX
MINGW
NOT_MINGW
FRAMEWORK_INSTALL_DIR
FRAMEWORK_REL_INSTALL
FRAMEWORK_PREFIX
@ -2180,6 +2183,10 @@ if test "${enable_shared}" = "yes" ; then
exit 1
fi
;;
mingw*)
echo "ERROR: don't use --enable-shared or --enable-dynlib with mingw"
exit 1
;;
esac
fi
@ -2368,6 +2375,7 @@ GCDIR=gc
MZBINTARGET=normal-bin
MZINSTALLTARGET=unix-install
MZINSTALLBINDIR='$(bindir)'
MZOPTIONS=
CGCOPTIONS=
@ -2403,6 +2411,7 @@ INSTALL_SETUP_FLAGS=
STRIP_DEBUG=":"
use_flag_pthread=yes
skip_iconv_check=no
###### OSKit stuff #######
@ -3927,6 +3936,8 @@ EXTRA_GMP_DEP=
# For Racket targets:
OSX=".osx"
NOT_OSX=""
MINGW=".mingw"
NOT_MINGW=""
CGC_X86_64=""
case "$host_os" in
@ -4010,6 +4021,23 @@ case "$host_os" in
MZOPTIONS="$MZOPTIONS +e"
fi
LIBS="$LIBS -Wl,-E"
;;
mingw*)
enable_parallel_by_default=yes
use_flag_pthread=no
MZOPTIONS="$MZOPTIONS -fno-omit-framepointer" # to make JIT backtraces work
MINGW=""
NOT_MINGW=".other"
MZINSTALLTARGET=mingw-install
MZINSTALLBINDIR="${MZINSTALLBINDIR}/.."
EXE_SUFFIX=".exe"
COLLECTS_PATH="collects"
skip_iconv_check=yes
cat >>confdefs.h <<\_ACEOF
#define HAVE_STDINT_H 1
_ACEOF
;;
cygwin*)
enable_cgcdefault="yes"
@ -4440,7 +4468,8 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
echo "${ECHO_T}$have_getaddrinfo" >&6; }
iconv_lib_flag=""
if test "${enable_iconv}" = "yes" ; then
if test "${skip_iconv_check}" = "no" ; then
if test "${enable_iconv}" = "yes" ; then
{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
@ -5091,15 +5120,16 @@ fi
fi
fi
fi
fi
msg="iconv is usable"
{ echo "$as_me:$LINENO: checking $msg" >&5
fi
msg="iconv is usable"
{ echo "$as_me:$LINENO: checking $msg" >&5
echo $ECHO_N "checking $msg... $ECHO_C" >&6; }
iconv_usage_result="$enable_iconv$iconv_lib_flag"
{ echo "$as_me:$LINENO: result: $iconv_usage_result" >&5
iconv_usage_result="$enable_iconv$iconv_lib_flag"
{ echo "$as_me:$LINENO: result: $iconv_usage_result" >&5
echo "${ECHO_T}$iconv_usage_result" >&6; }
if test "${enable_iconv}" = "no" ; then
if test "${enable_iconv}" = "no" ; then
MZOPTIONS="$MZOPTIONS -DMZ_NO_ICONV"
fi
fi
msg="for mbsrtowcs"
@ -8962,6 +8992,9 @@ LIBS="$LIBS $EXTRALIBS"
@ -9743,14 +9776,14 @@ GCDIR!$GCDIR$ac_delim
XFORMFLAGS!$XFORMFLAGS$ac_delim
MZBINTARGET!$MZBINTARGET$ac_delim
MZINSTALLTARGET!$MZINSTALLTARGET$ac_delim
MZINSTALLBINDIR!$MZINSTALLBINDIR$ac_delim
EXTRA_GMP_OBJ!$EXTRA_GMP_OBJ$ac_delim
EXTRA_GMP_DEP!$EXTRA_GMP_DEP$ac_delim
OSX!$OSX$ac_delim
NOT_OSX!$NOT_OSX$ac_delim
MINGW!$MINGW$ac_delim
NOT_MINGW!$NOT_MINGW$ac_delim
FRAMEWORK_INSTALL_DIR!$FRAMEWORK_INSTALL_DIR$ac_delim
FRAMEWORK_REL_INSTALL!$FRAMEWORK_REL_INSTALL$ac_delim
FRAMEWORK_PREFIX!$FRAMEWORK_PREFIX$ac_delim
INSTALL_ORIG_TREE!$INSTALL_ORIG_TREE$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@ -9792,6 +9825,9 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
FRAMEWORK_REL_INSTALL!$FRAMEWORK_REL_INSTALL$ac_delim
FRAMEWORK_PREFIX!$FRAMEWORK_PREFIX$ac_delim
INSTALL_ORIG_TREE!$INSTALL_ORIG_TREE$ac_delim
EXE_SUFFIX!$EXE_SUFFIX$ac_delim
SO_SUFFIX!$SO_SUFFIX$ac_delim
OWN_LIBFFI!$OWN_LIBFFI$ac_delim
@ -9839,7 +9875,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 45; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 48; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -13,9 +13,12 @@
#include <errno.h>
#ifndef WINDOWS_DYNAMIC_LOAD
# include <dlfcn.h>
#else /* WINDOWS_DYNAMIC_LOAD defined */
# include <windows.h>
#endif /* WINDOWS_DYNAMIC_LOAD */
#if !defined(WINDOWS_DYNAMIC_LOAD) || defined(__MINGW32__)
# if SIZEOF_CHAR == 1
typedef signed char Tsint8;
typedef unsigned char Tuint8;
@ -53,9 +56,8 @@
# error "configuration error, please contact PLT (int64)"
# endif
#else /* WINDOWS_DYNAMIC_LOAD defined */
#else /* !defined(WINDOWS_DYNAMIC_LOAD) || defined(__MINGW32__) */
# include <windows.h>
# ifndef __CYGWIN32__
# include <wtypes.h>
typedef _int8 Tsint8;
@ -68,7 +70,7 @@
typedef unsigned _int64 Tuint64;
# endif
#endif /* WINDOWS_DYNAMIC_LOAD */
#endif /* !defined(WINDOWS_DYNAMIC_LOAD) || defined(__MINGW32__) */
#include "ffi.h"

View File

@ -16,9 +16,12 @@ exec racket "$0" > `echo "$0" | sed 's/rktc$/c/'` "$0"
#include <errno.h>
@@@IFNDEF{WINDOWS_DYNAMIC_LOAD}{
# include <dlfcn.h>
}{
# include <windows.h>
}
@@@IF{!defined(WINDOWS_DYNAMIC_LOAD) || defined(__MINGW32__)}{
# if SIZEOF_CHAR == 1
typedef signed char Tsint8;
typedef unsigned char Tuint8;
@ -58,7 +61,6 @@ exec racket "$0" > `echo "$0" | sed 's/rktc$/c/'` "$0"
}{
# include <windows.h>
# ifndef __CYGWIN32__
# include <wtypes.h>
typedef _int8 Tsint8;

View File

@ -17,7 +17,7 @@
"\n"))
;; thunks are forced -- so this can be used as @@IFDEF{...}{...} too!
(provide IFDEF IFNDEF)
(provide IFDEF IFNDEF IF)
(define ((((IF*DEF token choose) . c) . t) . e)
(if (null? e)
@list{@disable-prefix{#}@token @c
@ -30,6 +30,7 @@
@disable-prefix{#}endif /* @c */}))
(define IFDEF (IF*DEF "ifdef" car))
(define IFNDEF (IF*DEF "ifndef" cdr))
(define IF (IF*DEF "if" (lambda (x) "")))
(provide DEFINE UNDEF)
(define (DEFINE . t) @list{@disable-prefix{#}define @t})

View File

@ -51,9 +51,15 @@ ARLIBFLAGS = $(LDFLAGS) $(LDLIBS)
GRACKETLINKER = @MZLINKER@
GRACKETLDLIBS = ../racket/libracket.@LIBSFX@ ../racket/libmzgc.@LIBSFX@ $(LDLIBS)
GRACKETLDLIBS@NOT_MINGW@ = ../racket/libracket.@LIBSFX@ ../racket/libmzgc.@LIBSFX@ $(LDLIBS)
GRACKETLDLIBS@MINGW@ = ../racket/libracket.dll.a ../racket/libmzgc.dll.a $(LDLIBS) -ldelayimp
GRACKETLDFLAGS = $(LDFLAGS) -L../racket
GRACKETRES@NOT_MINGW@ =
GRACKETRESDEP@NOT_MINGW@ =
GRACKETRES@MINGW@ = -mwindows gres.o
GRACKETRESDEP@MINGW@ = gres.o
LOCALFLAGS_wx_xt = @WX_MMD_FLAG@
LOCALFLAGS_wx_mac = -I$(srcdir)/../mac/racket -MMD -DWX_CARBON
LOCALFLAGS = $(LOCALFLAGS_@WXVARIANT@)
@ -78,6 +84,7 @@ bin:
$(MAKE) @MAIN_VARIANT@
3m:
$(MAKE) resources
cd gc2; $(MAKE) 3m
cgc:
@ -87,8 +94,17 @@ both:
$(MAKE) cgc
$(MAKE) 3m
gracket@CGC@ : $(RACKETDEPS) grmain.@LTO@ $(GRACKETOBJECTS) $(MRSTATIC_STUB)
$(GRACKETLINKER) $(GRACKETLDFLAGS) $(MRSTATIC) -o gracket@CGC@ $(GRACKETOBJECTS) $(GRACKETLDLIBS) $(MRSTATIC_STUB)
gracket@CGC@ : $(RACKETDEPS) grmain.@LTO@ $(GRACKETOBJECTS) $(MRSTATIC_STUB) $(GRACKETRESDEP)
$(GRACKETLINKER) $(GRACKETLDFLAGS) $(MRSTATIC) -o gracket@CGC@ $(GRACKETOBJECTS) $(GRACKETRES) $(GRACKETLDLIBS) $(MRSTATIC_STUB)
gres.o : $(srcdir)/../worksp/gracket/gracket.rc
windres -i $(srcdir)/../worksp/gracket/gracket.rc -o gres.o
resources@NOT_MINGW@ :
$(NOOP)
resources@MINGW@ : gres.o
$(NOOP)
MRFW = Racket.framework/Versions/$(FWVERSION)/Racket
MRAPPSKEL = GRacket@CGC@.app/Contents/MacOS
@ -164,12 +180,12 @@ install-common:
install-wx_xt:
$(MAKE) install-common
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@MMM_INSTALLED@"
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/gracket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/gracket@MMM_INSTALLED@"
cd ..; echo 'MROPTIONS=@MROPTIONS@' >> $(BUILDINFO)
cd ..; echo "MRLIBS=$(GUILIBS_@WXVARIANT@)" >> $(BUILDINFO)
cd ..; echo "MRLDFLAGS=$(GRACKETLDFLAGS)" >> $(BUILDINFO)
cd ..; mkdir -p "$(DESTDIR)$(bindir)"
cd ..; mkdir -p "$(DESTDIR)@MZINSTALLBINDIR@";
install-no-lib-cgc-wx_xt:
echo "no dynamic libs"
@ -179,8 +195,8 @@ install-lib-cgc-wx_xt:
install-wx_xt-cgc:
$(MAKE) @MRLIBINSTALL@-cgc-wx_xt
cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)$(bindir)/gracket@CGC_INSTALLED@"
@RUN_RACKET_CGC@ -cu "$(srcdir)/../racket/collects-path.rkt" "$(DESTDIR)$(bindir)/gracket@CGC_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
cd ..; $(ICP) gracket/gracket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/GRacket@CGC_INSTALLED@"
@RUN_RACKET_CGC@ -cu "$(srcdir)/../racket/collects-path.rkt" "$(DESTDIR)@MZINSTALLBINDIR@/gracket@CGC_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
install-wx_xt-cgc-final:
$(NOOP)
@ -193,8 +209,8 @@ install-lib-3m-wx_xt:
install-wx_xt-3m:
$(MAKE) @MRLIBINSTALL@-3m-wx_xt
cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)$(bindir)/gracket@MMM_INSTALLED@"
@RUN_RACKET_MMM@ -cu "$(srcdir)/../racket/collects-path.rkt" "$(DESTDIR)$(bindir)/gracket@MMM_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
cd ..; $(ICP) gracket/gracket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/GRacket@MMM_INSTALLED@"
@RUN_RACKET_MMM@ -cu "$(srcdir)/../racket/collects-path.rkt" "$(DESTDIR)@MZINSTALLBINDIR@/gracket@MMM_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
install-wx_xt-3m-final:
$(NOOP)

View File

@ -87,9 +87,12 @@ GRACKETLIBS_la =
GRACKETMZOBJS_a = $(MZOBJS)
GRACKETMZOBJS_la =
../gracket@MMM@@NOT_OSX@: grmain.@LTO@ ../../racket/libracket3m.@LIBSFX@
../gracket@MMM@@NOT_OSX@@NOT_MINGW@: grmain.@LTO@ ../../racket/libracket3m.@LIBSFX@
$(GRACKETLINKER) $(GRACKETLDFLAGS) -o ../gracket@MMM@ grmain.@LTO@ ../../racket/libracket3m.@LIBSFX@ $(GRACKETMZOBJS_@LIBSFX@) $(GRACKETLIBS_@LIBSFX@)
../gracket@MMM@@MINGW@: grmain.@LTO@ ../../racket/gc2/libracket3m.dll.a ../gres.o
$(GRACKETLINKER) -mwindows $(GRACKETLDFLAGS) -o ../gracket@MMM@ grmain.@LTO@ ../gres.o ../../racket/gc2/libracket3m.dll.a $(GRACKETMZOBJS_@LIBSFX@) $(GRACKETLIBS_@LIBSFX@) -l delayimp
MZFW = ../../racket/Racket.framework/Versions/$(FWVERSION)_3m/Racket
MRAPPSKEL = ../GRacket@MMM@.app/Contents/MacOS

View File

@ -15,6 +15,8 @@ static int wx_in_terminal = 0;
# define MZ_DEFINE_UTF8_MAIN
# define PRE_FILTER_CMDLINE_ARGUMENTS
static void pre_filter_cmdline_arguments(int *argc, char ***argv);
# define WINMAIN_ALREADY
# undef wx_xt
#endif
struct Scheme_Env;
@ -422,82 +424,6 @@ static void MrEdExit(int v)
START_XFORM_SKIP;
# endif
char *wchar_to_char(wchar_t *wa, int len)
{
char *a;
int l;
l = scheme_utf8_encode((unsigned int *)wa, 0, len,
NULL, 0,
1 /* UTF-16 */);
a = (char *)malloc(l + 1);
scheme_utf8_encode((unsigned int *)wa, 0, len,
(unsigned char *)a, 0,
1 /* UTF-16 */);
a[l] = 0;
return a;
}
static int parse_command_line(char ***_command, char *buf)
{
GC_CAN_IGNORE unsigned char *parse, *created, *write;
int maxargs;
int findquote = 0;
char **command;
int count = 0;
maxargs = 49;
command = (char **)malloc((maxargs + 1) * sizeof(char *));
parse = created = write = (unsigned char *)buf;
while (*parse) {
while (*parse && isspace(*parse)) { parse++; }
while (*parse && (!isspace(*parse) || findquote)) {
if (*parse== '"') {
findquote = !findquote;
} else if (*parse== '\\') {
GC_CAN_IGNORE unsigned char *next;
for (next = parse; *next == '\\'; next++) { }
if (*next == '"') {
/* Special handling: */
int count = (next - parse), i;
for (i = 1; i < count; i += 2) {
*(write++) = '\\';
}
parse += (count - 1);
if (count & 0x1) {
*(write++) = '\"';
parse++;
}
} else
*(write++) = *parse;
} else
*(write++) = *parse;
parse++;
}
if (*parse)
parse++;
*(write++) = 0;
if (*created) {
command[count++] = (char *)created;
if (count == maxargs) {
char **c2;
c2 = (char **)malloc(((2 * maxargs) + 1) * sizeof(char *));
memcpy(c2, command, maxargs * sizeof(char *));
maxargs *= 2;
}
}
created = write;
}
command[count] = NULL;
*_command = command;
return count;
}
/* ---------------------------------------- */
/* single-instance detection */
/* ---------------------------------------- */
@ -680,9 +606,8 @@ static void pre_filter_cmdline_arguments(int *argc, char ***argv)
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow)
{
LPWSTR m_lpCmdLine;
int j, argc, l;
char *a, **argv, *normalized_path;
int j, argc;
char **argv, *normalized_path;
/* Order matters: load dependencies first */
# ifndef MZ_PRECISE_GC
@ -691,6 +616,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored
load_delayed_dll(NULL, "libracket" DLL_3M_SUFFIX "xxxxxxx.dll");
record_dll_path();
# ifdef __MINGW32__
scheme_set_atexit(atexit);
# endif
{
HANDLE h;
h = GetStdHandle(STD_OUTPUT_HANDLE);
@ -700,41 +629,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored
}
}
/* Get command line: */
m_lpCmdLine = GetCommandLineW();
for (j = 0; m_lpCmdLine[j]; j++) {
}
a = wchar_to_char(m_lpCmdLine, j);
argc = parse_command_line(&argv, a);
/* argv[0] should be the name of the executable, but Windows doesn't
specify really where this name comes from, so we get it from
GetModuleFileName, just in case */
{
int name_len = 1024;
while (1) {
wchar_t *my_name;
my_name = (wchar_t *)malloc(sizeof(wchar_t) * name_len);
l = GetModuleFileNameW(NULL, my_name, name_len);
if (!l) {
name_len = GetLastError();
free(my_name);
my_name = NULL;
break;
} else if (l < name_len) {
a = wchar_to_char(my_name, l);
argv[0] = a;
CharLowerBuffW(my_name, l);
normalized_path = wchar_to_char(my_name, l);
free(my_name);
break;
} else {
free(my_name);
name_len = name_len * 2;
}
}
}
argv = cmdline_to_argv(&argc, &normalized_path);
if (CheckSingleInstance(normalized_path, argv))
return 0;
@ -748,7 +643,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored
scheme_set_console_printf(MrEdSchemeMessages);
scheme_set_exit(MrEdExit);
j = main(argc, argv);
j = MAIN(argc, argv);
MrEdExit(j);
/* shouldn't get here */

View File

@ -160,7 +160,7 @@ sproc.@LTO@: @GCDIR@/sproc.@LTO@
# Unix ----------------------------------------
racket@CGC@@NOT_OSX@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ $(SPECIALIZINGOBJECTS)
racket@CGC@@NOT_OSX@@NOT_MINGW@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ $(SPECIALIZINGOBJECTS)
@MZLINKER@ -o racket@CGC@ main.@LTO@ $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LDFLAGS@ @LIBS@
# Mac OS ----------------------------------------
@ -177,6 +177,31 @@ racket@CGC@@OSX@: $(MZFW) main.@LTO@
@MZLINKER@ -o racket@CGC@ @PROFFLAGS@ @LDFLAGS@ main.@LTO@ -Wl,-headerpad_max_install_names -F. -framework Racket @LIBS@
/usr/bin/install_name_tool -change "Racket.framework/Versions/$(FWVERSION)/Racket" "@executable_path/Racket.framework/Versions/$(FWVERSION)/Racket" "racket@CGC@"
# mingw ----------------------------------------
lib/libmzgcxxxxxxx.dll: libmzgc.@LIBSFX@
mkdir -p lib
@MZLINKER@ -shared -o lib/libmzgcxxxxxxx.dll -Wl,--output-def -Wl,libmzgc.def -Wl,--whole-archive libmzgc.@LIBSFX@ -Wl,--no-whole-archive
mzsj86g.o: $(srcdir)/src/mzsj86g.S
$(CC) -c -o mzsj86g.o $(srcdir)/src/mzsj86g.S
lib/libracketxxxxxxx.dll: lib/libmzgcxxxxxxx.dll libracket.@LIBSFX@ mzsj86g.o
mkdir -p lib
@MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll
libracket.dll.a: lib/libracketxxxxxxx.dll
dlltool --def libracket.def -D libracketxxxxxxx.dll --output-delaylib libracket.dll.a
libmzgc.dll.a: lib/libmzgcxxxxxxx.dll
dlltool --def libmzgc.def -D libmzgcxxxxxxx.dll --output-delaylib libmzgc.dll.a
rres.o : $(srcdir)/../worksp/racket/racket.rc
windres -i $(srcdir)/../worksp/racket/racket.rc -o rres.o
racket@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a main.@LTO@ $(SPECIALIZINGOBJECTS) rres.o
@MZLINKER@ -o racket@CGC@ main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) libracket.dll.a libmzgc.dll.a @LDFLAGS@ @LIBS@ -ldelayimp
# OSKit ----------------------------------------
racket.multiboot : libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@
@ -193,7 +218,7 @@ racket.multiboot : libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@
DEF_COLLECTS_DIR = -DINITIAL_COLLECTS_DIRECTORY='"'"`cd $(srcdir)/../../collects; pwd`"'"'
main.@LTO@: $(srcdir)/main.c $(srcdir)/include/scheme.h $(srcdir)/sconfig.h $(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/oskglue.inc
main.@LTO@: $(srcdir)/main.c $(srcdir)/include/scheme.h $(srcdir)/sconfig.h $(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/parse_cmdl.inc $(srcdir)/oskglue.inc
$(CC) -I$(builddir) -I$(srcdir)/include @CFLAGS@ @COMPFLAGS@ @PREFLAGS@ @PROFFLAGS@ @OPTIONS@ @MZOPTIONS@ $(DEF_COLLECTS_DIR) -c $(srcdir)/main.c -o main.@LTO@
main_ee.@LTO@: main.@LTO@
@ -299,12 +324,12 @@ install-both:
# Prefix might be relative to srcdir, or it might be absolute, so we
# have to go up and install things from there.
unix-install:
cd ..; rm -f "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@"
cd ..; cp racket/starter "$(DESTDIR)$(libpltdir)/starter"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/starter"
@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(libpltdir)/starter" @COLLECTS_PATH@
unix-install:
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/racket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/racket@MMM_INSTALLED@"
cd ..; cp racket/starter@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/starter@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/starter@EXE_SUFFIX@"
@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)$(libpltdir)/starter@EXE_SUFFIX@" @COLLECTS_PATH@
cd ..; echo 'CC=@CC@' > "$(BUILDINFO)"
cd ..; echo 'CFLAGS=@CFLAGS@ @PREFLAGS@ @COMPFLAGS@' >> "$(BUILDINFO)"
cd ..; echo 'OPTIONS=@OPTIONS@' >> "$(BUILDINFO)"
@ -331,6 +356,31 @@ unix-install-3m:
unix-install-3m-final:
$(NOOP)
# mingw install ----------------------------------------
mingw-install:
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/racket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)@MZINSTALLBINDIR@/racket@MMM_INSTALLED@"
cd ..; cp racket/starter@EXE_SUFFIX@ "$(DESTDIR)$(collectsdir)/launcher/MzStart@EXE_SUFFIX@"
cd ..; cp racket/mrstarter@EXE_SUFFIX@ "$(DESTDIR)$(collectsdir)/launcher/MrStart@EXE_SUFFIX@"
mingw-install-cgc:
cd ..; $(ICP) racket/lib/libmzgcxxxxxxx.dll "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll"
cd ..; $(ICP) racket/lib/libracketxxxxxxx.dll "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll"
cd ..; $(ICP) racket/racket@CGC@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@"
@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
mingw-install-cgc-final:
$(NOOP)
mingw-install-3m:
cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@"
cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll"
@RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@" @COLLECTS_PATH@
mingw-install-3m-final:
$(NOOP)
# OS X install ----------------------------------------
MZFWDIR = @FRAMEWORK_INSTALL_DIR@/Racket.framework

View File

@ -73,11 +73,7 @@ static void (*console_printf)(char *str, ...);
# define PRINTF console_printf
#endif
extern
# ifdef __cplusplus
"C"
# endif
__declspec(dllexport) void scheme_set_dll_path(wchar_t *s);
MZ_EXTERN void scheme_set_dll_path(wchar_t *s);
static void record_dll_path(void)
{

View File

@ -113,6 +113,10 @@ if test "${enable_shared}" = "yes" ; then
exit 1
fi
;;
mingw*)
echo "ERROR: don't use --enable-shared or --enable-dynlib with mingw"
exit 1
;;
esac
fi
@ -301,6 +305,7 @@ GCDIR=gc
MZBINTARGET=normal-bin
MZINSTALLTARGET=unix-install
MZINSTALLBINDIR='$(bindir)'
MZOPTIONS=
CGCOPTIONS=
@ -336,6 +341,7 @@ INSTALL_SETUP_FLAGS=
STRIP_DEBUG=":"
use_flag_pthread=yes
skip_iconv_check=no
###### OSKit stuff #######
@ -465,6 +471,8 @@ EXTRA_GMP_DEP=
# For Racket targets:
OSX=".osx"
NOT_OSX=""
MINGW=".mingw"
NOT_MINGW=""
CGC_X86_64=""
case "$host_os" in
@ -549,6 +557,19 @@ case "$host_os" in
fi
LIBS="$LIBS -Wl,-E"
;;
mingw*)
enable_parallel_by_default=yes
use_flag_pthread=no
MZOPTIONS="$MZOPTIONS -fno-omit-framepointer" # to make JIT backtraces work
MINGW=""
NOT_MINGW=".other"
MZINSTALLTARGET=mingw-install
MZINSTALLBINDIR="${MZINSTALLBINDIR}/.."
EXE_SUFFIX=".exe"
COLLECTS_PATH="collects"
skip_iconv_check=yes
AC_DEFINE(HAVE_STDINT_H,1,[Have stdint.h])
;;
cygwin*)
enable_cgcdefault="yes"
MZINSTALLTARGET=unix-cygwin-install
@ -748,7 +769,8 @@ AC_TRY_LINK([#include <sys/types.h>
AC_MSG_RESULT($have_getaddrinfo)
iconv_lib_flag=""
if test "${enable_iconv}" = "yes" ; then
if test "${skip_iconv_check}" = "no" ; then
if test "${enable_iconv}" = "yes" ; then
AC_CHECK_HEADER(iconv.h, enable_iconv=yes, enable_iconv=no)
if test "${enable_iconv}" = "yes" ; then
# Does it all work, now?
@ -778,13 +800,14 @@ if test "${enable_iconv}" = "yes" ; then
fi
fi
fi
fi
[ msg="iconv is usable" ]
AC_MSG_CHECKING($msg)
iconv_usage_result="$enable_iconv$iconv_lib_flag"
AC_MSG_RESULT($iconv_usage_result)
if test "${enable_iconv}" = "no" ; then
fi
[ msg="iconv is usable" ]
AC_MSG_CHECKING($msg)
iconv_usage_result="$enable_iconv$iconv_lib_flag"
AC_MSG_RESULT($iconv_usage_result)
if test "${enable_iconv}" = "no" ; then
MZOPTIONS="$MZOPTIONS -DMZ_NO_ICONV"
fi
fi
[ msg="for mbsrtowcs" ]
@ -1267,10 +1290,13 @@ AC_SUBST(GCDIR)
AC_SUBST(XFORMFLAGS)
AC_SUBST(MZBINTARGET)
AC_SUBST(MZINSTALLTARGET)
AC_SUBST(MZINSTALLBINDIR)
AC_SUBST(EXTRA_GMP_OBJ)
AC_SUBST(EXTRA_GMP_DEP)
AC_SUBST(OSX)
AC_SUBST(NOT_OSX)
AC_SUBST(MINGW)
AC_SUBST(NOT_MINGW)
AC_SUBST(FRAMEWORK_INSTALL_DIR)
AC_SUBST(FRAMEWORK_REL_INSTALL)
AC_SUBST(FRAMEWORK_PREFIX)

View File

@ -46,9 +46,17 @@ MZDYNDEP = ../mzdyn.o $(srcdir)/../include/ext.exp $(srcdir)/../include/racket.e
dynexmpl.o: $(srcdir)/dynexmpl.c $(HEADERS)
$(PLAIN_CC) $(CFLAGS) -c $(srcdir)/dynexmpl.c -o dynexmpl.o
../starter: $(srcdir)/ustart.c
../starter@NOT_MINGW@: $(srcdir)/ustart.c
$(PLAIN_CC) $(CFLAGS) -o ../starter $(srcdir)/ustart.c
../starter@MINGW@: $(srcdir)/start.c ../mrstarter@EXE_SUFFIX@ sres.o
$(PLAIN_CC) $(CFLAGS) -o ../starter $(srcdir)/start.c sres.o
../mrstarter@EXE_SUFFIX@: sres.o
$(PLAIN_CC) $(CFLAGS) -mwindows -DMRSTART -o ../mrstarter $(srcdir)/start.c sres.o
sres.o:
windres -i $(srcdir)/../../worksp/starters/start.rc -o sres.o
# Cygwin ########################################
ILIBDIR = $(libpltdir)

View File

@ -34,7 +34,7 @@
#define MAXCOMMANDLEN 1024
#define MAX_ARGS 100
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__MINGW32__)
# define MSC_IZE(x) _ ## x
#else
# define MSC_IZE(x) x
@ -163,7 +163,7 @@ static wchar_t *protect(wchar_t *s)
}
static int parse_command_line(int count, wchar_t **command,
wchar_t *buf, int maxargs)
wchar_t *buf, int maxargs, int skip)
{
wchar_t *parse, *created, *write;
@ -199,9 +199,13 @@ static int parse_command_line(int count, wchar_t **command,
*(write++) = 0;
if (*created) {
command[count++] = created;
if (count == maxargs)
return count;
if (skip) {
skip--;
} else {
command[count++] = created;
if (count == maxargs)
return count;
}
}
created = write;
}
@ -247,9 +251,13 @@ static wchar_t *copy_string(wchar_t *s)
}
#endif
#ifdef MRSTART
#if defined(MRSTART) || defined(__MINGW32__)
# define USE_WINMAIN
#endif
#ifdef USE_WINMAIN
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR m_lpCmdLine, int nCmdShow)
LPSTR m_lpCmdLine, int nCmdShow)
#else
int wmain(int argc_in, wchar_t **argv_in)
#endif
@ -274,7 +282,7 @@ int wmain(int argc_in, wchar_t **argv_in)
#endif
count = 1;
count = parse_command_line(count, args, input, MAX_ARGS);
count = parse_command_line(count, args, input, MAX_ARGS, 0);
/* exedir can be relative to the current executable */
if ((exedir[0] == '\\')
@ -310,7 +318,7 @@ int wmain(int argc_in, wchar_t **argv_in)
wc_strcat(go, L".exe");
if (_wstat(go, &st)) {
#ifdef MRSTART
#ifdef USE_WINMAIN
wchar_t errbuff[MAXCOMMANDLEN * 2];
swprintf(errbuff,L"Can't find %s",go);
MessageBoxW(NULL,errbuff,L"Error",MB_OK);
@ -324,15 +332,16 @@ int wmain(int argc_in, wchar_t **argv_in)
args[0] = go;
#ifdef MRSTART
#ifdef USE_WINMAIN
{
wchar_t *buf;
LPWSTR m_lpCmdLine;
m_lpCmdLine = GetCommandLineW();
buf = (wchar_t *)malloc((wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
memcpy(buf, m_lpCmdLine, (wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
count = parse_command_line(count, args, buf, MAX_ARGS);
count = parse_command_line(count, args, buf, MAX_ARGS, 1);
}
#else
{

View File

@ -154,7 +154,7 @@
#endif
#if defined(__MINGW32__) && defined(GC_DLL)
# ifdef GC_BUILD
# if defined(GC_BUILD) || defined(__MINGW32_DELAY_LOAD__)
# define GC_API __declspec(dllexport)
# else
# define GC_API __declspec(dllimport)

View File

@ -483,7 +483,7 @@ EXTRA_OBJS_L = ../src/gmp.@LTO@ $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_U
$(NICEAR) $(AR) $(ARFLAGS) ../libracket3m.@LIBSFX@ $(OBJS) $(EXTRA_OBJS_L) gc2.@LTO@
$(RANLIB) ../libracket3m.@LIBSFX@
../racket@MMM@@NOT_OSX@: main.@LTO@ ../libracket3m.@LIBSFX@
../racket@MMM@@NOT_OSX@@NOT_MINGW@: main.@LTO@ ../libracket3m.@LIBSFX@
cd ..; @MZLINKER@ -o racket@MMM@ @PROFFLAGS@ gc2/main.@LTO@ libracket3m.@LIBSFX@ @LDFLAGS@ $(LIBS)
# The above "cd .." prevents a problem with libtool's generated script in --enable-shared mode,
@ -504,6 +504,17 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@
cp "Racket.framework/Versions/$(FWVERSION)_3m/Racket" "../Racket.framework/Versions/$(FWVERSION)_3m/Racket"
/usr/bin/install_name_tool -change "Racket.framework/Versions/$(FWVERSION)_3m/Racket" "@executable_path/Racket.framework/Versions/$(FWVERSION)_3m/Racket" "../racket@MMM@"
../lib/libracket3mxxxxxxx.dll: ../libracket3m.@LIBSFX@ ../mzsj86g.o
mkdir -p lib
@MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive -lshell32 -luser32 -lws2_32
libracket3m.dll.a: ../lib/libracket3mxxxxxxx.dll
dlltool --def libracket3m.def -D libracket3mxxxxxxx.dll --output-delaylib libracket3m.dll.a
../racket@MMM@@MINGW@: libracket3m.dll.a main.@LTO@ ../rres.o $(SPECIALIZINGOBJECTS)
cd ..; @MZLINKER@ -o racket@MMM@ gc2/main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp
clean:
/bin/rm -f ../racket@MMM@ *.@LTO@ $(XSRCDIR)/*
/bin/rm -rf xform-collects

View File

@ -2,7 +2,9 @@
# include <winsock2.h>
# include <windows.h>
# define bzero(m, s) memset(m, 0, s)
# define inline _inline
# ifndef __MINGW32__
# define inline _inline
# endif
#endif
#include "mzconfig.h"

View File

@ -50,7 +50,9 @@
(set! gc-variable-stack-through-funcs? #t)]
[("+D") def "add CPP -D flag"
(set! cpp (string-append cpp " -D"
(regexp-replace* "[ \"]" def "'\\0'")))]]
(if (eq? (system-type) 'windows)
def
(regexp-replace* "[ \"]" def "'\\0'"))))]]
[args (file)
(set! file-in file)])

View File

@ -1903,7 +1903,7 @@ MZ_EXTERN Scheme_Object *scheme_register_parameter(Scheme_Prim *function, char *
/* addrinfo */
/*========================================================================*/
#ifdef HAVE_GETADDRINFO
#if defined(HAVE_GETADDRINFO) || defined(__MINGW32__)
# define mz_addrinfo addrinfo
#else
struct mz_addrinfo {

View File

@ -36,6 +36,10 @@ extern "C" {
# define THREAD_LOCAL /* empty */
# define IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
# endif
# elif __MINGW32__
# define THREAD_LOCAL __thread
# define MZ_THREAD_EXTERN extern
# define IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC
# elif (defined(__APPLE__) && defined(__MACH__)) || defined(GC2_PLACES_TESTING)
# define IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS
# if defined(__x86_64__) || defined(__i386__)
@ -54,7 +58,7 @@ extern "C" {
&& !defined(SCHEME_EMBEDDED_NO_DLL)
# define MZ_DLLIMPORT __declspec(dllimport)
# define MZ_DLLEXPORT __declspec(dllexport)
# ifdef __mzscheme_private__
# if defined(__mzscheme_private__) || defined(__MINGW32_DELAY_LOAD__)
# define MZ_DLLSPEC __declspec(dllexport)
# else
# define MZ_DLLSPEC __declspec(dllimport)

View File

@ -31,6 +31,7 @@
(except for the garbage collector, which is in `gc', `sgc', or
`gc2', depending on which one you're using). */
#define __MINGW32_DELAY_LOAD__ 1
#include "scheme.h"
/*========================================================================*/
@ -256,7 +257,11 @@ static BOOL WINAPI ConsoleBreakHandler(DWORD op)
static void do_scheme_rep(Scheme_Env *, FinishArgs *f);
static int cont_run(FinishArgs *f);
#if defined(WINDOWS_UNICODE_SUPPORT) && !defined(__CYGWIN32__) && !defined(MZ_DEFINE_UTF8_MAIN)
#if defined(__MINGW32__)
# define MAIN zmain
# define MAIN_char char
# define MAIN_argv argv
#elif defined(WINDOWS_UNICODE_SUPPORT) && !defined(__CYGWIN32__) && !defined(MZ_DEFINE_UTF8_MAIN)
# define MAIN wmain
# define MAIN_char wchar_t
# define MAIN_argv wargv
@ -277,14 +282,18 @@ static int main_after_stack(void *data);
START_XFORM_SKIP;
# endif
#if defined(__MINGW32__) || defined(WINMAIN_ALREADY)
# include "parse_cmdl.inc"
#endif
#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
extern intptr_t _tls_index;
static __declspec(thread) void *tls_space;
#endif
int MAIN(int argc, MAIN_char **MAIN_argv)
{
#ifdef DOS_FILE_SYSTEM
static void load_delayed()
{
/* Order matters: load dependencies first */
# ifndef MZ_PRECISE_GC
load_delayed_dll(NULL, "libmzgcxxxxxxx.dll");
@ -294,11 +303,34 @@ int MAIN(int argc, MAIN_char **MAIN_argv)
# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
scheme_register_tls_space(&tls_space, _tls_index);
# endif
}
#endif
int MAIN(int argc, MAIN_char **MAIN_argv)
{
#if defined(DOS_FILE_SYSTEM) && !defined(__MINGW32__)
load_delayed();
#endif
return main_after_dlls(argc, MAIN_argv);
}
#if defined(__MINGW32__) && !defined(WINMAIN_ALREADY)
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow)
{
int argc;
char **argv;
load_delayed();
scheme_set_atexit(atexit);
argv = cmdline_to_argv(&argc, NULL);
return zmain(argc, argv);
}
#endif
# ifdef MZ_PRECISE_GC
END_XFORM_SKIP;
# endif

128
src/racket/parse_cmdl.inc Normal file
View File

@ -0,0 +1,128 @@
/* Windows command-line parsing */
static char *wchar_to_char(wchar_t *wa, int len)
{
char *a;
int l;
l = scheme_utf8_encode((unsigned int *)wa, 0, len,
NULL, 0,
1 /* UTF-16 */);
a = (char *)malloc(l + 1);
scheme_utf8_encode((unsigned int *)wa, 0, len,
(unsigned char *)a, 0,
1 /* UTF-16 */);
a[l] = 0;
return a;
}
static int parse_command_line(char ***_command, char *buf)
{
GC_CAN_IGNORE unsigned char *parse, *created, *write;
int maxargs;
int findquote = 0;
char **command;
int count = 0;
maxargs = 49;
command = (char **)malloc((maxargs + 1) * sizeof(char *));
parse = created = write = (unsigned char *)buf;
while (*parse) {
int did_create = 0;
while (*parse && isspace(*parse)) { parse++; }
while (*parse && (!isspace(*parse) || findquote)) {
if (*parse== '"') {
findquote = !findquote;
did_create = 1;
} else if (*parse== '\\') {
GC_CAN_IGNORE unsigned char *next;
for (next = parse; *next == '\\'; next++) { }
if (*next == '"') {
/* Special handling: */
int count = (next - parse), i;
for (i = 1; i < count; i += 2) {
*(write++) = '\\';
}
parse += (count - 1);
if (count & 0x1) {
*(write++) = '\"';
parse++;
}
} else
*(write++) = *parse;
} else
*(write++) = *parse;
parse++;
}
if (*parse)
parse++;
*(write++) = 0;
if (*created || did_create) {
command[count++] = (char *)created;
if (count == maxargs) {
char **c2;
c2 = (char **)malloc(((2 * maxargs) + 1) * sizeof(char *));
memcpy(c2, command, maxargs * sizeof(char *));
maxargs *= 2;
}
}
created = write;
}
command[count] = NULL;
*_command = command;
return count;
}
static char **cmdline_to_argv(int *_argc, char **_normalized_path)
{
LPWSTR m_lpCmdLine;
int j, argc, l;
char *a, **argv, *normalized_path;
m_lpCmdLine = GetCommandLineW();
for (j = 0; m_lpCmdLine[j]; j++) {
}
a = wchar_to_char(m_lpCmdLine, j);
argc = parse_command_line(&argv, a);
/* argv[0] should be the name of the executable, but Windows doesn't
specify really where this name comes from, so we get it from
GetModuleFileName, just in case */
{
int name_len = 1024;
while (1) {
wchar_t *my_name;
my_name = (wchar_t *)malloc(sizeof(wchar_t) * name_len);
l = GetModuleFileNameW(NULL, my_name, name_len);
if (!l) {
name_len = GetLastError();
free(my_name);
my_name = NULL;
break;
} else if (l < name_len) {
a = wchar_to_char(my_name, l);
argv[0] = a;
CharLowerBuffW(my_name, l);
normalized_path = wchar_to_char(my_name, l);
free(my_name);
break;
} else {
free(my_name);
name_len = name_len * 2;
}
}
}
*_argc = argc;
if (_normalized_path)
*_normalized_path = normalized_path;
return argv;
}

View File

@ -512,7 +512,7 @@
/* See the "worksp" directory for more MSVC details. */
#if (defined(__BORLANDC__) \
|| (defined(_MSC_VER) \
|| ((defined(_MSC_VER) || defined(__MINGW32__)) \
&& (defined(__WIN32__) || defined(WIN32) || defined(_WIN32))))
# ifdef _WIN64
@ -523,7 +523,7 @@
# define SYSTEM_TYPE_NAME "windows"
# define DOS_FILE_SYSTEM
# if defined(_MSC_VER)
# if defined(_MSC_VER) || defined(__MINGW32__)
# define NO_READDIR
# define USE_FINDFIRST
# define NO_READLINK
@ -581,6 +581,10 @@
# define TRIG_ZERO_NEEDS_SIGN_CHECK
# define NEED_TO_DEFINE_MATHERR
#endif
#ifdef __MINGW32__
# define USE_IEEE_FP_PREDS
# define ATAN2_DOESNT_WORK_WITH_INFINITIES
#endif
# define IO_INCLUDE
# define DONT_IGNORE_PIPE_SIGNAL
@ -616,6 +620,9 @@
#if defined(_MSC_VER)
# define IGNORE_BY_MS_CONTROL_87
#endif
#if defined(__MINGW32__)
# define ASM_DBLPREC_CONTROL_87
#endif
# define REGISTER_POOR_MACHINE

View File

@ -141,8 +141,6 @@ static void register_traversers(void);
#define cons(a,b) scheme_make_pair(a,b)
#define icons(a,b) scheme_make_pair(a,b)
#define max(a, b) (((a) > (b)) ? (a) : (b))
/**********************************************************************/
/* initialization */
/**********************************************************************/

View File

@ -144,6 +144,9 @@
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifdef WINDOWS_FIND_STACK_BOUNDS
#include <windows.h>
#endif
#ifdef BEOS_FIND_STACK_BOUNDS
# include <be/kernel/OS.h>
#endif

40
src/racket/src/mzsj86g.S Normal file
View File

@ -0,0 +1,40 @@
.globl _scheme_mz_setjmp
_scheme_mz_setjmp:
push %EBP
mov %ESP, %EBP
mov 4(%EBP), %ECX # return address
mov 8(%EBP), %EAX # jmp_buf ptr
mov (%EBP), %EDX # old EBP
mov %EDX, (%EAX)
mov %EBX, 4(%EAX)
mov %EDI, 8(%EAX)
mov %ESI, 12(%EAX)
mov %ESP, 16(%EAX)
mov %ECX, 20(%EAX)
pop %EBP
mov $0, %EAX
ret
.globl _scheme_mz_longjmp
_scheme_mz_longjmp:
push %EBP
mov %ESP, %EBP
mov 12(%EBP), %EAX # return value
mov 8(%EBP), %ECX # jmp_buf
mov 16(%ECX), %ESP # restore stack pointer
mov (%ECX), %EBP # old EBP
mov %EBP, (%ESP)
mov %ESP, %EBP
mov 4(%ECX), %EBX
mov 8(%ECX), %EDI
mov 12(%ECX), %ESI
mov 20(%ECX), %ECX # return address
mov %ECX, 4(%EBP)
pop %EBP
ret
.section .drectve,"r"
.ascii " -export:scheme_mz_setjmp"
.section .drectve,"r"
.ascii " -export:scheme_mz_longjmp"

View File

@ -80,7 +80,12 @@ static int mzerrno = 0;
# include <process.h>
# include <winsock2.h>
# include <ws2tcpip.h>
# include <wspiapi.h>
# ifndef __MINGW32__
# include <wspiapi.h>
# else
typedef int (WINAPI*gai_t)(const char*, const char*, const struct mz_addrinfo *, struct mz_addrinfo **);
typedef void (WINAPI*fai_t)(struct mz_addrinfo *ai);
# endif
struct SOCKADDR_IN {
short sin_family;
unsigned short sin_port;
@ -381,6 +386,24 @@ static int mz_getaddrinfo(const char *nodename, const char *servname,
{
struct hostent *h;
#ifdef __MINGW32__
{
HMODULE hm;
hm = LoadLibrary("ws2_32.dll");
if (hm) {
gai_t gai;
gai = (gai_t)GetProcAddress(hm, "getaddrinfo");
if (gai) {
int v;
v = gai(nodename, servname, hints, res);
if (!v && !(*res)->ai_addr)
(*res)->ai_addrlen = 0;
return v;
}
}
}
#endif
if (nodename)
h = gethostbyname(nodename);
else
@ -423,13 +446,32 @@ static int mz_getaddrinfo(const char *nodename, const char *servname,
void mz_freeaddrinfo(struct mz_addrinfo *ai)
XFORM_SKIP_PROC
{
#ifdef __MINGW32__
{
HMODULE hm;
hm = LoadLibrary("ws2_32.dll");
if (hm) {
fai_t fai;
fai = (fai_t)GetProcAddress(hm, "freeaddrinfo");
if (fai) {
fai(ai);
return;
}
}
}
#endif
free(ai->ai_addr);
free(ai);
}
const char *mz_gai_strerror(int ecode)
XFORM_SKIP_PROC
{
#ifdef __MINGW32__
return NULL; /* => use FormatMessageW(), instead */
#else
return hstrerror(ecode);
#endif
}
#endif
@ -2302,7 +2344,7 @@ tcp_listen(int argc, Scheme_Object *argv[])
"tcp-listen: listen failed\n"
" port number: %d\n"
" system error: %E",
origid, errid);
(int)origid, errid);
#else
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED,
"tcp-listen: " NOT_SUPPORTED_STR);

View File

@ -333,8 +333,13 @@ int scheme_get_serialized_fd_flags(Scheme_Object* p, Scheme_Serialized_File_FD *
#endif
#if defined(DOS_FILE_SYSTEM)
# define fseeko _fseeki64
# define ftello _ftelli64
# if defined(__MINGW32__)
# define fseeko fseek
# define ftello ftell
# else
# define fseeko _fseeki64
# define ftello _ftelli64
# endif
#endif

View File

@ -657,11 +657,23 @@ void scheme_reset_jmpup_buf(Scheme_Jumpup_Buf *b)
#ifdef USE_MZ_CYGWIN_SETJMP
/* We have to define setjmp & longjmp to remain compatible
with MSVC-compiled extensions. It's the mostly same code
as mzsj86.c, just in a slightly different syntax, and it
probably only works with -O2. */
as mzsj86.c, just in a slightly different syntax. This code
is fragile, because it's not well defined whether the compiler
will generate frame-pointer setup; use mzsj86g.S, instead. */
#ifdef __MINGW32__
# if __OPTIMIZE__ > 0
# define NEED_STACK_FRAME_SETUP
# endif
#endif
int scheme_mz_setjmp(mz_pre_jmp_buf b)
{
#ifdef NEED_STACK_FRAME_SETUP
asm("push %EBP");
asm("mov %ESP, %EBP");
#endif
asm("mov 4(%EBP), %ECX"); /* return address */
asm("mov 8(%EBP), %EAX"); /* jmp_buf ptr */
asm("mov (%EBP), %EDX"); /* old EBP */
@ -671,12 +683,21 @@ int scheme_mz_setjmp(mz_pre_jmp_buf b)
asm("mov %ESI, 12(%EAX)");
asm("mov %ESP, 16(%EAX)");
asm("mov %ECX, 20(%EAX)");
#ifdef NEED_STACK_FRAME_SETUP
asm("pop %EBP");
#endif
return 0;
}
void scheme_mz_longjmp(mz_pre_jmp_buf b, int v)
{
#ifdef NEED_STACK_FRAME_SETUP
asm("push %EBP");
asm("mov %ESP, %EBP");
#endif
asm("mov 12(%EBP), %EAX"); /* return value */
asm("mov 8(%EBP), %ECX"); /* jmp_buf */
asm("mov 16(%ECX), %ESP"); /* restore stack pointer */
@ -688,6 +709,10 @@ void scheme_mz_longjmp(mz_pre_jmp_buf b, int v)
asm("mov 12(%ECX), %ESI");
asm("mov 20(%ECX), %ECX"); /* return address */
asm("mov %ECX, 4(%EBP)");
#ifdef NEED_STACK_FRAME_SETUP
asm("pop %EBP");
#endif
}
#endif

View File

@ -7921,10 +7921,6 @@ static Scheme_Object *will_executor_sema(Scheme_Object *w, int *repost)
/* GC preparation and timing */
/*========================================================================*/
#ifdef MZ_XFORM
START_XFORM_SKIP;
#endif
typedef struct Scheme_GC_Pre_Post_Callback_Desc {
/* All pointer fields => allocate with GC_malloc() */
Scheme_Object *boxed_key;
@ -7973,7 +7969,7 @@ void scheme_remove_gc_callback(Scheme_Object *key)
}
}
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__MINGW32__)
# define mzOSAPI WINAPI
#else
# define mzOSAPI /* empty */
@ -8128,6 +8124,10 @@ static void run_gc_callbacks(int pre)
}
}
#ifdef MZ_XFORM
START_XFORM_SKIP;
#endif
void scheme_zero_unneeded_rands(Scheme_Thread *p)
{
/* Call this procedure before GC or before copying out

View File

@ -21,17 +21,19 @@ This directory contains
Visual Studio Express is available for free from Microsoft; it can be
used to build Racket and GRacket, but not MzCOM.
Racket and GRacket also compile with Cygwin gcc (a free compiler from
GNU and Cygnus Solutions), but the result is a Unix-style installation,
not a Window-style installation. To compile with gcc, follow the
instructions in racket\src\README (which contains a short
Racket and GRacket also compile with MinGW. To compile with MinGW,
follow the instructions in racket\src\README (which contains a short
Windows-specific section).
Finally, Racket and GRacket also compile with Cygwin gcc (a free
compiler from GNU and Cygnus Solutions), but the result is a
Unix-style installation, not a Window-style installation. To compile
with gcc, follow the instructions in racket\src\README (which contains
a short Windows-specific section).
With an MSVC-built Racket, compatible extensions can be built with other
compilers. Build with Cygwin and copy the installed racket\lib\gcc to a
MSVC-based build to support Cygwin-built extensions. To support
Borland-built extensions, cd to racket\src\racket\dynsrc and run
mkbordyn.bat (which requires bcc23.exe, of course).
MSVC-based build to support Cygwin-built extensions.
As always, please report bugs via one of the following:
- DrRacket's "submit bug report" menu (preferred)

View File

@ -43,4 +43,12 @@ BEGIN
END
END
#ifndef RT_MANIFEST
#define RT_MANIFEST 24
#endif
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gracket.manifest"

View File

@ -43,4 +43,12 @@ BEGIN
END
END
#ifndef RT_MANIFEST
#define RT_MANIFEST 24
#endif
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "racket.manifest"