Integrate emscripten build process in Makefile

Move Emscripten dependencies into separate directory
This commit is contained in:
Marc Nieper-Wißkirchen 2015-06-22 20:37:52 +02:00
parent 2e4d0aed91
commit 899a15b725
6 changed files with 151 additions and 0 deletions

6
.gitignore vendored
View file

@ -1,5 +1,6 @@
# Object files
*.o
*.bc
*.ko
*.obj
*.elf
@ -36,6 +37,7 @@ lib/.*.meta
# Generated files
chibi-scheme
chibi-scheme-emscripten
chibi-scheme.pc
include/chibi/install.h
lib/chibi/emscripten.c
@ -48,6 +50,7 @@ lib/chibi/system.c
lib/chibi/time.c
*.tgz
*.html
!index.html
examples/snow-fort
examples/synthcode
@ -58,3 +61,6 @@ tmp
/lib/chibi/crypto/crypto.c
/chibi-scheme-ulimit
/clibs.c
js/chibi.*

View file

@ -82,6 +82,20 @@ endif
all: chibi-scheme$(EXE) all-libs chibi-scheme.pc $(META_FILES)
js: js/chibi.js
js/chibi.js: chibi-scheme-emscripten chibi-scheme-static.bc js/pre.js js/post.js js/exported_functions.json
emcc -O2 chibi-scheme-static.bc -o $@ -s MODULARIZE=1 -s EXPORT_NAME=\"Chibi\" -s EXPORTED_FUNCTIONS=@js/exported_functions.json `find lib -type f \( -name "*.scm" -or -name "*.sld" \) -printf " --preload-file %p"` --pre-js js/pre.js --post-js js/post.js
chibi-scheme-static.bc:
emmake $(MAKE) PLATFORM=emscripten CHIBI_DEPENDENCIES= CHIBI=./chibi-scheme-emscripten PREFIX= CFLAGS=-O2 SEXP_USE_DL=0 EXE=.bc SO=.bc CPPFLAGS="-DSEXP_USE_STRICT_TOPLEVEL_BINDINGS=1 -DSEXP_USE_ALIGNED_BYTECODE=1 -DSEXP_USE_STATIC_LIBS=1" clibs.c chibi-scheme-static.bc
chibi-scheme-emscripten: VERSION
$(MAKE) clean
$(MAKE) chibi-scheme-static PLATFORM=emscripten SEXP_USE_DL=0
mv chibi-scheme-static$(EXE) chibi-scheme-emscripten
$(MAKE) clean
include/chibi/install.h: Makefile
echo '#define sexp_so_extension "'$(SO)'"' > $@
echo '#define sexp_default_module_path "'$(MODDIR):$(BINMODDIR)'"' >> $@
@ -242,6 +256,8 @@ clean: clean-libs
cleaner: clean
-$(RM) chibi-scheme$(EXE) chibi-scheme-static$(EXE) chibi-scheme-ulimit$(EXE) \
libchibi-scheme$(SO)* *.a *.pc include/chibi/install.h lib/.*.meta \
chibi-scheme-emscripten \
js/chibi.* \
$(shell $(FIND) lib -name \*.o)
dist-clean: dist-clean-libs cleaner

View file

@ -0,0 +1,5 @@
[
'_main',
'_sexp_resume'
]

116
js/index.html Normal file
View file

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chibi-Scheme</title>
<style>
body {
font-family: sans-serif;
height: 100vh;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
}
main {
flex: 1;
display: flex;
flex-direction: column;
}
#program {
flex: 1 1 0;
padding: 0.5em;
}
#start {
font-size: inherit;
padding: 0.5em;
}
#output {
font-family: monospace;
padding: 0.5em;
white-space: pre;
background-color: #000;
color: #fff;
overflow: auto;
flex: 1 1 0;
}
</style>
</head>
<body>
<main>
<textarea id="program" spellcheck="false">;
; This is Chibi-Scheme compiled with Emscripten to run in the browser.
;
(import (scheme base))
(write-string "Hello, world!\n")
;
; You can also run arbitrary JavaScript code from scheme and yield control back and forth between Scheme and the browser
;
(import (chibi emscripten)) ; exports: eval-script!, integer-eval-script, string-eval-script, wait-on-event!
(write-string (number->string (integer-eval-script "6 * 7")))
(newline)
(eval-script! "window.addEventListener('click', function () {
Module['resume'](); // give control back to the Scheme process
})")
(let loop ()
(wait-on-event!) ; yields control back to the browser
(write-string "You have clicked me!\n")
(loop))
(write-string "Control never reaches this point\n")
</textarea>
<button type="button" id="start" disabled>Start Program</button>
<div id="output"></div>
</main>
<script src="chibi.js"></script>
<script>
function start(program, args, onOutput, onError) {
var firstError = true;
Chibi({
print: onOutput,
printErr: function (text) {
if (firstError) {
firstError = false;
return;
}
if (onError !== undefined) {
onError(text);
} else {
onOutput(text);
}
},
program: program,
arguments: args
});
}
</script>
<script>
(function () {
var programField = document.querySelector('#program');
var startButton = document.querySelector('#start');
var program = sessionStorage.getItem('program');
if (program) {
programField.value = program;
}
programField.addEventListener('input', function() {
sessionStorage.setItem('program', programField.value);
});
startButton.addEventListener('click', function() {
var program = programField.value;
startButton.disabled = true;
start(program, [],
function(text) {
output.textContent = output.textContent + text + '\n'
});
});
startButton.disabled = false;
})();
</script>
</body>
</html>

2
js/post.js Normal file
View file

@ -0,0 +1,2 @@
Module['resume'] = Module.cwrap('sexp_resume', 'void', []);

6
js/pre.js Normal file
View file

@ -0,0 +1,6 @@
Module['preRun'].push(function () {
FS.writeFile('program.scm', Module['program']);
});
Module['arguments'] = Module['arguments'] || [];
Module['arguments'].unshift('program.scm');