You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.6 KiB
Makefile

# ===== Directories =====
SRC_DIR = src
BIN_DIR = bin
TEST_DIR = test
SPEC_DIR = spec
BENCHMARK_DIR = benchmark
EXAMPLES_DIR = examples
LIB_DIR = lib
DIST_DIR = dist
DIST_WEB_DIR = $(DIST_DIR)/web
DIST_NODE_DIR = $(DIST_DIR)/node
# ===== Files =====
PARSER_SRC_FILE = $(SRC_DIR)/parser.pegjs
PARSER_OUT_FILE = $(SRC_DIR)/parser.js
PEGJS_SRC_FILE = $(SRC_DIR)/peg.js
PEGJS_LIB_FILE = $(LIB_DIR)/peg.js
PACKAGE_JSON_SRC_FILE = package.json
PACKAGE_JSON_DIST_FILE = $(DIST_NODE_DIR)/package.json
PEGJS_DIST_FILE_DEV = $(DIST_WEB_DIR)/peg-$(PEGJS_VERSION).js
PEGJS_DIST_FILE_MIN = $(DIST_WEB_DIR)/peg-$(PEGJS_VERSION).min.js
CHANGELOG_FILE = CHANGELOG
LICENSE_FILE = LICENSE
README_FILE = README.md
VERSION_FILE = VERSION
# ===== Executables =====
JSHINT = jshint
UGLIFYJS = uglifyjs
JASMINE_NODE = jasmine-node
PEGJS = $(BIN_DIR)/pegjs
TEST_RUN = $(TEST_DIR)/run
BENCHMARK_RUN = $(BENCHMARK_DIR)/run
# ===== Variables =====
PEGJS_VERSION = `cat $(VERSION_FILE)`
# ===== Preprocessor =====
# A simple preprocessor that recognizes two directives:
#
# @VERSION -- insert PEG.js version
# @include "<file>" -- include <file> here
#
# This could have been implemented many ways. I chose Perl because everyone will
# have it.
PREPROCESS=perl -e ' \
use strict; \
use warnings; \
\
use File::Basename; \
\
open(my $$f, "$(VERSION_FILE)") or die "Can\x27t open $(VERSION_FILE): $$!"; \
my $$PEGJS_VERSION = <$$f>; \
close($$f); \
chomp($$PEGJS_VERSION); \
\
sub preprocess { \
my $$file = shift; \
my $$output = ""; \
\
open(my $$f, $$file) or die "Can\x27t open $$file: $$!"; \
while(<$$f>) { \
s/\@VERSION/$$PEGJS_VERSION/g; \
\
if (/^\s*\/\/\s*\@include\s*"([^"]*)"\s*$$/) { \
$$output .= preprocess(dirname($$file) . "/" . $$1); \
next; \
} \
\
$$output .= $$_; \
} \
close($$f); \
\
return $$output; \
} \
\
print preprocess($$ARGV[0]); \
'
# ===== Targets =====
# Generate the grammar parser
parser:
$(PEGJS) --export-var PEG.parser $(PARSER_SRC_FILE) $(PARSER_OUT_FILE)
# Build the PEG.js library
build:
mkdir -p $(LIB_DIR)
$(PREPROCESS) $(PEGJS_SRC_FILE) > $(PEGJS_LIB_FILE)
# Remove built PEG.js library (created by "build")
clean:
rm -rf $(LIB_DIR)
# Prepare dstribution files
dist: build
# Web
mkdir -p $(DIST_WEB_DIR)
cp $(PEGJS_LIB_FILE) $(PEGJS_DIST_FILE_DEV)
$(UGLIFYJS) --ascii -o $(PEGJS_DIST_FILE_MIN) $(PEGJS_LIB_FILE)
# Node.js
mkdir -p $(DIST_NODE_DIR)
cp -r \
$(LIB_DIR) \
$(BIN_DIR) \
$(EXAMPLES_DIR) \
$(CHANGELOG_FILE) \
$(LICENSE_FILE) \
$(README_FILE) \
$(VERSION_FILE) \
$(DIST_NODE_DIR)
$(PREPROCESS) $(PACKAGE_JSON_SRC_FILE) > $(PACKAGE_JSON_DIST_FILE)
# Remove distribution file (created by "dist")
distclean:
rm -rf $(DIST_DIR)
# Run the test suite
test: build
$(TEST_RUN)
# Run the spec suite
spec: build
$(JASMINE_NODE) --verbose $(SPEC_DIR)
# Run the benchmark suite
benchmark: build
$(BENCHMARK_RUN)
# Run JSHint on the source
hint: build
$(JSHINT) \
`find $(SRC_DIR) -name '*.js'` \
`find $(TEST_DIR) -name '*.js' -and -not -path '$(TEST_DIR)/vendor/*'` \
$(TEST_RUN) \
`find $(SPEC_DIR) -name '*.js' -and -not -path '$(SPEC_DIR)/vendor/*'` \
$(BENCHMARK_DIR)/*.js \
$(BENCHMARK_RUN) \
$(PEGJS)
.PHONY: test spec benchmark hint parser build clean dist distclean
.SILENT: test spec benchmark hint parser build clean dist distclean