Bug 755724 - Don't use the xulrunner stub when building Firefox against a libxul SDK. r=bsmedberg
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 03 Jan 2013 16:04:42 +0100
changeset 126542 f438f50b8bb31e4f69c3e5e6b8c557cf95ca7c2c
parent 126541 8df6f376fdfb82710e33c8ffcdaa90a72dc52703
child 126543 b28771946018e90626908eb28b1d934d69a34765
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs755724
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 755724 - Don't use the xulrunner stub when building Firefox against a libxul SDK. r=bsmedberg
browser/app/Makefile.in
browser/app/nsBrowserApp.cpp
configure.in
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -31,19 +31,19 @@ DEFINES += \
   -DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \
   -DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \
   -DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \
 
   $(NULL)
 
 ifdef LIBXUL_SDK #{
 PREF_JS_EXPORTS += $(srcdir)/profile/channel-prefs.js
+DEFINES += -DLIBXUL_SDK
+endif #} LIBXUL_SDK
 
-include $(topsrcdir)/config/rules.mk
-else
 # Build a binary bootstrapping with XRE_main
 
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/toolkit/xre \
@@ -125,18 +125,16 @@ ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH
 
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 
 GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, firefox.js)
 
 endif
 
-endif #} LIBXUL_SDK
-
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs::
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(FINAL_TARGET)/icons
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png  $(FINAL_TARGET)/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png  $(FINAL_TARGET)/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png  $(FINAL_TARGET)/chrome/icons/default
 endif
 
@@ -183,31 +181,21 @@ libs-preqs = \
 
 .PHONY: repackage
 libs repackage:: $(PROGRAM) $(libs-preqs)
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/Contents/Resources/$(AB).lproj
 	sed -e "s/%APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" -e "s/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/" -e "s/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
 	sed -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
-ifdef LIBXUL_SDK
-	cp $(LIBXUL_DIST)/bin/$(XR_STUB_NAME) $(dist_dest)/Contents/MacOS/firefox
-else
 	$(RM) $(dist_dest)/Contents/MacOS/$(PROGRAM)
 	rsync -aL $(PROGRAM) $(dist_dest)/Contents/MacOS
-endif
 	cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
 	printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
-
-else
-ifdef LIBXUL_SDK
-libs::
-	cp $(LIBXUL_DIST)/bin/$(XULRUNNER_STUB_NAME)$(BIN_SUFFIX) $(DIST)/bin/firefox$(BIN_SUFFIX)
-endif
 endif
 
 ifdef LIBXUL_SDK #{
 ifndef SKIP_COPY_XULRUNNER #{
 libs::
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
 	rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(dist_dest)/Contents/Frameworks
 else
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -1,22 +1,24 @@
 /* -*- 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 "nsXULAppAPI.h"
+#include "mozilla/AppData.h"
 #include "application.ini.h"
 #include "nsXPCOMGlue.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <unistd.h>
 #endif
 
 #ifdef XP_MACOSX
 #include "MacQuirks.h"
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -33,16 +35,18 @@
 #define strcasecmp _stricmp
 #endif
 #include "BinaryPath.h"
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
 
 #include "mozilla/Telemetry.h"
 
+using namespace mozilla;
+
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
 
 #ifndef XP_WIN
   vfprintf(stderr, fmt, ap);
 #else
@@ -116,17 +120,17 @@ static const nsDynamicFunctionLoad kXULF
     { "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
 #endif
     { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
     { "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
     { "XRE_main", (NSFuncPtr*) &XRE_main },
     { nullptr, nullptr }
 };
 
-static int do_main(int argc, char* argv[])
+static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
 {
   nsCOMPtr<nsIFile> appini;
   nsresult rv;
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
@@ -161,22 +165,37 @@ static int do_main(int argc, char* argv[
 
   if (appini) {
     nsXREAppData *appData;
     rv = XRE_CreateAppData(appini, &appData);
     if (NS_FAILED(rv)) {
       Output("Couldn't read application.ini");
       return 255;
     }
+    // xreDirectory already has a refcount from NS_NewLocalFile
+    appData->xreDirectory = xreDirectory;
     int result = XRE_main(argc, argv, appData, 0);
     XRE_FreeAppData(appData);
     return result;
   }
 
-  return XRE_main(argc, argv, &sAppData, 0);
+  ScopedAppData appData(&sAppData);
+  nsCOMPtr<nsIFile> exeFile;
+  rv = mozilla::BinaryPath::GetFile(argv[0], getter_AddRefs(exeFile));
+  if (NS_FAILED(rv)) {
+    Output("Couldn't find the application directory.\n");
+    return 255;
+  }
+  nsCOMPtr<nsIFile> appDir;
+  exeFile->GetParent(getter_AddRefs(appDir));
+
+  SetStrongPtr(appData.directory, static_cast<nsIFile*>(appDir.get()));
+  // xreDirectory already has a refcount from NS_NewLocalFile
+  appData.xreDirectory = xreDirectory;
+  return XRE_main(argc, argv, &appData, 0);
 }
 
 /* Local implementation of PR_Now, since the executable can't depend on NSPR */
 static PRTime _PR_Now()
 {
 #ifdef XP_WIN
   MOZ_STATIC_ASSERT(sizeof(PRTime) == sizeof(FILETIME), "PRTime must have the same size as FILETIME");
   FILETIME ft;
@@ -191,60 +210,148 @@ static PRTime _PR_Now()
 
 #else
   struct timeval tm;
   gettimeofday(&tm, 0);
   return (((PRTime)tm.tv_sec * 1000000LL) + (PRTime)tm.tv_usec);
 #endif
 }
 
