support for building MzCOM with MinGW

This commit is contained in:
Matthew Flatt 2015-08-26 13:13:28 -06:00
parent 828aff1476
commit 2a9022945d
12 changed files with 130 additions and 57 deletions

View File

@ -27,9 +27,9 @@ To compile with Microsoft Visual C, read the instructions in
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".
The result is a Windows-style build. 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. The
result is a Unix-style build, not a Windows-style build (e.g.,

View File

@ -470,8 +470,9 @@ static STDMETHODIMP Advise(IConnectionPoint *com_obj, IUnknown *obj, DWORD *cook
// We need to return (to the app) some value that will clue our Unadvise() function
// below how to locate this app IMzObjEvents. The simpliest thing is to just use the
// app's IMzObjEvents pointer as that returned value
*cookie = (DWORD)iExample->evts;
// app's IMzObjEvents pointer as that returned value. We may lose some bits here,
// but that's ok:
*cookie = (DWORD)(intptr_t)iExample->evts;
return(hr);
}
@ -496,10 +497,10 @@ static STDMETHODIMP Unadvise(IConnectionPoint *com_obj, DWORD cookie)
// IMzObjEvents right now.
//
// Let's just make sure the cookie he passed is really the pointer we expect
if (cookie && (IMzObjEvents *)cookie == iExample->evts)
if (cookie && cookie == (DWORD)(intptr_t)iExample->evts)
{
// Release the app's IMzObjEvents
((IMzObjEvents *)cookie)->lpVtbl->Release((IMzObjEvents *)cookie);
iExample->evts->lpVtbl->Release(iExample->evts);
// We no longer have the app's IMzObjEvents, so clear the IMzObj
// feedback member
@ -672,7 +673,7 @@ HRESULT com_register()
// Initialize my IClassFactory with the pointer to its vtable
MyIClassFactoryObj.lpVtbl = (IClassFactoryVtbl *)&IClassFactory_Vtbl;
return CoRegisterClassObject(&CLSID_IMzObj, &MyIClassFactoryObj,
return CoRegisterClassObject(&CLSID_IMzObj, (IUnknown*)&MyIClassFactoryObj,
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &reg_cookie);
}

View File

@ -65,12 +65,12 @@ static bool StartMonitor() { return TRUE; }
#endif
static int set_reg_string(HKEY sub, char *name, char *s)
static int set_reg_string(HKEY sub, const char *name, const char *s)
{
return RegSetValueExA(sub, name, 0, REG_SZ, (const BYTE *)s, strlen(s));
}
static int set_reg_sub_string(HKEY sub, char *name, char *s)
static int set_reg_sub_string(HKEY sub, const char *name, const char *s)
{
HKEY sub2;
int nRet;
@ -86,10 +86,10 @@ static int set_reg_sub_string(HKEY sub, char *name, char *s)
LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
while (p1 != NULL && *p1 != NULL)
while (p1 != NULL && *p1 != 0)
{
LPCTSTR p = p2;
while (p != NULL && *p != NULL)
while (p != NULL && *p != 0)
{
if (*p1 == *p)
return CharNext(p1);

View File

@ -35,7 +35,7 @@ END_XFORM_SKIP;
START_XFORM_SKIP;
#endif
static void ErrorBox(char *s) {
static void ErrorBox(const char *s) {
::MessageBox(NULL,s,"MzCOM",MB_OK);
}
@ -112,12 +112,12 @@ static Scheme_Object *eval_string_or_get_exn_message(char *s) {
return exn;
}
OLECHAR *wideStringFromSchemeObj(Scheme_Object *obj,char *fmt,int fmtlen) {
OLECHAR *wideStringFromSchemeObj(Scheme_Object *obj,const char *fmt,int fmtlen) {
char *s;
OLECHAR *wideString;
int len;
s = scheme_format_utf8(fmt,fmtlen,1,&obj,NULL);
s = scheme_format_utf8((char *)fmt,fmtlen,1,&obj,NULL);
len = strlen(s);
wideString = (OLECHAR *)scheme_malloc((len + 1) * sizeof(OLECHAR));
MultiByteToWideChar(CP_ACP,(DWORD)0,s,len,wideString,len + 1);
@ -133,7 +133,7 @@ void exitHandler(int) {
void setupSchemeEnv(Scheme_Env *in_env)
{
char *wrapper;
const char *wrapper;
char exeBuff[260];
HMODULE mod;
static BOOL registered;
@ -308,12 +308,10 @@ static int record_at_exit(Scheme_At_Exit_Callback_Proc p) XFORM_SKIP_PROC
return 0;
}
static __declspec(thread) void *tls_space;
#include "../racket/win_tls.inc"
static unsigned WINAPI evalLoop(void *args) XFORM_SKIP_PROC {
#ifndef _WIN64
scheme_register_tls_space(&tls_space, 0);
#endif
register_win_tls();
scheme_set_atexit(record_at_exit);
return scheme_main_setup(1, do_evalLoop, 0, (char **)args);
@ -563,6 +561,20 @@ HRESULT mzobj_eval(void *o, BSTR s, BSTR *r)
return ((CMzObj *)o)->Eval(s, r);
}
#ifdef __MINGW32__
void * operator new(size_t n)
{
return malloc(n);
}
void operator delete(void * p)
{
free(p);
}
#endif
#ifdef MZ_PRECISE_GC
END_XFORM_SKIP;
#endif

Binary file not shown.

View File

@ -0,0 +1,3 @@
Scine MinGW doesn't currently include `widl`, since installing it with
Wine is a pain, and since the output is not platform-specific, we
include "MzCOM.tlb" as pre-built from "mzcom.idl".

View File

@ -89,13 +89,15 @@ cgc:
$(MAKE) common
$(MAKE) dynlib
$(MAKE) mzlibrary
$(MAKE) racket@CGC@
$(MAKE) racket@CGC@
$(MAKE) mzcom@CGC@
3m:
$(MAKE) @CGC_IF_NEEDED_FOR_MMM@
cd gc2; $(MAKE) all
cd dynsrc; $(MAKE) dynlib3m
cd gc2; $(MAKE) ../racket@MMM@
cd gc2; $(MAKE) ../mzcom@MMM@
both:
$(MAKE) cgc
@ -173,6 +175,9 @@ sproc.@LTO@: @GCDIR@/sproc.@LTO@
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@
mzcom@CGC@@NOT_MINGW@:
$(NOOP)
# Mac OS ----------------------------------------
MZFW = Racket.framework/Versions/$(FWVERSION)/Racket
@ -209,15 +214,23 @@ libmzgc.dll.a: lib/libmzgcxxxxxxx.dll
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 -static-libgcc
MW_RACKET_LIBS = libracket.dll.a libmzgc.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc
mingw-other@MINGW@: mzsj86g.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) $(MW_RACKET_LIBS)
mingw-other@MINGW@: mzsj86g.o rres.o comres.o com_glue.@LTO@
$(NOOP)
mingw-other@NOT_MINGW@:
$(NOOP)
mzcom@CGC@@MINGW@: libracket.dll.a libmzgc.dll.a mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ $(SPECIALIZINGOBJECTS) comres.o
@MZLINKER@ -o mzcom@CGC@ mzcom.@LTO@ mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS)
comres.o : $(srcdir)/../worksp/mzcom/mzcom.rc $(srcdir)/../mzcom/prebuilt/MzCOM.tlb
@WINDRES@ -I $(srcdir)/../mzcom -I $(srcdir)/../mzcom/prebuilt -i $(srcdir)/../worksp/mzcom/mzcom.rc -o comres.o
# OSKit ----------------------------------------
racket.multiboot : libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@
@ -238,7 +251,7 @@ DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
MAIN_HEADER_DEPS = $(srcdir)/include/scheme.h $(srcdir)/include/schthread.h $(srcdir)/sconfig.h \
$(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/parse_cmdl.inc \
$(srcdir)/oskglue.inc
$(srcdir)/oskglue.inc $(srcdir)/delayed.inc $(srcdir)/parse_cmdl.inc
main.@LTO@: $(srcdir)/main.c $(MAIN_HEADER_DEPS)
$(CC) -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ $(DEF_C_DIRS) -c $(srcdir)/main.c -o main.@LTO@
@ -257,6 +270,17 @@ mzstart.exe: $(srcdir)/dynsrc/start.c
starter: mzstart.exe
MZCOM_DEPS = $(MAIN_HEADER_DEPS) $(srcdir)/../mzcom/com_glue.h $(srcdir)/../mzcom/resource.h
mzcom.@LTO@: $(srcdir)/../mzcom/mzcom.cxx $(MZCOM_DEPS)
$(CC) -fno-exceptions -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ $(DEF_C_DIRS) -c $(srcdir)/../mzcom/mzcom.cxx -o mzcom.@LTO@
mzobj.@LTO@: $(srcdir)/../mzcom/mzobj.cxx $(MZCOM_DEPS)
$(CC) -fno-exceptions -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ -c $(srcdir)/../mzcom/mzobj.cxx -o mzobj.@LTO@
com_glue.@LTO@: $(srcdir)/../mzcom/com_glue.c $(MZCOM_DEPS)
$(CC) -I$(builddir) -I$(srcdir)/include $(CFLAGS) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@ -c $(srcdir)/../mzcom/com_glue.c -o com_glue.@LTO@
exn:
$(MAKE) $(srcdir)/src/schexn.h
$(MAKE) $(collectsdir)/racket/private/kernstruct.rkt
@ -403,14 +427,18 @@ mingw-install:
cd ..; cp racket/mrstarter@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MzStart@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libpltdir)/MrStart@EXE_SUFFIX@"
cp "$(srcdir)/../mzcom/prebuilt/MzCOM.tlb" MzCOM.tlb
cd ..; cp racket/MzCOM.tlb "$(DESTDIR)$(libpltdir)/MzCOM.tlb"
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@@EXE_SUFFIX@"
cd ..; $(ICP) racket/mzcom@CGC@ "$(DESTDIR)$(libdir)/MzCOM@CGC_INSTALLED@@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libmzgcxxxxxxx.dll"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracketxxxxxxx.dll"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/MzCOM@CGC_INSTALLED@@EXE_SUFFIX@"
@RUN_RACKET_CGC@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@
mingw-install-cgc-final:
@ -418,9 +446,11 @@ mingw-install-cgc-final:
mingw-install-3m:
cd ..; $(ICP) racket/racket@MMM@ "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"
cd ..; $(ICP) racket/mzcom@MMM@ "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@"
cd ..; $(ICP) racket/lib/libracket3mxxxxxxx.dll "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/libracket3mxxxxxxx.dll"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(libdir)/MzCOM@MMM_INSTALLED@@EXE_SUFFIX@"
@RUN_RACKET_MMM@ -cu "$(srcdir)/collects-path.rkt" @DIRCVTPRE@"$(DESTDIR)@MZINSTALLBINDIR@/Racket@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@
mingw-install-3m-final:

View File

@ -21,10 +21,10 @@ static int _dlldir_offset = 14; /* Skip permanent tag */
START_XFORM_SKIP;
# endif
static void load_delayed_dll(HINSTANCE me, char *lib)
static void load_delayed_dll(HINSTANCE me, const char *lib)
{
/* Don't use the C library here! */
wchar_t *dlldir = _dlldir + _dlldir_offset;
const wchar_t *dlldir = _dlldir + _dlldir_offset;
if (dlldir[0] != '<') {
if ((dlldir[0] == '\\')

View File

@ -313,6 +313,9 @@ $(XSRCDIR)/foreign.c: $(XFORMDEP)
$(XSRCDIR)/main.c: $(XFORMDEP)
$(XFORM_NOPRECOMP) $(XSRCDIR)/main.c $(DEF_C_DIRS) $(srcdir)/../main.c
$(XSRCDIR)/mzobj.cxx: $(XFORMDEP)
$(XFORM_NOPRECOMP) $(XSRCDIR)/mzobj.cxx $(DEF_C_DIRS) $(srcdir)/../../mzcom/mzobj.cxx
salloc.@LTO@: $(XSRCDIR)/salloc.c
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/salloc.c -o salloc.@LTO@
bignum.@LTO@: $(XSRCDIR)/bignum.c
@ -428,6 +431,11 @@ foreign.@LTO@: $(XSRCDIR)/foreign.c
main.@LTO@: $(XSRCDIR)/main.c
$(CC) $(ALL_CFLAGS) -c $(XSRCDIR)/main.c -o main.@LTO@
mzcom.@LTO@: $(srcdir)/../../mzcom/mzcom.cxx
$(CC) -DMZCOM_3M $(ALL_CFLAGS) -fno-exceptions -c $(srcdir)/../../mzcom/mzcom.cxx -o mzcom.@LTO@
mzobj.@LTO@: $(XSRCDIR)/mzobj.cxx
$(CC) $(ALL_CFLAGS) -fno-exceptions -c $(XSRCDIR)/mzobj.cxx -o mzobj.@LTO@
gc2.@LTO@: \
$(srcdir)/alloc_cache.c \
$(srcdir)/block_cache.c \
@ -523,9 +531,16 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@
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 -static-libgcc
MW_RACKET_LIBS = gc2/libracket3m.dll.a @LDFLAGS@ @LIBS@ -ldelayimp -static-libgcc
../racket@MMM@@MINGW@: libracket3m.dll.a main.@LTO@ ../rres.o $(SPECIALIZINGOBJECTS)
cd ..; @MZLINKER@ -o racket@MMM@ gc2/main.@LTO@ rres.o $(SPECIALIZINGOBJECTS) $(MW_RACKET_LIBS)
../mzcom@MMM@@NOT_MINGW@:
$(NOOP)
../mzcom@MMM@@MINGW@: libracket3m.dll.a mzcom.@LTO@ mzobj.@LTO@ ../com_glue.@LTO@ $(SPECIALIZINGOBJECTS) ../comres.o
cd ..; @MZLINKER@ -o mzcom@MMM@ gc2/mzcom.@LTO@ gc2/mzobj.@LTO@ com_glue.@LTO@ comres.o $(SPECIALIZINGOBJECTS) -lole32 -loleaut32 -luuid $(MW_RACKET_LIBS)
clean:
/bin/rm -f ../racket@MMM@ *.@LTO@ $(XSRCDIR)/*

View File

@ -292,13 +292,8 @@ START_XFORM_SKIP;
# include "parse_cmdl.inc"
#endif
#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
extern intptr_t _tls_index;
# ifdef __MINGW32__
static __thread void *tls_space;
# else
static __declspec(thread) void *tls_space;
# endif
#ifdef DOS_FILE_SYSTEM
# include "win_tls.inc"
#endif
#ifdef DOS_FILE_SYSTEM
@ -314,25 +309,8 @@ void load_delayed()
load_delayed_dll(NULL, "libracket" DLL_3M_SUFFIX "xxxxxxx.dll");
# endif
record_dll_path();
# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
# ifdef __MINGW32__
{
/* gcc declares space for the thread-local variable in a way that
the OS can set up, but its doesn't actually map variables
through the OS-supplied mechanism. Just assume that the first
thread-local variable is ours. */
void **base;
# ifdef _WIN64
asm("mov %%gs:(0x58), %0;" :"=r"(base));
# else
asm("mov %%fs:(0x2C), %0;" :"=r"(base));
# endif
scheme_register_tls_space(*base, _tls_index);
}
# else
scheme_register_tls_space(&tls_space, _tls_index);
# endif
# endif
register_win_tls();
}
#endif

View File

@ -328,7 +328,8 @@ int mz_proc_thread_detach(mz_proc_thread *thread) {
void mz_proc_thread_exit(void *rc) {
#ifdef WIN32
_endthreadex((unsigned)rc);
proc_thread_self->res = rc;
_endthreadex(0);
#else
# ifndef MZ_PRECISE_GC
pthread_exit(rc);

View File

@ -0,0 +1,33 @@
#ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
extern intptr_t _tls_index;
# ifdef __MINGW32__
static __thread void *tls_space;
# else
static __declspec(thread) void *tls_space;
# endif
#endif
# ifdef IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
static void register_win_tls()
{
# ifdef __MINGW32__
{
/* gcc declares space for the thread-local variable in a way that
the OS can set up, but its doesn't actually map variables
through the OS-supplied mechanism. Just assume that the first
thread-local variable is ours. */
void **base;
# ifdef _WIN64
asm("mov %%gs:(0x58), %0;" :"=r"(base));
# else
asm("mov %%fs:(0x2C), %0;" :"=r"(base));
# endif
scheme_register_tls_space(*base, _tls_index);
}
# else
scheme_register_tls_space(&tls_space, _tls_index);
# endif
}
# else
static void register_win_tls() {}
# endif