Bug 751541 - Fix for VS11 C++/CX link issues: delay load vccorlib and the winrt standard libraries, and provide a dummy vccorlib on non-win8 platforms so xul lib can load. r=ehsan+khuey, sr=bsmedberg

This commit is contained in:
Jim Mathies 2012-05-22 16:00:48 -05:00
parent 3ac258f511
commit 535421dfcb
6 changed files with 125 additions and 0 deletions

View File

@ -524,6 +524,8 @@ MOZ_ENABLE_D2D_SURFACE = @MOZ_ENABLE_D2D_SURFACE@
MOZ_ENABLE_D3D9_LAYER = @MOZ_ENABLE_D3D9_LAYER@
MOZ_ENABLE_D3D10_LAYER = @MOZ_ENABLE_D3D10_LAYER@
MOZ_METRO = @MOZ_METRO@
CRTDLLVERSION = @CRTDLLVERSION@
CRTEXPDLLVERSION = @CRTEXPDLLVERSION@
MOZ_GTK2_CFLAGS = @MOZ_GTK2_CFLAGS@
MOZ_GTK2_LIBS = @MOZ_GTK2_LIBS@

View File

@ -618,12 +618,18 @@ if test -n "$MOZ_METRO"; then
WINSDK_TARGETVER=602
# Allow a higher api set
WINVER=602
# toolkit/library/makefile.in needs these, see nsDllMain.
CRTDLLVERSION=110
CRTEXPDLLVERSION=1-1-0
else
# Target the Windows 7 SDK by default
WINSDK_TARGETVER=601
WINVER=502
fi
AC_SUBST(CRTDLLVERSION)
AC_SUBST(CRTEXPDLLVERSION)
if test -n "$MOZ_METRO"; then
case "$target" in
*-mingw*)

View File

@ -17,6 +17,10 @@ LIBRARY_NAME = xul
FORCE_SHARED_LIB = 1
MOZILLA_INTERNAL_API = 1
ifdef MOZ_METRO
DIRS += winvccorlib
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
# This is going to be a framework named "XUL", not an ordinary library named
# "libxul.dylib"
@ -544,6 +548,18 @@ EXTRA_DSO_LDOPTS += \
-DELAYLOAD:winspool.drv \
-DELAYLOAD:secur32.dll \
$(NULL)
# See nsDllMain for an explanation
ifdef MOZ_METRO
ifdef MOZ_DEBUG
EXTRA_DSO_LDOPTS += -DELAYLOAD:VCCORLIB$(CRTDLLVERSION)D.DLL
else
EXTRA_DSO_LDOPTS += -DELAYLOAD:VCCORLIB$(CRTDLLVERSION).DLL
endif
EXTRA_DSO_LDOPTS += -DELAYLOAD:API-MS-WIN-CORE-WINRT-L$(CRTEXPDLLVERSION).DLL
EXTRA_DSO_LDOPTS += -DELAYLOAD:API-MS-WIN-CORE-WINRT-STRING-L$(CRTEXPDLLVERSION).DLL
endif
ifdef ACCESSIBILITY
EXTRA_DSO_LDOPTS += -DELAYLOAD:oleacc.dll
endif

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h>
#include <delayimp.h>
#include "nsToolkit.h"
#if defined(__GNUC__)
@ -36,6 +37,63 @@ BOOL APIENTRY DllMain(
return TRUE;
}
#if defined(MOZ_METRO)
/*
* DelayDllLoadHook - the crt calls here anytime a delay load dll is about to
* load. There are a number of events, we listen for dliNotePreLoadLibrary.
*
* On Win8, we enable Windows Runtime Component Extension support. When enabled
* the compiler bakes auto-generated code into our binary, including a c init-
* ializer which inits the winrt library through a call into the winrt standard
* lib 'vccorlib'. Vccorlib in turn has system dll dependencies which are only
* available on Win8 (currently API-MS-WIN-CORE-WINRT and
* API-MS-WIN-CORE-WINRT-STRING), which prevent xul.dll from loading on os <=
* Win7. To get around this we generate a dummy vccore lib with the three entry
* points the initializer needs and load it in place of the real vccorlib. We
* also have to add vccorlib and the system dlls to the delay load list.
*/
static bool IsWin8OrHigher()
{
static PRInt32 version = 0;
if (version) {
return (version >= 0x602);
}
// Match Win8 or Win8 Server or higher
OSVERSIONINFOEX osInfo;
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
::GetVersionEx((OSVERSIONINFO*)&osInfo);
version =
(osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
return (version >= 0x602);
}
const char* kvccorlib = "vccorlib";
const char* kwinrtprelim = "api-ms-win-core-winrt";
static bool IsWinRTDLLPresent(PDelayLoadInfo pdli, const char* aLibToken)
{
return (!IsWin8OrHigher() && pdli->szDll &&
!strnicmp(pdli->szDll, aLibToken, strlen(aLibToken)));
}
FARPROC WINAPI DelayDllLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
if (dliNotify == dliNotePreLoadLibrary) {
if (IsWinRTDLLPresent(pdli, kvccorlib)) {
return (FARPROC)LoadLibraryA("dummyvccorlib.dll");
}
NS_ASSERTION(!IsWinRTDLLPresent(pdli, kwinrtprelim),
"Attempting to load winrt libs in non-metro environment. "
"(Winrt variable type placed in global scope?)");
}
return NULL;
}
ExternC PfnDliHook __pfnDliNotifyHook2 = DelayDllLoadHook;
#endif // MOZ_METRO
#if defined(__GNUC__)
} // extern "C"
#endif

View File

@ -0,0 +1,23 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
LIBRARY_NAME = dummyvccorlib
MODULE = dummyvccorlib
GRE_MODULE = 1
include $(DEPTH)/config/autoconf.mk
FORCE_SHARED_LIB=1
CPPSRCS = \
dummyvccorlib.cpp \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h>
// A dummy vccorlib.dll for shunting winrt initialization calls when we are not
// using the winrt library. For a longer explanantion see nsDllMain.cpp.
extern "C" {
__declspec(dllexport) long __stdcall __InitializeWinRTRuntime(unsigned long data) { return S_OK; }
}
namespace Platform {
namespace Details {
__declspec(dllexport) HRESULT InitializeData(int __threading_model) { return S_OK; }
__declspec(dllexport) void UninitializeData(int __threading_model) { }
}
}