+static bool
+FileExists(const char *path)
+{
+#ifdef XP_WIN
+  wchar_t wideDir[MAX_PATH];
+  MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
+  DWORD fileAttrs = GetFileAttributesW(wideDir);
+  return fileAttrs != INVALID_FILE_ATTRIBUTES;
+#else
+  return access(path, R_OK) == 0;
+#endif
+}
+
+#ifdef LIBXUL_SDK
+#  define XPCOM_PATH "xulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL
+#else
+#  define XPCOM_PATH XPCOM_DLL
+#endif
+static nsresult
+InitXPCOMGlue(const char *argv0, nsIFile **xreDirectory)
+{
+  char exePath[MAXPATHLEN];
+
+  nsresult rv = mozilla::BinaryPath::Get(argv0, exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't find the application directory.\n");
+    return rv;
+  }
+
+  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
+  if (!lastSlash || (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_PATH) - 1))
+    return NS_ERROR_FAILURE;
+
+  strcpy(lastSlash + 1, XPCOM_PATH);
+  lastSlash += sizeof(XPCOM_PATH) - sizeof(XPCOM_DLL);
+
+  if (!FileExists(exePath)) {
+#if defined(LIBXUL_SDK) && defined(XP_MACOSX)
+    // Check for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib
+    bool greFound = false;
+    CFBundleRef appBundle = CFBundleGetMainBundle();
+    if (!appBundle)
+      return NS_ERROR_FAILURE;
+    CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle);
+    CFURLRef absfwurl = nullptr;
+    if (fwurl) {
+      absfwurl = CFURLCopyAbsoluteURL(fwurl);
+      CFRelease(fwurl);
+    }
+    if (absfwurl) {
+      CFURLRef xulurl =
+        CFURLCreateCopyAppendingPathComponent(NULL, absfwurl,
+                                              CFSTR("XUL.framework"),
+                                              true);
+
+      if (xulurl) {
+        CFURLRef xpcomurl =
+          CFURLCreateCopyAppendingPathComponent(NULL, xulurl,
+                                                CFSTR("libxpcom.dylib"),
+                                                false);
+
+        if (xpcomurl) {
+          if (CFURLGetFileSystemRepresentation(xpcomurl, true,
+                                               (UInt8*) exePath,
+                                               sizeof(exePath)) &&
+              access(tbuffer, R_OK | X_OK) == 0) {
+            if (realpath(tbuffer, exePath)) {
+              greFound = true;
+            }
+          }
+          CFRelease(xpcomurl);
+        }
+        CFRelease(xulurl);
+      }
+      CFRelease(absfwurl);
+    }
+  }
+  if (!greFound) {
+#endif
+    Output("Could not find the Mozilla runtime.\n");
+    return NS_ERROR_FAILURE;
+  }
+
+  // We do this because of data in bug 771745
+  XPCOMGlueEnablePreload();
+
+  rv = XPCOMGlueStartup(exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XPCOM.\n");
+    return rv;
+  }
+
+  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XRE functions.\n");
+    return rv;
+  }
+
+  // chop XPCOM_DLL off exePath
+  *lastSlash = '\0';
+#ifdef XP_WIN
+  NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
+                  xreDirectory);
+#else
+  NS_NewNativeLocalFile(nsDependentCString(exePath), false,
+                        xreDirectory);
+#endif
+
+  return rv;
+}
+
 int main(int argc, char* argv[])
 {
   PRTime start = _PR_Now();
-  char exePath[MAXPATHLEN];
 
 #ifdef XP_MACOSX
   TriggerQuirks();
 #endif
 
-  nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't calculate the application directory.\n");
-    return 255;
-  }
-
-  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
-  if (!lastSlash || (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
-    return 255;
-
-  strcpy(++lastSlash, XPCOM_DLL);
-
   int gotCounters;
 #if defined(XP_UNIX)
   struct rusage initialRUsage;
   gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
 #elif defined(XP_WIN)
   IO_COUNTERS ioCounters;
   gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
 #endif
 
-  // We do this because of data in bug 771745
-  XPCOMGlueEnablePreload();
+  nsIFile *xreDirectory;
 
-  rv = XPCOMGlueStartup(exePath);
+  nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
   if (NS_FAILED(rv)) {
-    Output("Couldn't load XPCOM.\n");
-    return 255;
-  }
-  // Reset exePath so that it is the directory name and not the xpcom dll name
-  *lastSlash = 0;
-
-  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't load XRE functions.\n");
     return 255;
   }
 
   XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
 #ifdef XRE_HAS_DLL_BLOCKLIST
   XRE_SetupDllBlocklist();
 #endif
@@ -271,14 +378,14 @@ int main(int argc, char* argv[])
                               int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
     }
 #endif
   }
 
   int result;
   {
     ScopedLogging log;
-    result = do_main(argc, argv);
+    result = do_main(argc, argv, xreDirectory);
   }
 
   XPCOMGlueShutdown();
   return result;
 }
--- a/configure.in
+++ b/configure.in
@@ -8684,21 +8684,16 @@ AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIRE
 AC_SUBST(FIREFOX_VERSION)
 AC_SUBST(MOZ_UA_OS_AGNOSTIC)
 if test -n "$MOZ_UA_OS_AGNOSTIC"; then
   AC_DEFINE(MOZ_UA_OS_AGNOSTIC)
 fi
 AC_DEFINE_UNQUOTED(MOZ_UA_BUILDID, "$MOZ_UA_BUILDID")
 AC_SUBST(MOZ_UA_BUILDID)
 
-# We can't use the static application.ini data when building against
-# a libxul SDK.
-if test -n "$LIBXUL_SDK"; then
-    MOZ_APP_STATIC_INI=
-fi
 AC_SUBST(MOZ_APP_STATIC_INI)
 
 AC_SUBST(MOZ_PKG_SPECIAL)
 
 AC_SUBST(MOZILLA_OFFICIAL)
 
 AC_DEFINE_UNQUOTED(MOZ_TELEMETRY_DISPLAY_REV, 2)
 AC_SUBST(MOZ_TELEMETRY_DISPLAY_REV)