bug 776783 - build win32 wrapper program r=cjones
authorJohn Ford <jhford@mozilla.com>
Fri, 28 Sep 2012 16:25:20 -0700
changeset 114878 c1eccb33893206027726f19883845d54431bbe20
parent 114877 189a1aaac3451b00d45445accd808b33add4d22f
child 114879 b6a9cb1be492dc87926b1001fa6a1fdf795fea7c
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs776783
milestone18.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 776783 - build win32 wrapper program r=cjones
b2g/gaia/Makefile.in
b2g/gaia/run-b2g.cpp
--- a/b2g/gaia/Makefile.in
+++ b/b2g/gaia/Makefile.in
@@ -6,37 +6,38 @@ DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 GAIA_PATH := gaia/profile
 
+PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
-# We don't have a wrapper script on Windows yet
-ifneq ($(OS_ARCH),WINNT)
-PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
+ifeq ($(OS_ARCH),WINNT)
+CPPSRCS = run-b2g.cpp
+DEFINES += \
+  -DB2G_NAME=L\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
+  -DGAIA_PATH=L\"$(subst /,\\\\,$(GAIA_PATH))\" \
+  $(NULL)
+GAIA_MAKE=make
+else # Non-windows machines use the same wrapper program
 CSRCS = run-b2g.c
-
 DEFINES += \
   -DB2G_NAME=\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
   -DGAIA_PATH=\"$(GAIA_PATH)\" \
   $(NULL)
+GAIA_MAKE=$(MAKE)
+endif
 
 # This is needed to avoid making run-b2g depend on mozglue
 WRAP_LDFLAGS :=
-endif
 
 GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
 
 include $(topsrcdir)/config/rules.mk
 
-
 libs::
-	# Below here is how Gaia gets built
-	# The Gaia build system freaks out when N > 1 for -jN
-	$(MAKE) -j1 -C $(GAIADIR) clean
-	$(MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
+	$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
+	$(GAIA_MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
 	(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
 
-
-
new file mode 100644
--- /dev/null
+++ b/b2g/gaia/run-b2g.cpp
@@ -0,0 +1,102 @@
+#include <Windows.h>
+#include <Shlwapi.h>
+#include <strsafe.h>
+
+// Linker options
+#pragma comment(lib, "User32.lib")
+#pragma comment(lib, "shlwapi.lib")
+#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
+
+#define NUM_MAX_PATH_BYTES sizeof(wchar_t) * MAX_PATH + 1
+#define PROFILE_ARG L" -profile "
+
+// Options that can be overridden at build time with -D
+#ifndef B2G_NAME
+#define B2G_NAME L"b2g.exe"
+#endif
+#ifndef GAIA_PATH
+#define GAIA_PATH L"gaia\\profile"
+#endif
+
+void error(wchar_t* msg){
+    MessageBoxW(NULL, msg, L"Error starting program", MB_OK | MB_ICONERROR);
+}
+
+/* This function takes a string which represents a windows path, orig.
+ * The file portion of the path is stripped off and replaced with the
+ * path component, file.  This function returns a string which represents
+ * a windows path with the modifications requested and needs to be freed
+ * explicitly by the calling function.
+ */
+wchar_t* make_path_with_leaf_file_name(wchar_t* orig, wchar_t* file){
+    wchar_t* buffer = (wchar_t*) malloc(NUM_MAX_PATH_BYTES);
+    if (!buffer) {
+        return NULL;
+    }
+    if (FAILED(StringCchCopyW(buffer, NUM_MAX_PATH_BYTES, orig))) {
+        error(L"Error copying string");
+        free(buffer);
+        buffer = NULL;
+    }
+    PathRemoveFileSpecW(buffer);
+    if (!PathAppendW(buffer, file)) {
+        error(L"Unable to append file to directory");
+        free(buffer);
+        buffer = NULL;
+    }
+    return buffer;
+}
+
+BOOL execute(wchar_t* binary_path, wchar_t* args, int cp_flags) {
+    STARTUPINFOW si;
+    PROCESS_INFORMATION pi;
+
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    ZeroMemory(&pi, sizeof(pi));
+    
+    if (!CreateProcessW(
+        binary_path,
+        args,
+        NULL,
+        NULL,
+        FALSE,
+        cp_flags,
+        NULL,
+        NULL,
+        &si,
+        &pi)){
+            error(L"Could not execute program");
+            return FALSE;
+    }
+
+    WaitForInputIdle(pi.hProcess, 0);
+    CloseHandle(pi.hProcess);
+    CloseHandle(pi.hThread);
+    return true;
+}
+
+int wmain(int argc, wchar_t *argv[], wchar_t *envp[]){
+    int cp_flags;
+    wchar_t* b2g_path = make_path_with_leaf_file_name(argv[0], B2G_NAME);
+    wchar_t* profile_path = make_path_with_leaf_file_name(argv[0], GAIA_PATH);
+	// 10 chars for the ' -profile ' portion of the argument
+    wchar_t* args = (wchar_t*) malloc(2 * NUM_MAX_PATH_BYTES + wcslen(PROFILE_ARG));
+    if (FAILED(StringCchPrintfW(args, NUM_MAX_PATH_BYTES, L"\"%ws\"%ws\"%ws\"", b2g_path, PROFILE_ARG, profile_path))) {
+        error(L"Could not create argument string");
+        ExitProcess(1);
+    }
+#ifdef SHOW_CONSOLE
+    cp_flags = 0;
+#else
+    cp_flags = DETACHED_PROCESS;
+#endif
+    if (!execute(b2g_path, args, cp_flags)) {
+        error(L"Failed to launch program");
+    }
+    free(profile_path);
+    free(b2g_path);
+    free(args);
+    profile_path = b2g_path = args = NULL;
+    
+}