diff --git a/c/Mf-ta6nt b/c/Mf-ta6nt index 5df2d40d0b..2709378ee6 100644 --- a/c/Mf-ta6nt +++ b/c/Mf-ta6nt @@ -21,10 +21,11 @@ o = obj mdobj=windows.$o mdsrc=windows.c Makefile.$m cs.ico scheme.rc make.bat mdclean=vs.bat make.bat scheme.res ../bin/$m/*.exp mtscheme.exe* mdscheme.exe* +cross=f include Mf-base -${Scheme}: make.bat +${Scheme}${cross:f=}: make.bat cmd.exe /c make.bat cp ../bin/$m/scheme.exe ../bin/$m/petite.exe cp ../bin/$m/scheme.pdb ../bin/$m/petite.pdb @@ -34,3 +35,20 @@ make.bat: vs.bat echo 'set MAKEFLAGS=' >> $@ echo 'vs.bat amd64 && nmake /f Makefile.$m /nologo %*' >> $@ chmod +x $@ + +# -------------------------------------------------- +# For cross-compilation, triggered by setting cross=t + +C = ${CC} ${CPPFLAGS} -O2 ${CFLAGS} + +${Scheme}${cross:t=}: ${Kernel} ${Main} + $C -o ${Scheme} ${Kernel} ${Main} ${mdclib} ${LDFLAGS} -lshell32 -luser32 -lole32 -lRpcrt4 -luuid + +.c.$o: + $C -c -D${Cpu} -I${Include} -I../zlib $*.c + +${Kernel}: ${kernelobj} ../zlib/libz.a + $(LD) -r -X -o ${Kernel} ${kernelobj} ../zlib/libz.a + +../zlib/configure.log: + (cd ../zlib; env CC="$(CC)" CFLAGS="$(CFLAGS)" AR="$(AR)" RANLIB="$(RANLIB)" ./configure --uname=CYGWIN) diff --git a/c/main.c b/c/main.c index 080cbb5cb6..de8c71959f 100644 --- a/c/main.c +++ b/c/main.c @@ -59,12 +59,13 @@ static const char *path_last(const char *p) { return p; } -#ifdef WIN32 +#if defined(WIN32) && !defined(__MINGW32__) #define GETENV Sgetenv #define GETENV_FREE free int wmain(int argc, wchar_t* wargv[], wchar_t* wenvp[]) { const char** argv = (char**)malloc((argc + 1) * sizeof(char*)); - for (int i = 0; i < argc; i++) { + int i; + for (i = 0; i < argc; i++) { wchar_t* warg = wargv[i]; if (NULL == (argv[i] = Swide_to_utf8(warg))) { fprintf_s(stderr, "Invalid argument: %S\n", warg); diff --git a/c/scheme.c b/c/scheme.c index d53b625c45..a04f61effb 100644 --- a/c/scheme.c +++ b/c/scheme.c @@ -389,7 +389,7 @@ void S_generic_invoke(tc, code) ptr tc; ptr code; { hdr.env = (I32)0; p = (ugly)((I32)&hdr + 2); p(tc); -#elif defined(WIN32) +#elif defined(WIN32) && !defined(__MINGW32__) __try { (*((void (*) PROTO((ptr)))(void *)&CODEIT(code,0)))(tc); } diff --git a/c/segment.h b/c/segment.h index abe28858b8..0d6c3b0210 100644 --- a/c/segment.h +++ b/c/segment.h @@ -15,8 +15,10 @@ */ #ifdef WIN32 -#undef FORCEINLINE -#define FORCEINLINE static __forceinline +# ifndef __MINGW32__ +# undef FORCEINLINE +# define FORCEINLINE static __forceinline +# endif #else #define FORCEINLINE static inline #endif diff --git a/c/system.h b/c/system.h index 565155aacf..9bb340e1c8 100644 --- a/c/system.h +++ b/c/system.h @@ -17,6 +17,10 @@ #include "scheme.h" #include "equates.h" #ifdef FEATURE_WINDOWS +#ifdef __MINGW32__ +# undef WINVER +# undef _WIN32_WINNT +#endif #define WINVER 0x0601 // Windows 7 #define _WIN32_WINNT WINVER #include diff --git a/c/types.h b/c/types.h index 34b61c76d8..ce8ec0a79d 100644 --- a/c/types.h +++ b/c/types.h @@ -349,11 +349,24 @@ typedef struct { #define tc_mutex_release() {} #endif +#ifdef __MINGW32__ +/* With MinGW on 64-bit Windows, setjmp/longjmp is not reliable. Using + __builtin_setjmp/__builtin_longjmp is reliable, but + __builtin_longjmp requires 1 as its second argument. So, allocate + room in the buffer for a return value. Using 16 bytes of extra + room should preserves any relavant alignment. */ +# define JMPBUF_RET(jb) (*(int *)((char *)(jb)+sizeof(jmp_buf))) +# define CREATEJMPBUF() malloc(sizeof(jmp_buf)+16) +# define FREEJMPBUF(jb) free(jb) +# define SETJMP(jb) (JMPBUF_RET(jb) = 0, __builtin_setjmp(jb), JMPBUF_RET(jb)) +# define LONGJMP(jb,n) (JMPBUF_RET(jb) = n, __builtin_longjmp(jb, 1)) +#else /* assuming malloc will give us required alignment */ -#define CREATEJMPBUF() malloc(sizeof(jmp_buf)) -#define FREEJMPBUF(jb) free(jb) -#define SETJMP(jb) _setjmp(jb) -#define LONGJMP(jb,n) _longjmp(jb, n) +# define CREATEJMPBUF() malloc(sizeof(jmp_buf)) +# define FREEJMPBUF(jb) free(jb) +# define SETJMP(jb) _setjmp(jb) +# define LONGJMP(jb,n) _longjmp(jb, n) +#endif #define DOUNDERFLOW\ &CODEIT(CLOSCODE(S_lookup_library_entry(library_dounderflow, 1)),size_rp_header) diff --git a/c/version.h b/c/version.h index ebb4937a07..fd704f8078 100644 --- a/c/version.h +++ b/c/version.h @@ -199,11 +199,17 @@ typedef int tputsputcchar; #define USE_VIRTUAL_ALLOC #define NAN_INCLUDE #define MAKE_NAN(x) { x = sqrt(-1.0); } -#define PATH_MAX _MAX_PATH +#ifndef PATH_MAX +# define PATH_MAX _MAX_PATH +#endif typedef char *memcpy_t; -#define _setjmp setjmp -#define _longjmp longjmp +#ifndef __MINGW32__ +# define _setjmp setjmp +# define _longjmp longjmp +#endif +#ifndef __MINGW32__ #define ftruncate _chsize_s +#endif #define LOCK_SH 1 #define LOCK_EX 2 #define LOCK_NB 4 diff --git a/configure b/configure index f26066054b..5efab7e8d6 100755 --- a/configure +++ b/configure @@ -217,9 +217,21 @@ while [ $# != 0 ] ; do CFLAGS=*) CFLAGS=`echo $1 | sed -e 's/^CFLAGS=//'` ;; + LD=*) + LD=`echo $1 | sed -e 's/^LD=//'` + ;; LDFLAGS=*) LDFLAGS=`echo $1 | sed -e 's/^LDFLAGS=//'` ;; + AR=*) + AR=`echo $1 | sed -e 's/^AR=//'` + ;; + ARFLAGS=*) + ARFLAGS=`echo $1 | sed -e 's/^ARFLAGS=//'` + ;; + RANLIB=*) + RANLIB=`echo $1 | sed -e 's/^RANLIB=//'` + ;; *) echo "option '$1' unrecognized or missing an argument; try $0 --help" exit 1 @@ -295,9 +307,14 @@ if [ "$help" = "yes" ]; then echo " --installscriptname= install with group ($installscriptname)" echo " --[no]gzip-man-pages compress manual pages ($gzipmanpages)" echo " --workarea= build directory ($w)" + echo " CC= C compiler" echo " CPPFLAGS= additional C preprocessor flags ($CPPFLAGS)" echo " CFLAGS= additional C compiler flags ($CFLAGS)" + echo " LD= linker" echo " LDFLAGS= additional linker flags ($LDFLAGS)" + echo " AR= archiver" + echo " ARFLAGS= archiver flags" + echo " RANLIB= archive indexer" echo "" echo "Available machine types: $machs" echo "" @@ -402,7 +419,11 @@ cat > $w/c/Mf-config << END CC=$CC CPPFLAGS=$CPPFLAGS CFLAGS=$CFLAGS +LD=$LD LDFLAGS=$LDFLAGS LIBCURSES=$LIBCURSES LIBNCURSES=$LIBNCURSES +AR=$AR +ARFLAGS=$ARFLAGS +RANLIB=$RANLIB END