mkdir hello-ncurses
,cd hello-ncurses
.wget ftp://ftp.invisible-island.net/ncurses/ncurses-6.1.tar.gz
tar xf ncurses-6.1.tar.gz
cd ncurses-6.1
Ncurses expects getenv to be reentrant, but emscripten doesn't provide it. You may vote for a request to provide reentrance. So, the first thing would be to patch emscripten getenv to be reentrant:
vim emsdk/emscripten/1.38.8/system/include/libc/stdlib.h
- Replace line
char *getenv (const char *);
with this block:
#pragma push_macro("getenv")
#undef getenv
char *getenv (const char *);
#pragma pop_macro("getenv")
#ifndef getenv
#include <string.h>
#define getenv(name) (char*)({\
\
char* volat = getenv(name);\
int vlen = strlen(volat) + 1;\
char* dest = (char*)malloc(vlen * sizeof(char));\
strcpy(dest, volat);\
dest;\
})
#endif
- run
emcc --clear-cache
and try to compile hello world after it to rebuild the cache.
From https://kripken.github.io/emscripten-site/docs/compiling/Building-Projects.html:
Some large projects generate executables and run them in order to generate input for later parts of the build process (for example, a parser may be built and then run on a grammar, which then generates C/C++ code that implements that grammar). This sort of build process causes problems when using Emscripten because you cannot directly run the code you are generating.
The simplest solution is usually to build the project twice: once natively, and once to JavaScript. When the JavaScript build procedure fails because a generated executable is not present, you can then copy that executable from the native build, and continue to build normally. This approach was successfully used for compiling Python (see tests/python/readme.md for more details).
From INSTALL
:
BUILDING NCURSES WITH A CROSS-COMPILER
Ncurses can be built with a cross-compiler. Some parts must be built with the host's compiler since they are used for building programs (e.g., ncurses/make_hash and ncurses/make_keys) that generate tables that are compiled into the ncurses library. The essential thing to do is set the BUILD_CC environment variable to your host's compiler, and run the configure script configuring for the cross-compiler.
The configure options --with-build-cc, etc., are provided to make this simpler. Since make_hash and make_keys use only ANSI C features, it is normally not necessary to provide the other options such as --with-build-libs, but they are provided for completeness.
- I don't know how to get use of
--with-build-cc
for compiling only two targets (make_hash
andmake_keys
). - In addition to
make_keys
andmake_hash
you will need to compile to x86report_offsets
also. You will also need terminfo database which I believe can't be compiled withemmake make install
, so you have to use baremake
andmake install
(not sure, should be checked). mkdir ./INSTALLED
./configure --prefix=`pwd`/INSTALLED
make
make install
mkdir ../lib
cp -r INSTALLED/share/terminfo ../lib/.
cd ncurses
cp make_hash make_hash_x86
cp make_keys make_keys_x86
cp report_offsets report_offsets_x86
cd ..
make clean
cd ncurses
.- Now in
./ncurses
dir you should havemake_hash_x86
,make_keys_x86
andreport_offsets_x86
. vim tinfo/MKcaptab.sh
and
make the following changes:
./make_hash 1 info $OPT1 <$DATA
./make_hash 3 cap $OPT1 <$DATA
replace on:
./make_hash_x86 1 info $OPT1 <$DATA
./make_hash_x86 3 cap $OPT1 <$DATA
vim Makefile.in
and
make the following changes:
init_keytry.h: make_keys$(BUILD_EXEEXT) keys.list
./make_keys$(BUILD_EXEEXT) keys.list > $@
replace on:
init_keytry.h: make_keys$(BUILD_EXEEXT) keys.list
./make_keys_x86$(BUILD_EXEEXT) keys.list > $@
and
report_offsets$(BUILD_EXEEXT) : \
$(srcdir)/report_offsets.c
$(BUILD_CC) -o $@ $(BUILD_CPPFLAGS) $(BUILD_CCFLAGS) $(srcdir)/report_offsets.c $(BUILD_LDFLAGS) $(BUILD_LIBS)
./report_offsets$(BUILD_EXEEXT)
replace on:
report_offsets$(BUILD_EXEEXT) : \
$(srcdir)/report_offsets.c
$(BUILD_CC) -o $@ $(BUILD_CPPFLAGS) $(BUILD_CCFLAGS) $(srcdir)/report_offsets.c $(BUILD_LDFLAGS) $(BUILD_LIBS)
./report_offsets_x86$(BUILD_EXEEXT)
cd ..
,make clean
,emconfigure ./configure
.emmake make
cd ../
vim hello.c
:
#include <curses.h>
int main()
{
// See https://linux.die.net/man/3/curs_trace.
// Write debug messages to the ./trace file:
trace(TRACE_MAXIMUM);
initscr(); /* Start curses mode */
printw("Hello World !!!"); /* Print Hello World */
refresh(); /* Print it on to the real screen */
getch(); /* Wait for user input */
endwin(); /* End curses mode */
return 0;
}
wget https://github.com/kripken/emscripten/blob/master/src/shell_minimal.html -O min-shell.html
(the link is from here).vim min-shell.html
, add:
...
var Module = {
preRun: [function() {ENV.TERM='xterm-new'}],
...
Also add xterm.js, look at ./min-shell.html for details.
25. Compile with emcc ./hello.c -L ./ncurses-6.1/lib -I ./ncurses-6.1/include -lncurses_g --preload-file lib/terminfo@/home/web_user/.terminfo -o hello.html -s FORCE_FILESYSTEM=1 --shell-file ./min-shell.html
. lncurses_g
is used for outputting debug messages. If this doesn't work for you, look up compile command in the ./hello2.sh.
26. Run your favorite http server from ./
, open http://localhost:YOUR_PORT/hello.html in a browser.