Skip to content

Latest commit

 

History

History
149 lines (132 loc) · 5.87 KB

COMPILE.md

File metadata and controls

149 lines (132 loc) · 5.87 KB
  1. mkdir hello-ncurses, cd hello-ncurses.
  2. wget ftp://ftp.invisible-island.net/ncurses/ncurses-6.1.tar.gz
  3. tar xf ncurses-6.1.tar.gz
  4. cd ncurses-6.1

How to Compile ncurses

Emscripten's getenv is not Reentrant

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:

  1. vim emsdk/emscripten/1.38.8/system/include/libc/stdlib.h
  2. 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
  1. run emcc --clear-cache and try to compile hello world after it to rebuild the cache.

Understanding

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.

  1. I don't know how to get use of --with-build-cc for compiling only two targets (make_hash and make_keys).
  2. In addition to make_keys and make_hash you will need to compile to x86 report_offsets also. You will also need terminfo database which I believe can't be compiled with emmake make install, so you have to use bare make and make install (not sure, should be checked).
  3. mkdir ./INSTALLED
  4. ./configure --prefix=`pwd`/INSTALLED
  5. make
  6. make install
  7. mkdir ../lib
  8. cp -r INSTALLED/share/terminfo ../lib/.
  9. cd ncurses
  10. cp make_hash make_hash_x86
  11. cp make_keys make_keys_x86
  12. cp report_offsets report_offsets_x86
  13. cd ..
  14. make clean
  15. cd ncurses.
  16. Now in ./ncurses dir you should have make_hash_x86, make_keys_x86 and report_offsets_x86.
  17. 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
  1. 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)
  1. cd .., make clean, emconfigure ./configure.
  2. emmake make
  3. cd ../
  4. 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;
}
  1. wget https://github.com/kripken/emscripten/blob/master/src/shell_minimal.html -O min-shell.html (the link is from here).
  2. 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.