@@ -32,18 +32,31 @@ ifeq ($(PYTHON),)
3232endif
3333PYTHON_BIN := $(shell which $(PYTHON ) )
3434PYTHON_VER := $(word 2,$(shell $(PYTHON ) -V 2>&1) )
35+ GO_REQ_MAJ := 1
36+ GO_REQ_MIN := 6
37+ GO_MAJ_MIN := $(subst go,, $(word 3,$(shell go version 2>&1) ) )
38+ GO_MAJ := $(word 1,$(subst ., ,$(GO_MAJ_MIN ) ) )
39+ GO_MIN := $(word 2,$(subst ., ,$(GO_MAJ_MIN ) ) )
3540
3641ifeq ($(filter 2.7.% ,$(PYTHON_VER ) ) ,)
3742 $(error unsupported Python version $(PYTHON_VER ) , Grumpy only supports 2.7.x. To use a different python binary such as python2, run : 'make PYTHON=python2 ...')
3843endif
3944
45+ ifneq ($(shell test $(GO_MAJ ) -ge $(GO_REQ_MAJ ) -a $(GO_MIN ) -ge $(GO_REQ_MIN ) && echo ok) ,ok)
46+ $(error unsupported Go version $(GO_VER), Grumpy requires at least $(GO_REQ_MAJ).$(GO_REQ_MIN). Please update Go)
47+ endif
48+
4049PY_DIR := build/lib/python2.7/site-packages
4150PY_INSTALL_DIR := $(shell $(PYTHON ) -c "from distutils.sysconfig import get_python_lib; print(get_python_lib() )")
4251
4352export GOPATH := $(ROOT_DIR ) /build
4453export PYTHONPATH := $(ROOT_DIR ) /$(PY_DIR )
4554export PATH := $(ROOT_DIR ) /build/bin:$(PATH )
4655
56+ GOPATH_PY_ROOT := $(GOPATH ) /src/__python__
57+
58+ PYTHONPARSER_SRCS := $(patsubst third_party/% ,$(PY_DIR ) /grumpy/% ,$(wildcard third_party/pythonparser/* .py) )
59+
4760COMPILER_BIN := build/bin/grumpc
4861COMPILER_SRCS := $(addprefix $(PY_DIR ) /grumpy/compiler/,$(notdir $(shell find compiler -name '* .py' -not -name '* _test.py') ) ) $(PY_DIR ) /grumpy/__init__.py
4962COMPILER_TESTS := $(patsubst % .py,grumpy/% ,$(filter-out compiler/expr_visitor_test.py compiler/stmt_test.py,$(wildcard compiler/* _test.py) ) )
@@ -53,7 +66,7 @@ COMPILER_PASS_FILES := $(patsubst %,$(PY_DIR)/%.pass,$(COMPILER_TESTS))
5366COMPILER_EXPR_VISITOR_PASS_FILES := $(patsubst % ,$(PY_DIR ) /grumpy/compiler/expr_visitor_test.% of32.pass,$(shell seq 32) )
5467COMPILER_STMT_PASS_FILES := $(patsubst % ,$(PY_DIR ) /grumpy/compiler/stmt_test.% of16.pass,$(shell seq 16) )
5568COMPILER_D_FILES := $(patsubst % ,$(PY_DIR ) /% .d,$(COMPILER_TESTS ) )
56- COMPILER := $(COMPILER_BIN ) $(COMPILER_SRCS )
69+ COMPILER := $(COMPILER_BIN ) $(COMPILER_SRCS ) $( PYTHONPARSER_SRCS )
5770
5871RUNNER_BIN := build/bin/grumprun
5972RUNTIME_SRCS := $(addprefix build/src/grumpy/,$(notdir $(wildcard runtime/* .go) ) )
@@ -62,33 +75,39 @@ RUNTIME_PASS_FILE := build/runtime.pass
6275RUNTIME_COVER_FILE := $(PKG_DIR ) /grumpy.cover
6376RUNNER = $(RUNNER_BIN ) $(COMPILER ) $(RUNTIME ) $(STDLIB )
6477
65- GRUMPY_STDLIB_SRCS := $(shell find lib -name '* .py')
66- GRUMPY_STDLIB_PACKAGES := $(foreach x,$(GRUMPY_STDLIB_SRCS ) ,$(patsubst lib/% .py,% ,$(patsubst lib/% /__init__.py,% ,$(x ) ) ) )
67- THIRD_PARTY_STDLIB_SRCS := $(shell find third_party -name '* .py')
68- THIRD_PARTY_STDLIB_PACKAGES := $(foreach x,$(THIRD_PARTY_STDLIB_SRCS ) ,$(patsubst third_party/stdlib/% .py,% ,$(patsubst third_party/pypy/% .py,% ,$(patsubst third_party/pypy/% /__init__.py,% ,$(patsubst third_party/stdlib/% /__init__.py,% ,$(x ) ) ) ) ) )
69- STDLIB_SRCS := $(GRUMPY_STDLIB_SRCS ) $(THIRD_PARTY_STDLIB_SRCS )
70- STDLIB_PACKAGES := $(GRUMPY_STDLIB_PACKAGES ) $(THIRD_PARTY_STDLIB_PACKAGES )
71- STDLIB := $(patsubst % ,$(PKG_DIR ) /grumpy/lib/% .a,$(STDLIB_PACKAGES ) )
72- LIB_TEST_SRCS := \
73- lib/itertools_test.py \
74- lib/math_test.py \
75- lib/os/path_test.py \
76- lib/os_test.py \
77- lib/random_test.py \
78- lib/sys_test.py \
79- lib/tempfile_test.py \
80- lib/threading_test.py \
81- lib/time_test.py \
82- lib/types_test.py \
83- lib/weetest_test.py
84- LIB_PASS_FILES := $(patsubst % .py,$(PKG_DIR ) /grumpy/% .pass,$(LIB_TEST_SRCS ) )
85- CPYTHON_TEST_SRCS := \
86- third_party/stdlib/re_tests.py \
87- third_party/stdlib/test/seq_tests.py \
88- third_party/stdlib/test/test_support.py \
89- third_party/stdlib/test/test_tuple.py
90- CPYTHON_PASS_FILES := $(patsubst third_party/stdlib/% .py,$(PKG_DIR ) /grumpy/lib/% .pass,$(CPYTHON_TEST_SRCS ) )
91- STDLIB_PASS_FILES := $(LIB_PASS_FILES ) $(CPYTHON_PASS_FILES )
78+ LIB_SRCS := $(patsubst lib/% ,$(GOPATH_PY_ROOT ) /% ,$(shell find lib -name '* .py') )
79+ THIRD_PARTY_STDLIB_SRCS := $(patsubst third_party/stdlib/% ,$(GOPATH_PY_ROOT ) /% ,$(shell find third_party/stdlib -name '* .py') )
80+ THIRD_PARTY_PYPY_SRCS := $(patsubst third_party/pypy/% ,$(GOPATH_PY_ROOT ) /% ,$(shell find third_party/pypy -name '* .py') )
81+ THIRD_PARTY_OUROBOROS_SRCS := $(patsubst third_party/ouroboros/% ,$(GOPATH_PY_ROOT ) /% ,$(shell find third_party/ouroboros -name '* .py') )
82+ STDLIB_SRCS := $(LIB_SRCS ) $(THIRD_PARTY_STDLIB_SRCS ) $(THIRD_PARTY_PYPY_SRCS ) $(THIRD_PARTY_OUROBOROS_SRCS )
83+
84+
85+ STDLIB_PACKAGES := $(patsubst $(GOPATH_PY_ROOT ) /% .py,% ,$(patsubst $(GOPATH_PY_ROOT ) /% /__init__.py,% ,$(STDLIB_SRCS ) ) )
86+ STDLIB := $(patsubst % ,$(PKG_DIR ) /__python__/% .a,$(STDLIB_PACKAGES ) )
87+ STDLIB_TESTS := \
88+ itertools_test \
89+ math_test \
90+ os/path_test \
91+ os_test \
92+ random_test \
93+ re_tests \
94+ sys_test \
95+ tempfile_test \
96+ test/test_tuple \
97+ test/test_dict \
98+ test/test_list \
99+ test/test_slice \
100+ test/test_string \
101+ test/test_md5 \
102+ test/test_bisect \
103+ test/test_datetime \
104+ test/test_operator \
105+ test/test_colorsys \
106+ threading_test \
107+ time_test \
108+ types_test \
109+ weetest_test
110+ STDLIB_PASS_FILES := $(patsubst % ,build/testing/% .pass,$(notdir $(STDLIB_TESTS ) ) )
92111
93112ACCEPT_TESTS := $(patsubst % .py,% ,$(wildcard testing/* .py) )
94113ACCEPT_PASS_FILES := $(patsubst % ,build/% .pass,$(ACCEPT_TESTS ) )
@@ -97,12 +116,12 @@ ACCEPT_PY_PASS_FILES := $(patsubst %,build/%_py.pass,$(filter-out %/native_test,
97116BENCHMARKS := $(patsubst % .py,% ,$(wildcard benchmarks/* .py) )
98117BENCHMARK_BINS := $(patsubst % ,build/% _benchmark,$(BENCHMARKS ) )
99118
100- TOOL_BINS = $(patsubst % ,build/bin/% ,benchcmp coverparse diffrange)
119+ TOOL_BINS = $(patsubst % ,build/bin/% ,benchcmp coverparse diffrange genmake pydeps )
101120
102121GOLINT_BIN = build/bin/golint
103122PYLINT_BIN = build/bin/pylint
104123
105- all : $(COMPILER ) $(RUNTIME ) $(STDLIB ) $( TOOL_BINS )
124+ all : $(COMPILER ) $(RUNTIME ) $(TOOL_BINS )
106125
107126benchmarks : $(BENCHMARK_BINS )
108127
@@ -133,13 +152,15 @@ $(COMPILER_SRCS) $(COMPILER_TEST_SRCS) $(COMPILER_SHARDED_TEST_SRCS): $(PY_DIR)/
133152 @mkdir -p $(PY_DIR ) /grumpy/compiler
134153 @cp -f $< $@
135154
136- $(COMPILER_PASS_FILES ) : % .pass: % .py $(COMPILER )
155+ $(COMPILER_PASS_FILES ) : % .pass: % .py $(COMPILER ) $( COMPILER_TEST_SRCS )
137156 @$(PYTHON ) $< -q
138157 @touch $@
139158 @echo compiler/` basename $* ` PASS
140159
141- $(COMPILER_D_FILES ) : $(PY_DIR ) /% .d: $(PY_DIR ) /% .py $(COMPILER_SRCS )
142- @$(PYTHON ) -m modulefinder $< | awk ' {if (match($$2, /^grumpy\>/)) { print "$(PY_DIR)/$*.pass: " substr($$3, length("$(ROOT_DIR)/") + 1) }}' > $@
160+ # NOTE: In the regex below we use (\.|$) instead of \> because the latter is
161+ # not available in the awk available on OS X.
162+ $(COMPILER_D_FILES ) : $(PY_DIR ) /% .d: $(PY_DIR ) /% .py $(COMPILER_SRCS ) $(PYTHONPARSER_SRCS )
163+ @$(PYTHON ) -m modulefinder $< | awk ' {if (match($$2, /^grumpy(\.|$$)/)) { print "$(PY_DIR)/$*.pass: " substr($$3, length("$(ROOT_DIR)/") + 1) }}' > $@
143164
144165-include $(COMPILER_D_FILES )
145166
@@ -198,38 +219,65 @@ $(PYLINT_BIN):
198219 @cd build/third_party && curl -sL https://pypi.io/packages/source/p/pylint/pylint-1.6.4.tar.gz | tar -zx
199220 @cd build/third_party/pylint-1.6.4 && $(PYTHON ) setup.py install --prefix $(ROOT_DIR ) /build
200221
201- pylint : $(PYLINT_BIN )
202- @$(PYLINT_BIN ) compiler/ * .py $(addprefix tools/,benchcmp coverparse diffrange grumpc grumprun )
222+ pylint : $(PYLINT_BIN ) $( COMPILER_SRCS ) $( PYTHONPARSER_SRCS ) $( COMPILER_BIN ) $( RUNNER_BIN ) $( TOOL_BINS )
223+ @$(PYTHON ) $( PYLINT_BIN ) $( COMPILER_SRCS ) $(COMPILER_BIN ) $( RUNNER_BIN ) $( TOOL_BINS )
203224
204225lint : golint pylint
205226
206227# ------------------------------------------------------------------------------
207228# Standard library
208229# ------------------------------------------------------------------------------
209230
210- $(STDLIB_PASS_FILES ) : $(PKG_DIR ) /grumpy/lib/% .pass: $(PKG_DIR ) /grumpy/lib/% .a
211- @$(RUNNER_BIN ) -m ` echo $* | tr / .`
212- @touch $@
213- @echo ' lib/$* PASS'
231+ $(LIB_SRCS ) : $(GOPATH_PY_ROOT ) /% : lib/%
232+ @mkdir -p $(@D )
233+ @cp -f $< $@
214234
215- define GRUMPY_STDLIB
216- build/src/grumpy/lib/$(2 ) /module.go: $(1 ) $(COMPILER )
217- @mkdir -p build/src/grumpy/lib/$(2 )
218- @$(COMPILER_BIN ) -modname=$(notdir $(2 ) ) $(1 ) > $$@
235+ $(THIRD_PARTY_STDLIB_SRCS ) : $(GOPATH_PY_ROOT ) /% : third_party/stdlib/%
236+ @mkdir -p $(@D )
237+ @cp -f $< $@
219238
220- build/src/grumpy/lib/ $( 2 ) /module.d : $(1 )
221- @mkdir -p build/src/grumpy/lib/ $( 2 )
222- @$( PYTHON ) -m modulefinder -p $( ROOT_DIR ) /lib: $( ROOT_DIR ) /third_party/stdlib: $( ROOT_DIR ) /third_party/pypy $$< | awk '{if (($$$$1 == "m" || $$$$1 == "P") && $$$$2 != "__main__" && $$$$2 != " $( 2 ) ") {gsub(/\./, "/", $$$$2); print " $( PKG_DIR ) /grumpy/lib/ $( 2 ) .a: $( PKG_DIR ) /grumpy/lib/" $$$$2 ".a"}}' > $ $@
239+ $( THIRD_PARTY_PYPY_SRCS ) : $(GOPATH_PY_ROOT ) / % : third_party/pypy/ %
240+ @mkdir -p $( @D )
241+ @cp -f $< $@
223242
224- $(PKG_DIR ) /grumpy/lib/$(2 ) .a: build/src/grumpy/lib/$(2 ) /module.go $(RUNTIME )
225- @mkdir -p $(PKG_DIR ) /grumpy/lib/$(dir $(2 ) )
226- @go tool compile -o $$@ -p grumpy/lib/$(2 ) -complete -I $(PKG_DIR ) -pack $$<
227243
228- -include build/src/grumpy/lib/$(2 ) /module.d
244+ $(THIRD_PARTY_OUROBOROS_SRCS ) : $(GOPATH_PY_ROOT ) /% : third_party/ouroboros/%
245+ @mkdir -p $(@D )
246+ @cp -f $< $@
247+
248+ build/stdlib.mk : build/bin/genmake | $(STDLIB_SRCS )
249+ @genmake build > $@
250+
251+ -include build/stdlib.mk
252+
253+ $(patsubst % ,build/src/__python__/% /module.go,$(STDLIB_PACKAGES ) ) : $(COMPILER )
254+ $(patsubst % ,build/src/__python__/% /module.d,$(STDLIB_PACKAGES ) ) : build/bin/pydeps $(PYTHONPARSER_SRCS ) $(COMPILER )
255+ $(patsubst % ,$(PKG_DIR ) /__python__/% .a,$(STDLIB_PACKAGES ) ) : $(RUNTIME )
256+
257+ define GRUMPY_STDLIB_TEST
258+ build/testing/$(patsubst % _test,% _test_,$(notdir $(1 ) ) ) .go:
259+ @mkdir -p build/testing
260+ @echo 'package main' > $$@
261+ @echo 'import (' >> $$@
262+ @echo ' "os"' >> $$@
263+ @echo ' "grumpy"' >> $$@
264+ @echo ' mod "__python__/$(1 ) "' >> $$@
265+ @echo ')' >> $$@
266+ @echo 'func main() {' >> $$@
267+ @echo ' os.Exit(grumpy.RunMain(mod.Code))' >> $$@
268+ @echo '}' >> $$@
269+
270+ build/testing/$(notdir $(1 ) ) : build/testing/$(patsubst % _test,% _test_,$(notdir $(1 ) ) ) .go $(RUNTIME ) $(PKG_DIR ) /__python__/$(1 ) .a
271+ @go build -o $$@ $$<
272+
273+ build/testing/$(notdir $(1 ) ) .pass: build/testing/$(notdir $(1 ) )
274+ @$$<
275+ @touch $$@
276+ @echo 'lib/$(1 ) PASS'
229277
230278endef
231279
232- $(eval $(foreach x,$(shell seq $(words $(STDLIB_SRCS))) ,$(call GRUMPY_STDLIB ,$(word $(x),$(STDLIB_SRCS)),$(word $(x),$(STDLIB_PACKAGES) ))))
280+ $(eval $(foreach x,$(STDLIB_TESTS) ,$(call GRUMPY_STDLIB_TEST ,$(x ))))
233281
234282# ------------------------------------------------------------------------------
235283# Acceptance tests & benchmarks
@@ -238,6 +286,10 @@ $(eval $(foreach x,$(shell seq $(words $(STDLIB_SRCS))),$(call GRUMPY_STDLIB,$(w
238286$(PY_DIR ) /weetest.py : lib/weetest.py
239287 @cp -f $< $@
240288
289+ $(PYTHONPARSER_SRCS ) : $(PY_DIR ) /grumpy/% : third_party/%
290+ @mkdir -p $(@D )
291+ @cp -f $< $@
292+
241293$(patsubst % _test,build/% .go,$(ACCEPT_TESTS ) ) : build/% .go: % _test.py $(COMPILER )
242294 @mkdir -p $(@D )
243295 @$(COMPILER_BIN ) $< > $@
@@ -271,11 +323,12 @@ $(BENCHMARK_BINS): build/benchmarks/%_benchmark: build/benchmarks/%.go $(RUNTIME
271323
272324install : $(RUNNER_BIN ) $(COMPILER ) $(RUNTIME ) $(STDLIB )
273325 # Binary executables
274- install -Dm755 build/bin/grumpc " $( DESTDIR) /usr/bin/grumpc"
275- install -Dm755 build/bin/grumprun " $( DESTDIR) /usr/bin/grumprun"
326+ install -d " $( DESTDIR) /usr/bin"
327+ install -m755 build/bin/grumpc " $( DESTDIR) /usr/bin/grumpc"
328+ install -m755 build/bin/grumprun " $( DESTDIR) /usr/bin/grumprun"
276329 # Python module
277330 install -d " $( DESTDIR) " {/usr/lib/go," $( PY_INSTALL_DIR) " }
278- cp -rv --no-preserve=ownership " $( PY_DIR) /grumpy" " $( DESTDIR) $( PY_INSTALL_DIR) "
331+ cp -rv " $( PY_DIR) /grumpy" " $( DESTDIR) $( PY_INSTALL_DIR) "
279332 # Go package and sources
280- cp -rv --no-preserve=ownership build/pkg build/src " $( DESTDIR) /usr/lib/go/"
281-
333+ install -d " $( DESTDIR) /usr/lib/go/"
334+ cp -rv build/pkg build/src " $( DESTDIR ) /usr/lib/go/ "
0 commit comments