jl777
9 years ago
6 changed files with 1074 additions and 0 deletions
@ -0,0 +1,19 @@ |
|||
#!/bin/sh |
|||
|
|||
OS=`uname -s` |
|||
|
|||
if [ $OS == Linux ] |
|||
then |
|||
google-chrome --allow-nacl-socket-api=127.0.0.1 |
|||
else |
|||
if [ $OS == Darwin ] |
|||
then |
|||
echo must be a mac |
|||
open -a "Google Chrome" --args --allow-nacl-socket-api=127.0.0.1 |
|||
else |
|||
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -allow-nacl-socket-api=127.0.0.1 |
|||
fi |
|||
fi |
|||
#open -a "Google Chrome" --args --allow-nacl-socket-api=127.0.0.1 --no-sandbox |
|||
#open -a "Google Chrome" --args --allow-nacl-socket-api=commondatastorage.googleapis.com --no-sandbox |
|||
#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -allow-nacl-socket-api=localhost |
@ -0,0 +1,5 @@ |
|||
SET KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe |
|||
FOR /F "skip=2 tokens=2,*" %%A IN ('reg query "%KEY_NAME%" /ve') DO set "CHROME_PATH=%%B" |
|||
REM echo %CHROME_PATH% |
|||
|
|||
"%CHROME_PATH%" -allow-nacl-socket-api=localhost |
@ -0,0 +1,547 @@ |
|||
# Copyrigh t (c) 2012 The Chromium Authors. All rights reserved.
|
|||
# Use of this source code is governed by a BSD-style license that can be
|
|||
# found in the LICENSE file.
|
|||
|
|||
#
|
|||
# GNU Make based build file. For details on GNU Make see:
|
|||
# http://www.gnu.org/software/make/manual/make.html
|
|||
#
|
|||
|
|||
#
|
|||
# Toolchain
|
|||
#
|
|||
# By default the VALID_TOOLCHAINS list contains pnacl, newlib and glibc. If
|
|||
# your project only builds in one or the other then this should be overridden
|
|||
# accordingly.
|
|||
#
|
|||
ifneq ($(ENABLE_BIONIC),) |
|||
ALL_TOOLCHAINS ?= pnacl newlib glibc clang-newlib bionic |
|||
else |
|||
ALL_TOOLCHAINS ?= pnacl newlib glibc clang-newlib |
|||
endif |
|||
|
|||
VALID_TOOLCHAINS ?= $(ALL_TOOLCHAINS) |
|||
TOOLCHAIN ?= $(word 1,$(VALID_TOOLCHAINS)) |
|||
|
|||
#
|
|||
# Top Make file, which we want to trigger a rebuild on if it changes
|
|||
#
|
|||
TOP_MAKE := $(word 1,$(MAKEFILE_LIST)) |
|||
|
|||
|
|||
#
|
|||
# Figure out which OS we are running on.
|
|||
#
|
|||
GETOS := python $(NACL_SDK_ROOT)/tools/getos.py |
|||
NACL_CONFIG := python $(NACL_SDK_ROOT)/tools/nacl_config.py |
|||
FIXDEPS := python $(NACL_SDK_ROOT)/tools/fix_deps.py -c |
|||
OSNAME := $(shell $(GETOS)) |
|||
|
|||
|
|||
#
|
|||
# TOOLCHAIN=all recursively calls this Makefile for all VALID_TOOLCHAINS.
|
|||
#
|
|||
ifeq ($(TOOLCHAIN),all) |
|||
|
|||
# Define the default target
|
|||
all: |
|||
|
|||
#
|
|||
# Generate a new MAKE command for each TOOLCHAIN.
|
|||
#
|
|||
# Note: We use targets for each toolchain (instead of an explicit recipe) so
|
|||
# each toolchain can be built in parallel.
|
|||
#
|
|||
# $1 = Toolchain Name
|
|||
#
|
|||
define TOOLCHAIN_RULE |
|||
TOOLCHAIN_TARGETS += $(1)_TARGET |
|||
.PHONY: $(1)_TARGET |
|||
$(1)_TARGET: |
|||
+$(MAKE) TOOLCHAIN=$(1) $(MAKECMDGOALS) |
|||
endef |
|||
|
|||
#
|
|||
# The target for all versions
|
|||
#
|
|||
USABLE_TOOLCHAINS=$(filter $(OSNAME) $(ALL_TOOLCHAINS),$(VALID_TOOLCHAINS)) |
|||
|
|||
ifeq ($(NO_HOST_BUILDS),1) |
|||
USABLE_TOOLCHAINS:=$(filter-out $(OSNAME),$(USABLE_TOOLCHAINS)) |
|||
endif |
|||
|
|||
# Define the toolchain targets for all usable toolchains via the macro.
|
|||
$(foreach tool,$(USABLE_TOOLCHAINS),$(eval $(call TOOLCHAIN_RULE,$(tool)))) |
|||
|
|||
.PHONY: all clean install |
|||
all: $(TOOLCHAIN_TARGETS) |
|||
clean: $(TOOLCHAIN_TARGETS) |
|||
install: $(TOOLCHAIN_TARGETS) |
|||
|
|||
else # TOOLCHAIN=all
|
|||
|
|||
#
|
|||
# Verify we selected a valid toolchain for this example
|
|||
#
|
|||
ifeq (,$(findstring $(TOOLCHAIN),$(VALID_TOOLCHAINS))) |
|||
|
|||
# Only fail to build if this is a top-level make. When building recursively, we
|
|||
# don't care if an example can't build with this toolchain.
|
|||
ifeq ($(MAKELEVEL),0) |
|||
$(warning Availbile choices are: $(VALID_TOOLCHAINS)) |
|||
$(error Can not use TOOLCHAIN=$(TOOLCHAIN) on this example.) |
|||
else |
|||
|
|||
# Dummy targets for recursive make with unsupported toolchain...
|
|||
.PHONY: all clean install |
|||
all: |
|||
clean: |
|||
install: |
|||
|
|||
endif |
|||
|
|||
else # TOOLCHAIN is valid...
|
|||
|
|||
#
|
|||
# Build Configuration
|
|||
#
|
|||
# The SDK provides two sets of libraries, Debug and Release. Debug libraries
|
|||
# are compiled without optimizations to make debugging easier. By default
|
|||
# this will build a Release configuration. When debugging via "make debug",
|
|||
# build the debug configuration by default instead.
|
|||
#
|
|||
ifneq (,$(findstring debug,$(MAKECMDGOALS))) |
|||
CONFIG ?= Debug |
|||
else |
|||
CONFIG ?= Release |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Verify we selected a valid configuration for this example.
|
|||
#
|
|||
VALID_CONFIGS ?= Debug Release |
|||
ifeq (,$(findstring $(CONFIG),$(VALID_CONFIGS))) |
|||
$(warning Availbile choices are: $(VALID_CONFIGS)) |
|||
$(error Can not use CONFIG=$(CONFIG) on this example.) |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Note for Windows:
|
|||
# The GCC and LLVM toolchains (include the version of Make.exe that comes
|
|||
# with the SDK) expect and are capable of dealing with the '/' seperator.
|
|||
# For this reason, the tools in the SDK, including Makefiles and build scripts
|
|||
# have a preference for POSIX style command-line arguments.
|
|||
#
|
|||
# Keep in mind however that the shell is responsible for command-line escaping,
|
|||
# globbing, and variable expansion, so those may change based on which shell
|
|||
# is used. For Cygwin shells this can include automatic and incorrect expansion
|
|||
# of response files (files starting with '@').
|
|||
#
|
|||
# Disable DOS PATH warning when using Cygwin based NaCl tools on Windows.
|
|||
#
|
|||
ifeq ($(OSNAME),win) |
|||
# Always use cmd.exe as the shell on Windows. Otherwise Make may try to |
|||
# search the path for sh.exe. If it is found in a path with a space, the |
|||
# command will fail. |
|||
SHELL := cmd.exe |
|||
CYGWIN ?= nodosfilewarning |
|||
export CYGWIN |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# If NACL_SDK_ROOT is not already set, then set it relative to this makefile.
|
|||
#
|
|||
THIS_MAKEFILE := $(CURDIR)/$(lastword $(MAKEFILE_LIST)) |
|||
NACL_SDK_ROOT ?= $(realpath $(dir $(THIS_MAKEFILE))/..) |
|||
|
|||
|
|||
#
|
|||
# Check that NACL_SDK_ROOT is set to a valid location.
|
|||
# We use the existence of tools/oshelpers.py to verify the validity of the SDK
|
|||
# root.
|
|||
#
|
|||
ifeq (,$(wildcard $(NACL_SDK_ROOT)/tools/oshelpers.py)) |
|||
$(error NACL_SDK_ROOT is set to an invalid location: $(NACL_SDK_ROOT)) |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# If this makefile is part of a valid nacl SDK, but NACL_SDK_ROOT is set
|
|||
# to a different location this is almost certainly a local configuration
|
|||
# error.
|
|||
#
|
|||
LOCAL_ROOT := $(realpath $(dir $(THIS_MAKEFILE))/..) |
|||
ifneq (,$(wildcard $(LOCAL_ROOT)/tools/oshelpers.py)) |
|||
ifneq ($(realpath $(NACL_SDK_ROOT)), $(realpath $(LOCAL_ROOT))) |
|||
$(error common.mk included from an SDK that does not match the current NACL_SDK_ROOT) |
|||
endif |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Alias for standard POSIX file system commands
|
|||
#
|
|||
OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py |
|||
WHICH := $(OSHELPERS) which |
|||
ifdef V |
|||
RM := $(OSHELPERS) rm |
|||
CP := $(OSHELPERS) cp |
|||
MKDIR := $(OSHELPERS) mkdir |
|||
MV := $(OSHELPERS) mv |
|||
else |
|||
RM := @$(OSHELPERS) rm |
|||
CP := @$(OSHELPERS) cp |
|||
MKDIR := @$(OSHELPERS) mkdir |
|||
MV := @$(OSHELPERS) mv |
|||
endif |
|||
|
|||
|
|||
|
|||
#
|
|||
# Compute path to requested NaCl Toolchain
|
|||
#
|
|||
TC_PATH := $(abspath $(NACL_SDK_ROOT)/../toolchain) |
|||
|
|||
|
|||
#
|
|||
# Check for required minimum SDK version.
|
|||
# A makefile can declare NACL_SDK_VERSION_MIN of the form "<major>.<position>",
|
|||
# where <major> is the major Chromium version number, and <position> is the
|
|||
# Chromium Cr-Commit-Position number. eg. "39.295386".
|
|||
#
|
|||
ifdef NACL_SDK_VERSION_MIN |
|||
VERSION_CHECK:=$(shell $(GETOS) --check-version=$(NACL_SDK_VERSION_MIN) 2>&1) |
|||
ifneq ($(VERSION_CHECK),) |
|||
$(error $(VERSION_CHECK)) |
|||
endif |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# The default target
|
|||
#
|
|||
# If no targets are specified on the command-line, the first target listed in
|
|||
# the makefile becomes the default target. By convention this is usually called
|
|||
# the 'all' target. Here we leave it blank to be first, but define it later
|
|||
#
|
|||
all: |
|||
.PHONY: all |
|||
|
|||
|
|||
#
|
|||
# The install target is used to install built libraries to thier final destination.
|
|||
# By default this is the NaCl SDK 'lib' folder.
|
|||
#
|
|||
install: |
|||
.PHONY: install |
|||
|
|||
ifdef SEL_LDR |
|||
STANDALONE = 1 |
|||
endif |
|||
|
|||
OUTBASE ?= . |
|||
ifdef STANDALONE |
|||
OUTDIR := $(OUTBASE)/$(TOOLCHAIN)/standalone_$(CONFIG) |
|||
else |
|||
OUTDIR := $(OUTBASE)/$(TOOLCHAIN)/$(CONFIG) |
|||
endif |
|||
STAMPDIR ?= $(OUTDIR) |
|||
LIBDIR ?= $(NACL_SDK_ROOT)/lib |
|||
|
|||
|
|||
#
|
|||
# Target to remove temporary files
|
|||
#
|
|||
.PHONY: clean |
|||
clean: |
|||
$(RM) -f $(TARGET).nmf |
|||
$(RM) -rf $(OUTDIR) |
|||
$(RM) -rf user-data-dir |
|||
mkdir pnacl; mkdir pnacl/Release |
|||
cp Release/* nacl_io.stamp pnacl/Release; |
|||
|
|||
|
|||
#
|
|||
# Rules for output directories.
|
|||
#
|
|||
# Output will be places in a directory name based on Toolchain and configuration
|
|||
# be default this will be "newlib/Debug". We use a python wrapped MKDIR to
|
|||
# proivde a cross platform solution. The use of '|' checks for existance instead
|
|||
# of timestamp, since the directory can update when files change.
|
|||
#
|
|||
%dir.stamp : |
|||
$(MKDIR) -p $(dir $@) |
|||
@echo Directory Stamp > $@ |
|||
|
|||
|
|||
#
|
|||
# Dependency Macro
|
|||
#
|
|||
# $1 = Name of stamp
|
|||
# $2 = Directory for the sub-make
|
|||
# $3 = Extra Settings
|
|||
#
|
|||
define DEPEND_RULE |
|||
ifndef IGNORE_DEPS |
|||
.PHONY: rebuild_$(1) |
|||
|
|||
rebuild_$(1) :| $(STAMPDIR)/dir.stamp |
|||
ifeq (,$(2)) |
|||
+$(MAKE) -C $(NACL_SDK_ROOT)/src/$(1) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3) |
|||
else |
|||
+$(MAKE) -C $(2) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3) |
|||
endif |
|||
cp pnacl/Release/*.pexe pnacl/Release/*.bc pnacl/Release/SuperNET_API.nmf Release |
|||
|
|||
all: rebuild_$(1) |
|||
$(STAMPDIR)/$(1).stamp: rebuild_$(1) |
|||
|
|||
else |
|||
|
|||
.PHONY: $(STAMPDIR)/$(1).stamp |
|||
$(STAMPDIR)/$(1).stamp: |
|||
@echo Ignore $(1) |
|||
endif |
|||
endef |
|||
|
|||
ifeq ($(TOOLCHAIN),win) |
|||
ifdef STANDALONE |
|||
HOST_EXT = .exe |
|||
else |
|||
HOST_EXT = .dll |
|||
endif |
|||
else |
|||
ifdef STANDALONE |
|||
HOST_EXT = |
|||
else |
|||
HOST_EXT = .so |
|||
endif |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Common Compile Options
|
|||
#
|
|||
# For example, -DNDEBUG is added to release builds by default
|
|||
# so that calls to assert(3) are not included in the build.
|
|||
#
|
|||
ifeq ($(CONFIG),Release) |
|||
POSIX_CFLAGS ?= -g -O2 -pthread -MMD -DNDEBUG |
|||
NACL_LDFLAGS ?= -O2 |
|||
PNACL_LDFLAGS ?= -O2 |
|||
else |
|||
POSIX_CFLAGS ?= -g -O0 -pthread -MMD -DNACL_SDK_DEBUG |
|||
endif |
|||
|
|||
NACL_CFLAGS ?= -Wno-long-long -Werror |
|||
NACL_CXXFLAGS ?= -Wno-long-long -Werror |
|||
NACL_LDFLAGS += -Wl,-as-needed -pthread |
|||
|
|||
#
|
|||
# Default Paths
|
|||
#
|
|||
INC_PATHS := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --include-dirs) $(EXTRA_INC_PATHS) |
|||
LIB_PATHS := $(NACL_SDK_ROOT)/lib $(EXTRA_LIB_PATHS) |
|||
|
|||
#
|
|||
# Define a LOG macro that allow a command to be run in quiet mode where
|
|||
# the command echoed is not the same as the actual command executed.
|
|||
# The primary use case for this is to avoid echoing the full compiler
|
|||
# and linker command in the default case. Defining V=1 will restore
|
|||
# the verbose behavior
|
|||
#
|
|||
# $1 = The name of the tool being run
|
|||
# $2 = The target file being built
|
|||
# $3 = The full command to run
|
|||
#
|
|||
ifdef V |
|||
define LOG |
|||
$(3) |
|||
endef |
|||
else |
|||
ifeq ($(OSNAME),win) |
|||
define LOG |
|||
@echo $(1) $(2) && $(3) |
|||
endef |
|||
else |
|||
define LOG |
|||
@echo " $(1) $(2)" && $(3) |
|||
endef |
|||
endif |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Convert a source path to a object file path.
|
|||
#
|
|||
# $1 = Source Name
|
|||
# $2 = Arch suffix
|
|||
#
|
|||
define SRC_TO_OBJ |
|||
$(OUTDIR)/$(basename $(subst ..,__,$(1)))$(2).o |
|||
endef |
|||
|
|||
|
|||
#
|
|||
# Convert a source path to a dependency file path.
|
|||
# We use the .deps extension for dependencies. These files are generated by
|
|||
# fix_deps.py based on the .d files which gcc generates. We don't reference
|
|||
# the .d files directly so that we can avoid the the case where the compile
|
|||
# failed but still generated a .d file (in that case the .d file would not
|
|||
# be processed by fix_deps.py)
|
|||
#
|
|||
# $1 = Source Name
|
|||
# $2 = Arch suffix
|
|||
#
|
|||
define SRC_TO_DEP |
|||
$(patsubst %.o,%.deps,$(call SRC_TO_OBJ,$(1),$(2))) |
|||
endef |
|||
|
|||
#
|
|||
# The gcc-generated deps files end in .d
|
|||
#
|
|||
define SRC_TO_DEP_PRE_FIXUP |
|||
$(patsubst %.o,%.d,$(call SRC_TO_OBJ,$(1),$(2))) |
|||
endef |
|||
|
|||
|
|||
#
|
|||
# If the requested toolchain is a NaCl or PNaCl toolchain, the use the
|
|||
# macros and targets defined in nacl.mk, otherwise use the host sepecific
|
|||
# macros and targets.
|
|||
#
|
|||
ifneq (,$(findstring $(TOOLCHAIN),linux mac)) |
|||
include $(NACL_SDK_ROOT)/tools/host_gcc.mk |
|||
endif |
|||
|
|||
ifneq (,$(findstring $(TOOLCHAIN),win)) |
|||
include $(NACL_SDK_ROOT)/tools/host_vc.mk |
|||
endif |
|||
|
|||
ifneq (,$(findstring $(TOOLCHAIN),glibc newlib bionic clang-newlib)) |
|||
include $(NACL_SDK_ROOT)/tools/nacl_gcc.mk |
|||
endif |
|||
|
|||
ifneq (,$(findstring $(TOOLCHAIN),pnacl)) |
|||
include $(NACL_SDK_ROOT)/tools/nacl_llvm.mk |
|||
endif |
|||
|
|||
#
|
|||
# File to redirect to to in order to hide output.
|
|||
#
|
|||
ifeq ($(OSNAME),win) |
|||
DEV_NULL = nul |
|||
else |
|||
DEV_NULL = /dev/null |
|||
endif |
|||
|
|||
|
|||
#
|
|||
# Variables for running examples with Chrome.
|
|||
#
|
|||
RUN_PY := python $(NACL_SDK_ROOT)/tools/run.py |
|||
#HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py
|
|||
HTTPD_PY := python tools/httpd.py |
|||
|
|||
# Add this to launch Chrome with additional environment variables defined.
|
|||
# Each element should be specified as KEY=VALUE, with whitespace separating
|
|||
# key-value pairs. e.g.
|
|||
# CHROME_ENV=FOO=1 BAR=2 BAZ=3
|
|||
CHROME_ENV ?= |
|||
|
|||
# Additional arguments to pass to Chrome.
|
|||
CHROME_ARGS += --enable-nacl --enable-pnacl --no-first-run |
|||
CHROME_ARGS += --user-data-dir=$(CURDIR)/user-data-dir |
|||
|
|||
|
|||
# Paths to Debug and Release versions of the Host Pepper plugins
|
|||
PPAPI_DEBUG = $(abspath $(OSNAME)/Debug/$(TARGET)$(HOST_EXT));application/x-ppapi-debug |
|||
PPAPI_RELEASE = $(abspath $(OSNAME)/Release/$(TARGET)$(HOST_EXT));application/x-ppapi-release |
|||
|
|||
|
|||
SYSARCH := $(shell $(GETOS) --nacl-arch) |
|||
SEL_LDR_PATH := python $(NACL_SDK_ROOT)/tools/sel_ldr.py |
|||
|
|||
#
|
|||
# Common Compile Options
|
|||
#
|
|||
ifeq ($(CONFIG),Debug) |
|||
SEL_LDR_ARGS += --debug-libs |
|||
endif |
|||
|
|||
ifndef STANDALONE |
|||
#
|
|||
# Assign a sensible default to CHROME_PATH.
|
|||
#
|
|||
CHROME_PATH ?= $(shell $(GETOS) --chrome 2> $(DEV_NULL)) |
|||
|
|||
#
|
|||
# Verify we can find the Chrome executable if we need to launch it.
|
|||
#
|
|||
|
|||
NULL := |
|||
SPACE := $(NULL) # one space after NULL is required |
|||
CHROME_PATH_ESCAPE := $(subst $(SPACE),\ ,$(CHROME_PATH)) |
|||
|
|||
ifeq ($(OSNAME),win) |
|||
SANDBOX_ARGS := --no-sandbox |
|||
endif |
|||
|
|||
GDB_PATH := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --tool=gdb) |
|||
|
|||
.PHONY: check_for_chrome |
|||
check_for_chrome: |
|||
ifeq (,$(wildcard $(CHROME_PATH_ESCAPE))) |
|||
$(warning No valid Chrome found at CHROME_PATH=$(CHROME_PATH)) |
|||
$(error Set CHROME_PATH via an environment variable, or command-line.) |
|||
else |
|||
$(warning Using chrome at: $(CHROME_PATH)) |
|||
endif |
|||
PAGE ?= index.html |
|||
PAGE_TC_CONFIG ?= "$(PAGE)?tc=$(TOOLCHAIN)&config=$(CONFIG)" |
|||
|
|||
.PHONY: run |
|||
run: check_for_chrome all $(PAGE) |
|||
$(RUN_PY) -C $(CURDIR) -P $(PAGE_TC_CONFIG) \
|
|||
$(addprefix -E ,$(CHROME_ENV)) -- "$(CHROME_PATH)" \
|
|||
$(CHROME_ARGS) \
|
|||
--register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)" |
|||
|
|||
.PHONY: run_package |
|||
run_package: check_for_chrome all |
|||
@echo "$(TOOLCHAIN) $(CONFIG)" > $(CURDIR)/run_package_config |
|||
"$(CHROME_PATH)" --load-and-launch-app=$(CURDIR) $(CHROME_ARGS) |
|||
|
|||
GDB_ARGS += -D $(GDB_PATH) |
|||
# PNaCl's nexe is acquired with "remote get nexe <path>" instead of the NMF.
|
|||
ifeq (,$(findstring $(TOOLCHAIN),pnacl)) |
|||
GDB_ARGS += -D --eval-command="nacl-manifest $(abspath $(OUTDIR))/$(TARGET).nmf" |
|||
GDB_ARGS += -D $(GDB_DEBUG_TARGET) |
|||
endif |
|||
|
|||
.PHONY: debug |
|||
debug: check_for_chrome all $(PAGE) |
|||
$(RUN_PY) $(GDB_ARGS) \
|
|||
-C $(CURDIR) -P $(PAGE_TC_CONFIG) \
|
|||
$(addprefix -E ,$(CHROME_ENV)) -- "$(CHROME_PATH)" \
|
|||
$(CHROME_ARGS) $(SANDBOX_ARGS) --enable-nacl-debug \
|
|||
--register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)" |
|||
|
|||
.PHONY: serve |
|||
serve: all |
|||
echo run tools/httpd.py |
|||
endif |
|||
|
|||
# uppercase aliases (for backward compatibility)
|
|||
.PHONY: CHECK_FOR_CHROME DEBUG LAUNCH RUN |
|||
CHECK_FOR_CHROME: check_for_chrome |
|||
DEBUG: debug |
|||
LAUNCH: run |
|||
RUN: run |
|||
|
|||
endif # TOOLCHAIN is valid...
|
|||
|
|||
endif # TOOLCHAIN=all
|
@ -0,0 +1,275 @@ |
|||
#!/usr/bin/env python |
|||
# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|||
# Use of this source code is governed by a BSD-style license that can be |
|||
# found in the LICENSE file. |
|||
|
|||
"""Determine OS and various other system properties. |
|||
|
|||
Determine the name of the platform used and other system properties such as |
|||
the location of Chrome. This is used, for example, to determine the correct |
|||
Toolchain to invoke. |
|||
""" |
|||
|
|||
import argparse |
|||
import os |
|||
import re |
|||
import subprocess |
|||
import sys |
|||
|
|||
import oshelpers |
|||
|
|||
|
|||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
|||
CHROME_DEFAULT_PATH = { |
|||
'win': r'c:\Program Files (x86)\Google\Chrome\Application\chrome.exe', |
|||
'mac': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', |
|||
'linux': '/usr/bin/google-chrome', |
|||
} |
|||
|
|||
|
|||
if sys.version_info < (2, 7, 0): |
|||
sys.stderr.write("python 2.7 or later is required run this script\n") |
|||
sys.exit(1) |
|||
|
|||
|
|||
class Error(Exception): |
|||
pass |
|||
|
|||
|
|||
def GetSDKPath(): |
|||
return os.getenv('NACL_SDK_ROOT', os.path.dirname(SCRIPT_DIR)) |
|||
|
|||
|
|||
def GetPlatform(): |
|||
if sys.platform.startswith('cygwin') or sys.platform.startswith('win'): |
|||
return 'win' |
|||
elif sys.platform.startswith('darwin'): |
|||
return 'mac' |
|||
elif sys.platform.startswith('linux'): |
|||
return 'linux' |
|||
else: |
|||
raise Error("Unknown platform: %s" % sys.platform) |
|||
|
|||
|
|||
def UseWin64(): |
|||
arch32 = os.environ.get('PROCESSOR_ARCHITECTURE') |
|||
arch64 = os.environ.get('PROCESSOR_ARCHITEW6432') |
|||
|
|||
if arch32 == 'AMD64' or arch64 == 'AMD64': |
|||
return True |
|||
return False |
|||
|
|||
|
|||
def GetSDKVersion(): |
|||
root = GetSDKPath() |
|||
readme = os.path.join(root, "README") |
|||
if not os.path.exists(readme): |
|||
raise Error("README not found in SDK root: %s" % root) |
|||
|
|||
version = None |
|||
revision = None |
|||
commit_position = None |
|||
for line in open(readme): |
|||
if ':' in line: |
|||
name, value = line.split(':', 1) |
|||
if name == "Version": |
|||
version = value.strip() |
|||
if name == "Chrome Revision": |
|||
revision = value.strip() |
|||
if name == "Chrome Commit Position": |
|||
commit_position = value.strip() |
|||
|
|||
if revision is None or version is None or commit_position is None: |
|||
raise Error("error parsing SDK README: %s" % readme) |
|||
|
|||
try: |
|||
version = int(version) |
|||
revision = int(revision) |
|||
except ValueError: |
|||
raise Error("error parsing SDK README: %s" % readme) |
|||
|
|||
return (version, revision, commit_position) |
|||
|
|||
|
|||
def GetSystemArch(platform): |
|||
if platform == 'win': |
|||
if UseWin64(): |
|||
return 'x86_64' |
|||
return 'x86_32' |
|||
|
|||
if platform in ['mac', 'linux']: |
|||
try: |
|||
pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE) |
|||
arch = pobj.communicate()[0] |
|||
arch = arch.split()[0] |
|||
if arch.startswith('arm'): |
|||
arch = 'arm' |
|||
except Exception: |
|||
arch = None |
|||
return arch |
|||
|
|||
|
|||
def GetChromePath(platform): |
|||
# If CHROME_PATH is defined and exists, use that. |
|||
chrome_path = os.environ.get('CHROME_PATH') |
|||
if chrome_path: |
|||
if not os.path.exists(chrome_path): |
|||
raise Error('Invalid CHROME_PATH: %s' % chrome_path) |
|||
return os.path.realpath(chrome_path) |
|||
|
|||
# Otherwise look in the PATH environment variable. |
|||
basename = os.path.basename(CHROME_DEFAULT_PATH[platform]) |
|||
chrome_path = oshelpers.FindExeInPath(basename) |
|||
if chrome_path: |
|||
return os.path.realpath(chrome_path) |
|||
|
|||
# Finally, try the default paths to Chrome. |
|||
chrome_path = CHROME_DEFAULT_PATH[platform] |
|||
if os.path.exists(chrome_path): |
|||
return os.path.realpath(chrome_path) |
|||
|
|||
raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % ( |
|||
basename, chrome_path)) |
|||
|
|||
|
|||
def GetNaClArch(platform): |
|||
if platform == 'win': |
|||
# On windows the nacl arch always matches to system arch |
|||
return GetSystemArch(platform) |
|||
elif platform == 'mac': |
|||
# On Mac the nacl arch is currently always 32-bit. |
|||
return 'x86_32' |
|||
|
|||
# On linux the nacl arch matches to chrome arch, so we inspect the chrome |
|||
# binary using objdump |
|||
chrome_path = GetChromePath(platform) |
|||
|
|||
# If CHROME_PATH is set to point to google-chrome or google-chrome |
|||
# was found in the PATH and we are running on UNIX then google-chrome |
|||
# is a bash script that points to 'chrome' in the same folder. |
|||
# |
|||
# When running beta or dev branch, the name is google-chrome-{beta,dev}. |
|||
if os.path.basename(chrome_path).startswith('google-chrome'): |
|||
chrome_path = os.path.join(os.path.dirname(chrome_path), 'chrome') |
|||
|
|||
if not os.path.exists(chrome_path): |
|||
raise Error("File %s does not exist." % chrome_path) |
|||
|
|||
if not os.access(chrome_path, os.X_OK): |
|||
raise Error("File %s is not executable" % chrome_path) |
|||
|
|||
try: |
|||
pobj = subprocess.Popen(['objdump', '-f', chrome_path], |
|||
stdout=subprocess.PIPE, |
|||
stderr=subprocess.PIPE) |
|||
output, stderr = pobj.communicate() |
|||
# error out here if objdump failed |
|||
if pobj.returncode: |
|||
raise Error(output + stderr.strip()) |
|||
except OSError as e: |
|||
# This will happen if objdump is not installed |
|||
raise Error("Error running objdump: %s" % e) |
|||
|
|||
pattern = r'(file format) ([a-zA-Z0-9_\-]+)' |
|||
match = re.search(pattern, output) |
|||
if not match: |
|||
raise Error("Error running objdump on: %s" % chrome_path) |
|||
|
|||
arch = match.group(2) |
|||
if 'arm' in arch: |
|||
return 'arm' |
|||
if '64' in arch: |
|||
return 'x86_64' |
|||
return 'x86_32' |
|||
|
|||
|
|||
def ParseVersion(version): |
|||
"""Parses a version number of the form '<major>.<position>'. |
|||
|
|||
<position> is the Cr-Commit-Position number. |
|||
""" |
|||
if '.' in version: |
|||
version = version.split('.') |
|||
else: |
|||
version = (version, '0') |
|||
|
|||
try: |
|||
return tuple(int(x) for x in version) |
|||
except ValueError: |
|||
raise Error('error parsing SDK version: %s' % version) |
|||
|
|||
|
|||
def CheckVersion(required_version): |
|||
"""Determines whether the current SDK version meets the required version. |
|||
|
|||
Args: |
|||
required_version: (major, position) pair, where position is the |
|||
Cr-Commit-Position number. |
|||
|
|||
Raises: |
|||
Error: The SDK version is older than required_version. |
|||
""" |
|||
version = GetSDKVersion()[:2] |
|||
if version < required_version: |
|||
raise Error("SDK version too old (current: %d.%d, required: %d.%d)" |
|||
% (version[0], version[1], required_version[0], required_version[1])) |
|||
|
|||
|
|||
def main(args): |
|||
parser = argparse.ArgumentParser() |
|||
parser.add_argument('--arch', action='store_true', |
|||
help='Print architecture of current machine (x86_32, x86_64 or arm).') |
|||
parser.add_argument('--chrome', action='store_true', |
|||
help='Print the path chrome (by first looking in $CHROME_PATH and ' |
|||
'then $PATH).') |
|||
parser.add_argument('--nacl-arch', action='store_true', |
|||
help='Print architecture used by NaCl on the current machine.') |
|||
parser.add_argument('--sdk-version', action='store_true', |
|||
help='Print major version of the NaCl SDK.') |
|||
parser.add_argument('--sdk-revision', action='store_true', |
|||
help='Print revision number of the NaCl SDK.') |
|||
parser.add_argument('--sdk-commit-position', action='store_true', |
|||
help='Print commit position of the NaCl SDK.') |
|||
parser.add_argument('--check-version', |
|||
metavar='MAJOR.POSITION', |
|||
help='Check that the SDK version is at least as great as the ' |
|||
'version passed in. MAJOR is the major version number and POSITION ' |
|||
'is the Cr-Commit-Position number.') |
|||
|
|||
if len(args) > 1: |
|||
parser.error('Only one option can be specified at a time.') |
|||
|
|||
options = parser.parse_args(args) |
|||
|
|||
platform = GetPlatform() |
|||
|
|||
if options.arch: |
|||
out = GetSystemArch(platform) |
|||
elif options.nacl_arch: |
|||
out = GetNaClArch(platform) |
|||
elif options.chrome: |
|||
out = GetChromePath(platform) |
|||
elif options.sdk_version: |
|||
out = GetSDKVersion()[0] |
|||
elif options.sdk_revision: |
|||
out = GetSDKVersion()[1] |
|||
elif options.sdk_commit_position: |
|||
out = GetSDKVersion()[2] |
|||
elif options.check_version: |
|||
required_version = ParseVersion(options.check_version) |
|||
CheckVersion(required_version) |
|||
out = None |
|||
else: |
|||
out = platform |
|||
|
|||
if out: |
|||
print out |
|||
return 0 |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
try: |
|||
sys.exit(main(sys.argv[1:])) |
|||
except Error as e: |
|||
sys.stderr.write(str(e) + '\n') |
|||
sys.exit(1) |
@ -0,0 +1,225 @@ |
|||
#!/usr/bin/env python |
|||
# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|||
# Use of this source code is governed by a BSD-style license that can be |
|||
# found in the LICENSE file. |
|||
|
|||
import argparse |
|||
import logging |
|||
import multiprocessing |
|||
import os |
|||
import socket |
|||
import sys |
|||
import time |
|||
|
|||
if sys.version_info < (2, 7, 0): |
|||
sys.stderr.write("python 2.7 or later is required run this script\n") |
|||
sys.exit(1) |
|||
|
|||
try: |
|||
# Python 3+ |
|||
from http.server import HTTPServer, SimpleHTTPRequestHandler |
|||
from urllib.parse import urlparse, parse_qs, urlsplit |
|||
except ImportError: |
|||
# Python 2.7 |
|||
from urlparse import urlparse, urlsplit, parse_qs |
|||
from BaseHTTPServer import HTTPServer |
|||
from SimpleHTTPServer import SimpleHTTPRequestHandler |
|||
|
|||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
|||
NACL_SDK_ROOT = os.path.dirname(SCRIPT_DIR) |
|||
|
|||
# We only run from the examples directory so that not too much is exposed |
|||
# via this HTTP server. Everything in the directory is served, so there should |
|||
# never be anything potentially sensitive in the serving directory, especially |
|||
# if the machine might be a multi-user machine and not all users are trusted. |
|||
# We only serve via the loopback interface. |
|||
def SanityCheckDirectory(dirname): |
|||
abs_serve_dir = os.path.abspath(dirname) |
|||
|
|||
# Verify we don't serve anywhere above NACL_SDK_ROOT. |
|||
if abs_serve_dir[:len(NACL_SDK_ROOT)] == NACL_SDK_ROOT: |
|||
return |
|||
logging.error('For security, httpd.py should only be run from within the') |
|||
logging.error('example directory tree.') |
|||
logging.error('Attempting to serve from %s.' % abs_serve_dir) |
|||
logging.error('Run with --no-dir-check to bypass this check.') |
|||
sys.exit(1) |
|||
|
|||
|
|||
class SuperNetHTTPServer(HTTPServer): |
|||
def __init__(self, *args, **kwargs): |
|||
HTTPServer.__init__(self, *args) |
|||
self.running = True |
|||
self.result = 0 |
|||
|
|||
def Shutdown(self, result=0): |
|||
self.running = False |
|||
self.result = result |
|||
|
|||
|
|||
class SuperNetHTTPRequestHandler(SimpleHTTPRequestHandler): |
|||
def _SendNothingAndDie(self, result=0): |
|||
self.send_response(200, 'OK') |
|||
self.send_header('Content-type', 'text/html') |
|||
self.send_header('Content-length', '0') |
|||
self.end_headers() |
|||
self.server.Shutdown(result) |
|||
|
|||
def do_GET(self): |
|||
# Browsing to ?quit=1 will kill the server cleanly. |
|||
_, _, _, query, _ = urlsplit(self.path) |
|||
if query: |
|||
params = parse_qs(query) |
|||
if '1' in params.get('quit', []): |
|||
self._SendNothingAndDie() |
|||
return |
|||
|
|||
return SimpleHTTPRequestHandler.do_GET(self) |
|||
|
|||
|
|||
class LocalHTTPServer(object): |
|||
"""Class to start a local HTTP server as a child process.""" |
|||
|
|||
def __init__(self, dirname, port): |
|||
parent_conn, child_conn = multiprocessing.Pipe() |
|||
self.process = multiprocessing.Process( |
|||
target=_HTTPServerProcess, |
|||
args=(child_conn, dirname, port, {})) |
|||
self.process.start() |
|||
if parent_conn.poll(10): # wait 10 seconds |
|||
self.port = parent_conn.recv() |
|||
else: |
|||
raise Exception('Unable to launch HTTP server.') |
|||
|
|||
self.conn = parent_conn |
|||
|
|||
def ServeForever(self): |
|||
"""Serve until the child HTTP process tells us to stop. |
|||
|
|||
Returns: |
|||
The result from the child (as an errorcode), or 0 if the server was |
|||
killed not by the child (by KeyboardInterrupt for example). |
|||
""" |
|||
child_result = 0 |
|||
try: |
|||
# Block on this pipe, waiting for a response from the child process. |
|||
child_result = self.conn.recv() |
|||
except KeyboardInterrupt: |
|||
pass |
|||
finally: |
|||
self.Shutdown() |
|||
return child_result |
|||
|
|||
def ServeUntilSubprocessDies(self, process): |
|||
"""Serve until the child HTTP process tells us to stop or |subprocess| dies. |
|||
|
|||
Returns: |
|||
The result from the child (as an errorcode), or 0 if |subprocess| died, |
|||
or the server was killed some other way (by KeyboardInterrupt for |
|||
example). |
|||
""" |
|||
child_result = 0 |
|||
try: |
|||
while True: |
|||
if process.poll() is not None: |
|||
child_result = 0 |
|||
break |
|||
if self.conn.poll(): |
|||
child_result = self.conn.recv() |
|||
break |
|||
time.sleep(0) |
|||
except KeyboardInterrupt: |
|||
pass |
|||
finally: |
|||
self.Shutdown() |
|||
return child_result |
|||
|
|||
def Shutdown(self): |
|||
"""Send a message to the child HTTP server process and wait for it to |
|||
finish.""" |
|||
print("Shutting down server") |
|||
self.conn.send(False) |
|||
self.process.join() |
|||
|
|||
def GetURL(self, rel_url): |
|||
"""Get the full url for a file on the local HTTP server. |
|||
|
|||
Args: |
|||
rel_url: A URL fragment to convert to a full URL. For example, |
|||
GetURL('foobar.baz') -> 'http://127.0.0.1:1234/foobar.baz' |
|||
""" |
|||
return 'http://127.0.0.1:%d/%s' % (self.port, rel_url) |
|||
|
|||
|
|||
def _HTTPServerProcess(conn, dirname, port, server_kwargs): |
|||
"""Run a local httpserver with the given port or an ephemeral port. |
|||
|
|||
This function assumes it is run as a child process using multiprocessing. |
|||
|
|||
Args: |
|||
conn: A connection to the parent process. The child process sends |
|||
the local port, and waits for a message from the parent to |
|||
stop serving. It also sends a "result" back to the parent -- this can |
|||
be used to allow a client-side test to notify the server of results. |
|||
dirname: The directory to serve. All files are accessible through |
|||
http://127.0.0.1:<port>/path/to/filename. |
|||
port: The port to serve on. If 0, an ephemeral port will be chosen. |
|||
server_kwargs: A dict that will be passed as kwargs to the server. |
|||
""" |
|||
try: |
|||
os.chdir(dirname) |
|||
httpd = SuperNetHTTPServer(('', port), SuperNetHTTPRequestHandler, **server_kwargs) |
|||
except socket.error as e: |
|||
sys.stderr.write('Error creating SuperNetHTTPServer: %s\n' % e) |
|||
sys.exit(1) |
|||
|
|||
try: |
|||
conn.send(httpd.server_address[1]) # the chosen port number |
|||
httpd.timeout = 0.5 # seconds |
|||
while httpd.running: |
|||
# Flush output for MSVS Add-In. |
|||
sys.stdout.flush() |
|||
sys.stderr.flush() |
|||
httpd.handle_request() |
|||
if conn.poll(): |
|||
httpd.running = conn.recv() |
|||
except KeyboardInterrupt: |
|||
pass |
|||
finally: |
|||
conn.send(httpd.result) |
|||
conn.close() |
|||
|
|||
|
|||
def main(args): |
|||
parser = argparse.ArgumentParser() |
|||
parser.add_argument('-C', '--serve-dir', |
|||
help='Serve files out of this directory.', |
|||
default=os.path.abspath('.')) |
|||
parser.add_argument('-p', '--port', |
|||
help='Run server on this port.', default=7777) |
|||
parser.add_argument('--no-dir-check', '--no_dir_check', |
|||
help='No check to ensure serving from safe directory.', |
|||
dest='do_safe_check', action='store_false', default=True) |
|||
|
|||
# To enable bash completion for this command first install optcomplete |
|||
# and then add this line to your .bashrc: |
|||
# complete -F _optcomplete httpd.py |
|||
try: |
|||
import optcomplete |
|||
optcomplete.autocomplete(parser) |
|||
except ImportError: |
|||
pass |
|||
|
|||
options = parser.parse_args(args) |
|||
if options.do_safe_check: |
|||
SanityCheckDirectory(options.serve_dir) |
|||
|
|||
server = LocalHTTPServer(options.serve_dir, int(options.port)) |
|||
|
|||
# Serve until the client tells us to stop. When it does, it will give us an |
|||
# errorcode. |
|||
print(('Serving {0} on {1}...'.format(options.serve_dir, server.GetURL('')))) |
|||
return server.ServeForever() |
|||
|
|||
if __name__ == '__main__': |
|||
sys.exit(main(sys.argv[1:])) |
@ -0,0 +1,3 @@ |
|||
@echo OFF |
|||
call chrome.localhost.bat |
|||
python tools\httpd.py -p 7777 |
Loading…
Reference in new issue