Commit 20012318 authored by John Ford's avatar John Ford
Browse files

bug 776783 - build win32 wrapper program r=cjones

parent c263db03
Loading
Loading
Loading
Loading
+13 −12
Original line number Diff line number Diff line
@@ -11,32 +11,33 @@ include $(DEPTH)/config/autoconf.mk

GAIA_PATH := gaia/profile


# We don't have a wrapper script on Windows yet
ifneq ($(OS_ARCH),WINNT)
PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
CSRCS = run-b2g.c

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 -)

b2g/gaia/run-b2g.cpp

0 → 100644
+102 −0
Original line number Diff line number Diff line
#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;
    
}