Compiling

Overview

There are two basic steps to compiling Duktape:

While Duktape is usually compiled together with your application, you can also build it into a static or shared library. Duktape can also be installed as a system-wide library, see system-install.rst.

The DUK_OPT_xxx feature options are no longer supported in Duktape 2.x. All configuration information is embedded in duk_config.h and/or autogenerated sources and headers.

Configuring

Preconfigured sources and default configuration

The Duktape distributable contains preconfigured sources and headers with a few variants:

These preconfigured sources provide automatic platform, compiler, and architecture detection and use the Duktape default configuration:

The preconfigured sources cannot be used to build Duktape into a Windows DLL. Run configure.py with the --dll option to do that.

Running configure.py to customize Duktape configuration

The configure.py utility prepares Duktape source and header files for a specific configuration described using command line options. For example, to prepare Duktape sources for a DLL build with fastint support enabled and Ecmascript 6 Proxy object support disabled:

# Default output format is single source file (--separate-sources for separate
# sources) and no #line directives (--line-directives to enable them).

$ python2 tools/configure.py \
      --output-directory /tmp/output \
      --dll \
      -DDUK_USE_FASTINT \
      -UDUK_USE_ES6_PROXY

# The output directory /tmp/output contains the header and source files to
# be included in your build.

$ ls /tmp/output
duk_config.h  duk_source_meta.json  duktape.c  duktape.h

Configuration options given to configure.py affect several different aspects of the prepared header and source files, for example:

The configure.py utility requires Python 2.x support. If your build environment doesn't support Python 2.x, you can run configure.py on a different platform and compile the resulting files in your build environment.

Even if the default options are OK, it's recommended that you run configure.py as part of your build instead of using the preconfigured sources. Custom options may be necessary on e.g. low memory platforms. See Configuring Duktape for build for more practical details.

Commonly needed configuration options

Some commonly needed configuration options are:

Memory management alternatives

There are two supported memory management alternatives:

Reference counting relies on mark-and-sweep to handle reference cycles. For example, every Ecmascript function instance is required to be in a reference loop with an automatic prototype object created for the function. You can break this loop manually if you wish. For internal technical reasons, named function expressions are also in a reference loop; this loop cannot be broken from user code and only mark-and-sweep can collect such functions.

Compiling

General guidelines

Duktape doesn't have an official Makefile or a build script: given the number of different portability targets, maintaining an official build script would be difficult. Instead, you should add Duktape to your existing build process in whatever way is most natural.

Duktape is compiled with a C or C++ compiler (C99 is recommended) and then linked to your program in some way; the exact details vary between platforms and toolchains. For example, you can:

All Duktape API functions are potentially macros, and the implementation of a certain API primitive may change between a macro and an actual function even between compatible releases. Some Duktape configuration options also affect binary compatibility. To ensure binary compatibility:

Recommended compiler options

Recommended compiler options for GCC/clang, use similar options for your compiler:

Compilation warnings

Duktape usually compiles without warnings when using a mainstream compiler (e.g. GCC, Clang, MSVC, or MinGW) in C99 mode with warnings enabled (e.g. -Wall in gcc/clang), and using default Duktape configuration options. There may be some warnings when using a non-mainstream compiler, very strict warning levels (like -Wextra in gcc/clang or /W4 in MSVC), or non-default Duktape configuration options. Eliminating compilation warnings for all compilers and all configuration option combinations is very difficult and is thus explicitly not a project goal. You're still encouraged to report warnings so that they can be fixed if possible.

Using a C++ compiler

Duktape works with both C and C++ compilers and applications. You can compile Duktape and the application with a C or a C++ compiler in any combination. Even so, it is recommended to compile both Duktape and the application with the same compiler (i.e. both with a C compiler or both with a C++ compiler) and with the same compiler options.

The duktape.h header contains the necessary glue to make all of these combinations work. Specifically, all symbols needed by Duktape public API are inside a extern "C" { ... } wrapper when compiled with a C++ compiler. This ensures that such symbols are defined and used without C++ name mangling. Specifically:

If you mix C and C++ compilation, you should do the final linking with the C++ toolchain. At least when mixing gcc/g++ you may encounter something like:

$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ gcc -o duk duktape.o duk_cmdline.o -lm
duktape.o:(.eh_frame+0x1ab): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status

One fix is to use g++ for linking:

$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ g++ -o duk duktape.o duk_cmdline.o -lm

Because duk_config.h selects C/C++ data types needed by Duktape and also does other feature detection, mixing C and C++ compilers could theoretically cause the C and C++ compilers to end up with different active features or data types. If that were to happen, Duktape and the application would be binary incompatible which would lead to very difficult to diagnose issues. This is usually not an issue, but to avoid the potential, compile Duktape and the application with the same compiler.

By default scope-based resource management (sometimes referred to as RAII) won't work in Duktape/C functions because Duktape uses longjmp() for internal long control transfers, bypassing C++ stack unwind mechanisms. You can use DUK_USE_CPP_EXCEPTIONS to cause Duktape to use C++ exceptions for internal long control transfers, which allows scope-based resource management to work in Duktape/C functions.