Skip to content

Commit

Permalink
[interpreter] Use dune instead of ocamlbuild (#1665)
Browse files Browse the repository at this point in the history
  • Loading branch information
zapashcanon authored Jul 26, 2023
1 parent cfc9343 commit 653938a
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 294 deletions.
15 changes: 4 additions & 11 deletions interpreter/.gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
*.cmo
*.cmx
*.native
*.byte
*.opt
*.unopt
*.js
*.zip
*.mlpack
_build
wasm
wasm.debug

*.install
*.js
*.zip
opam
212 changes: 54 additions & 158 deletions interpreter/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This Makefile uses ocamlbuild but does not rely on ocamlfind or the Opam
# This Makefile uses dune but does not rely on ocamlfind or the Opam
# package manager to build. However, Opam package management is available
# optionally through the check/install/uninstall targets.
#
Expand All @@ -9,131 +9,45 @@

# Configuration

NAME = wasm
UNOPT = $(NAME).debug
OPT = $(NAME)
LIB = $(NAME)
NAME = wasm
OPT = $(NAME).exe
ZIP = $(NAME).zip
JSLIB = wast
WINMAKE = winmake.bat

DIRS = util syntax binary text valid runtime exec script host main tests
LIBS =
FLAGS = -lexflags -ml -cflags '-w +a-4-27-42-44-45-70 -warn-error +a-3'
OCBA = ocamlbuild $(FLAGS) $(DIRS:%=-I %)
OCB = $(OCBA) $(LIBS:%=-libs %)
JSO = js_of_ocaml -q --opt 3
JS = # set to JS shell command to run JS tests, empty to skip
JSLIB = wast.js

BUILDDIR = _build/default

# Main targets
JS = # set to JS shell command to run JS tests, empty to skip

.PHONY: default opt unopt libopt libunopt jslib all land zip smallint dunebuild

default: opt
debug: unopt
opt: $(OPT)
unopt: $(UNOPT)
libopt: _build/$(LIB).cmx _build/$(LIB).cmxa
libunopt: _build/$(LIB).cmo _build/$(LIB).cma
jslib: $(JSLIB).js
all: unopt opt libunopt libopt test
land: $(WINMAKE) all
zip: $(ZIP)
smallint: smallint.native
ci: land jslib dunebuild
# Main targets

dunebuild:
dune build
.PHONY: default opt jslib all zip smallint

default: $(OPT)
jslib: $(JSLIB)
all: $(OPT) test
zip: $(ZIP)
smallint: smallint.exe
ci: all jslib

# Building executable
.PHONY: $(NAME).exe
$(NAME).exe:
rm -f $(NAME)
dune build $@
cp $(BUILDDIR)/$(OPT) $(NAME)

empty =
space = $(empty) $(empty)
comma = ,

.INTERMEDIATE: _tags
_tags:
echo >$@ "true: bin_annot"
echo >>$@ "true: debug"
echo >>$@ "<{$(subst $(space),$(comma),$(DIRS))}/*.cmx>: for-pack($(PACK))"

$(UNOPT): main.byte
mv $< $@

$(OPT): main.native
mv $< $@

.PHONY: main.byte main.native
main.byte: _tags
$(OCB) -quiet $@

main.native: _tags
$(OCB) -quiet $@

.PHONY: smallint.byte smallint.native
smallint.byte: _tags
$(OCB) -quiet $@
smallint.native: _tags
$(OCB) -quiet $@


# Building library

FILES = $(shell ls $(DIRS:%=%/*) | grep '[.]ml[^.]*$$')
PACK = $(shell echo `echo $(LIB) | sed 's/^\(.\).*$$/\\1/g' | tr [:lower:] [:upper:]``echo $(LIB) | sed 's/^.\(.*\)$$/\\1/g'`)
.INTERMEDIATE: $(LIB).mlpack
$(LIB).mlpack: $(DIRS)
ls $(FILES) \
| sed 's:\(.*/\)\{0,1\}\(.*\)\.[^\.]*:\2:' \
| grep -v main \
| sort | uniq \
>$@
.INTERMEDIATE: $(LIB).mllib
$(LIB).mllib:
echo Wasm >$@
_build/$(LIB).cmo: $(FILES) $(LIB).mlpack _tags Makefile
$(OCB) -quiet $(LIB).cmo
_build/$(LIB).cmx: $(FILES) $(LIB).mlpack _tags Makefile
$(OCB) -quiet $(LIB).cmx
_build/$(LIB).cma: $(FILES) $(LIB).mllib _tags Makefile
$(OCBA) -quiet $(LIB).cma
_build/$(LIB).cmxa: $(FILES) $(LIB).mllib _tags Makefile
$(OCBA) -quiet $(LIB).cmxa
.PHONY: smallint.exe
smallint.exe:
dune build $@

# Building JavaScript library

JSLIB_DIR = meta/jslib
JSLIB_FLAGS = -I $(JSLIB_DIR) -use-ocamlfind -pkg js_of_ocaml -pkg js_of_ocaml-ppx
.INTERMEDIATE: $(JSLIB).byte
$(JSLIB).byte: $(JSLIB_DIR)/$(JSLIB).ml
$(OCBA) $(JSLIB_FLAGS) $@
$(JSLIB).js: $(JSLIB).byte
$(JSO) $<
# Building Windows build file
$(WINMAKE): clean
echo rem Auto-generated from Makefile! >$@
echo set NAME=$(NAME) >>$@
echo if \'%1\' neq \'\' set NAME=%1 >>$@
$(OCB) main.byte \
| grep -v ocamldep \
| grep -v mkdir \
| sed s:`which ocaml`:ocaml:g \
| sed s:main/main.d.byte:%NAME%.exe: \
>>$@
$(JSLIB): $(BUILDDIR)/$(JSLIB)
cp $< $@

$(BUILDDIR)/$(JSLIB):
dune build $(JSLIB)

# Executing test suite

Expand All @@ -142,78 +56,60 @@ TESTDIR = ../test/core
TESTFILES = $(shell cd $(TESTDIR); ls *.wast; ls [a-z]*/*.wast)
TESTS = $(TESTFILES:%.wast=%)

.PHONY: test debugtest partest dune-test
.PHONY: test partest dune-test

test: $(OPT) smallint
$(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',)
./smallint.native
debugtest: $(UNOPT) smallint
$(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',)
./smallint.native
$(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',)
dune exec ./smallint.exe

test/%: $(OPT)
$(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast
debugtest/%: $(UNOPT)
$(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast
$(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast

run/%: $(OPT)
./$(OPT) $(TESTDIR)/$*.wast
debug/%: $(UNOPT)
./$(UNOPT) $(TESTDIR)/$*.wast

partest: $(TESTS:%=quiettest/%)
partest: $(TESTS:%=quiettest/%)
@echo All tests passed.

quiettest/%: $(OPT)
@ ( \
$(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \
$(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \
rm $(@F).out \
) || \
cat $(@F).out || rm $(@F).out || exit 1

smallinttest: smallint
@./smallint.native
dune exec ./smallint.exe

dunetest:
dune test

install:
dune build -p $(NAME) @install
dune install

opam-release/%:
git tag opam-$*
git push --tags
rm -f opam-$*.zip
wget https://github.com/WebAssembly/spec/archive/opam-$*.zip
cp wasm.opam opam
echo "url {" >> opam
echo " src: \"https://github.com/WebAssembly/spec/archive/opam-$*.zip\"" >> opam
echo " checksum: \"md5=`md5 -q opam-$*.zip`\"" >> opam
echo "}" >> opam
rm opam-$*.zip
@echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam

# Miscellaneous targets

.PHONY: clean

$(ZIP): $(WINMAKE)
git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD
$(ZIP):
git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD

clean:
rm -rf _build/jslib $(LIB).mlpack _tags $(JSLIB).js
$(OCB) -clean
# Opam support
.PHONY: check install uninstall
dune clean

check:
# Check that we can find all relevant libraries
# when using ocamlfind
ocamlfind query $(LIBS)
install: _build/$(LIB).cmx _build/$(LIB).cmo
ocamlfind install $(LIB) meta/findlib/META _build/$(LIB).o \
$(wildcard _build/$(LIB).cm*) \
$(wildcard $(DIRS:%=%/*.mli))
uninstall:
ocamlfind remove $(LIB)
opam-release/%:
git tag opam-$*
git push --tags
rm -f opam-$*.zip
wget https://github.com/WebAssembly/spec/archive/opam-$*.zip
cp meta/opam/opam .
sed -i ".tmp" s/@VERSION/$*/g opam
sed -i ".tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam
rm opam.tmp opam-$*.zip
@echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam
distclean: clean
rm -f $(NAME) $(JSLIB)
19 changes: 3 additions & 16 deletions interpreter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ The text format defines modules in S-expression syntax. Moreover, it is generali

You'll need OCaml 4.12 or higher. Instructions for installing a recent version of OCaml on multiple platforms are available [here](https://ocaml.org/docs/install.html). On most platforms, the recommended way is through [OPAM](https://ocaml.org/docs/install.html#OPAM).

You'll also need to install the dune build system. See the [installation instructions](https://github.com/ocaml/dune#installation-1).

Once you have OCaml, simply do

```
make
```
You'll get an executable named `./wasm`. This is a byte code executable. If you want a (faster) native code executable, do
```
make opt
```
You'll get an executable named `./wasm`.
To run the test suite,
```
make test
Expand All @@ -34,12 +33,6 @@ To do everything:
```
make all
```
Before committing changes, you should do
```
make land
```
That builds `all`, plus updates `winmake.bat`.


#### Building on Windows

Expand All @@ -49,12 +42,6 @@ The instructions depend on how you [installed OCaml on Windows](https://ocaml.or

2. *Windows Subsystem for Linux* (WSL): You can build the interpreter using `make`, as described above.

3. *From source*: If you just want to build the interpreter and don't care about modifying it, you don't need to install the Cygwin core that comes with the installer. Just install OCaml itself and run
```
winmake.bat
```
in a Windows shell, which creates a program named `wasm`. Note that this will be a byte code executable only, i.e., somewhat slower.

In any way, in order to run the test suite you'll need to have Python installed. If you used Option 3, you can invoke the test runner `runtests.py` directly instead of doing it through `make`.


Expand Down
31 changes: 24 additions & 7 deletions interpreter/dune
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
(include_subdirs unqualified)

(library
(name wasm)
; The 'main' module shall not be part of the library, as it would start the
(public_name wasm)
; The 'wasm' module shall not be part of the library, as it would start the
; Wasm REPL every time in all the dependencies.
; We exclude the 'wast' module as it is only used for the JS build.
; 'smallint' is a separate test module.
(modules :standard \ main smallint wast))
(modules :standard \ main wasm smallint wast))

(executable
(name main)
(modules main)
(public_name wasm)
(modules wasm)
(libraries wasm)
(flags
(-open Wasm)))
Expand All @@ -22,6 +22,23 @@
(flags
(-open Wasm)))

(executable
(name wast)
(modules wast)
(modes js)
(libraries js_of_ocaml wasm)
(preprocess (pps js_of_ocaml-ppx)))

(rule
(targets wasm.ml)
(deps main/main.ml)
(action (copy main/main.ml wasm.ml)))

(rule
(targets wast.js)
(deps wast.bc.js)
(action (copy wast.bc.js wast.js)))

(subdir
text
(rule
Expand All @@ -42,10 +59,10 @@
(rule
(alias runtest)
(deps
./main.exe
./wasm.exe
./smallint.exe
(source_tree ../test))
(action
(progn
(run ../test/core/run.py --wasm ./main.exe)
(run ../test/core/run.py --wasm ./wasm.exe)
(run ./smallint.exe))))
Loading

0 comments on commit 653938a

Please sign in to comment.