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