mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
17 KiB
336 lines
17 KiB
<a name="installing-system-wide"></a> <!-- for old links -->
|
|
<h1 id="compiling">Compiling</h1>
|
|
|
|
<h2>Overview</h2>
|
|
|
|
<p>There are two basic steps to compiling Duktape:</p>
|
|
<ul>
|
|
<li><b>Configuration</b>. Use <code>tools/configure.py</code> to prepare
|
|
Duktape source and header files for compilation. The requested Duktape
|
|
configuration is described using configure.py command line options,
|
|
see <a href="http://wiki.duktape.org/Configuring.html">Configuring Duktape for build</a>.
|
|
For example:
|
|
<pre>
|
|
$ python2 tools/configure.py --output-directory /tmp/output -DDUK_USE_FASTINT -UDUK_USE_ES6_PROXY
|
|
$ ls /tmp/output/
|
|
duk_config.h duk_source_meta.json duktape.c duktape.h
|
|
</pre></li>
|
|
<li><b>Compilation</b>. Ensure that the generated header files are in the compiler
|
|
include search path, and include the generate source file(s) in your application
|
|
build; there's no official Duktape build script or Makefile.
|
|
For example:
|
|
<pre>
|
|
$ gcc -O2 -Wall -otest -I/tmp/output /tmp/output/duktape.c my_application.c -lm
|
|
</pre></li>
|
|
</ul>
|
|
|
|
<p>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
|
|
<a href="https://github.com/svaarala/duktape/blob/master/doc/system-install.rst">system-install.rst</a>.</p>
|
|
|
|
<div class="note">
|
|
The <code>DUK_OPT_xxx</code> feature options are no longer supported in
|
|
Duktape 2.x. All configuration information is embedded in <code>duk_config.h</code>
|
|
and/or autogenerated sources and headers.
|
|
</div>
|
|
|
|
<a name="timing-sensitive-options"></a> <!-- for old links -->
|
|
<a name="memory-constrained-options"></a> <!-- for old links -->
|
|
<a name="performance-sensitive-options"></a> <!-- for old links -->
|
|
<h2>Configuring</h2>
|
|
|
|
<h3>Preconfigured sources and default configuration</h3>
|
|
|
|
<p>The Duktape distributable contains preconfigured sources and headers with
|
|
a few variants:</p>
|
|
<ul>
|
|
<li><code>src/</code>: a single source file version which consists of
|
|
<code>duk_config.h</code>, <code>duktape.h</code>, and <code>duktape.c</code>.</li>
|
|
<li><code>src-noline/</code>: same as <code>src/</code> but with no <code>#line</code>
|
|
directives in the combined source file; this matters in some environments,
|
|
see <a href="https://github.com/svaarala/duktape/pull/363">https://github.com/svaarala/duktape/pull/363</a>.</li>
|
|
<li><code>src-separate/</code>: a separate source files version which consists
|
|
of <code>duk_config.h</code>, <code>duktape.h</code>, and a set of separate
|
|
source files. The single source file version is preferred, but separate
|
|
files work better with some toolchains.</li>
|
|
</ul>
|
|
|
|
<p>These preconfigured sources provide automatic platform, compiler, and
|
|
architecture detection and use the Duktape default configuration:</p>
|
|
<ul>
|
|
<li>Full Ecmascript E5/E5.1 compliance
|
|
(including the optional
|
|
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-B">Annex B</a>
|
|
features), except for intentional real world compatibility deviations
|
|
(see <a href="#custombehavior">Custom behavior</a>)</li>
|
|
<li>ES2015 typed array and Node.js Buffer support</li>
|
|
<li>Some features from <a href="#es6features">Ecmascript 2015 (E6)</a> and
|
|
<a href="#es7features">Ecmascript 2016 (E7)</a></li>
|
|
<li>Packed value representation (8 bytes per value) when available,
|
|
unpacked value representation (usually 16 bytes per value) when not</li>
|
|
<li>Reference counting and mark-and-sweep garbage collection</li>
|
|
<li>Full error messages and tracebacks</li>
|
|
<li>No debug printing, no asserts, etc</li>
|
|
<li>All portable fast paths enabled</li>
|
|
</ul>
|
|
|
|
<div class="note">
|
|
The preconfigured sources cannot be used to build Duktape into a Windows DLL.
|
|
Run <code>configure.py</code> with the <code>--dll</code> option to do that.
|
|
</div>
|
|
|
|
<h3>Running configure.py to customize Duktape configuration</h3>
|
|
|
|
<p>The <code>configure.py</code> 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 <code>Proxy</code> object support disabled:</p>
|
|
<pre>
|
|
# 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
|
|
</pre>
|
|
|
|
<p>Configuration options given to <code>configure.py</code> affect several
|
|
different aspects of the prepared header and source files, for example:</p>
|
|
<ul>
|
|
<li>Optional features in Duktape source code are enabled/disabled using config
|
|
options (<code>DUK_USE_xxx</code>) which are provided by the
|
|
<code>duk_config.h</code> configuration header. The configuration
|
|
header also handles platform, architecture, and compiler detection, and
|
|
all other aspects of platform portability.</li>
|
|
<li>Built-in objects and strings are read in from metadata files and bit-packed
|
|
built-in initialization data is generated. It's also possible to supply
|
|
custom metadata files to add custom built-in bindings or modify standard
|
|
built-ins such as <code>Math</code> and <code>JSON</code>.</li>
|
|
<li>When using "ROM built-ins", built-in objects and strings are placed into the
|
|
read-only code section to reduce RAM footprint. The necessary source code
|
|
for built-in object/string initializers is autogenerated by configure.py.
|
|
Also custom built-ins can be placed in the read-only code section.</li>
|
|
<li>Unicode data files (UnicodeData.txt and SpecialCasing.txt) are converted into
|
|
bit-packed run-time Unicode tables. The Unicode data files can also be
|
|
overridden e.g. to reduce Unicode table footprint.</li>
|
|
</ul>
|
|
|
|
<p>The <code>configure.py</code> utility requires Python 2.x support. If your
|
|
build environment doesn't support Python 2.x, you can run <code>configure.py</code>
|
|
on a different platform and compile the resulting files in your build environment.</p>
|
|
|
|
<p>Even if the default options are OK, it's recommended that you run
|
|
<code>configure.py</code> as part of your build instead of using the
|
|
preconfigured sources. Custom options may be necessary on e.g. low memory
|
|
platforms. See
|
|
<a href="http://wiki.duktape.org/Configuring.html">Configuring Duktape for build</a>
|
|
for more practical details.</p>
|
|
|
|
<a name="duktape-date-provider"></a> <!-- for old links -->
|
|
<h3>Commonly needed configuration options</h3>
|
|
|
|
<p>Some commonly needed configuration options are:</p>
|
|
|
|
<ul>
|
|
<li><b>DUK_USE_FATAL_HANDLER, strongly recommended</b>. The built-in default fatal
|
|
error handler will write a debug log message (but <b>won't</b> write anything to
|
|
<code>stdout</code> to <code>stderr</code>), and will then call <code>abort()</code>.
|
|
If that fails, it enters an infinite loop to ensure execution doesn't resume
|
|
after a fatal error. This is usually not the best behavior for production
|
|
applications which may already have better fatal error recovery mechanisms.
|
|
To replace the default fatal handler, see
|
|
<a href="http://wiki.duktape.org/HowtoFatalErrors.html">How to handle fatal errors</a>.</li>
|
|
<li><b>Long control transfer: setjmp/longjmp and C++ exceptions</b>.
|
|
By default Duktape uses <code>setjmp()</code> and <code>longjmp()</code>
|
|
(or their variants) for internal long control transfers. If you're
|
|
compiling with a C++ compiler you may want to use
|
|
<code>DUK_USE_CPP_EXCEPTIONS</code> which causes Duktape to use C++
|
|
exceptions for long control transfers and allows scope-based resource
|
|
management (automatic destructors, etc; sometimes referred to as
|
|
<a href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a>)
|
|
in Duktape/C functions to work as expected.</li>
|
|
<li><b>Windows DLL build</b>. Windows DLL build requires some
|
|
<code>declspec()</code> declarations for DLL library symbols. Use the
|
|
<code>--dll</code> option when running <code>configure.py</code> to
|
|
enable them for Duktape symbols.</li>
|
|
<li><b>Forced byte order or alignment</b>. If you're using Duktape on a
|
|
platform where Duktape's automatic feature detection doesn't (yet) work,
|
|
you may need to force a specific byte order or alignment requirements
|
|
during the configuration step.</li>
|
|
<li><b>Date built-in on exotic platforms</b>. When porting to new or exotic
|
|
platforms the Duktape built-in Date support may not work on the platform.
|
|
In such a case you can implement an external "Date provider" which allows
|
|
you to provide the necessary date/time primitives without Duktape changes. See
|
|
<a href="https://github.com/svaarala/duktape/blob/master/doc/datetime.rst">datetime.rst</a>.</li>
|
|
</ul>
|
|
|
|
<!-- XXX: this might be more suited to the Wiki -->
|
|
<h3>Memory management alternatives</h3>
|
|
|
|
<p>There are two supported memory management alternatives:</p>
|
|
<ul>
|
|
<li><b>Reference counting and mark-and-sweep (default)</b>: heap objects are
|
|
freed immediately when they become unreachable except for objects
|
|
participating in unreachable reference cycles. Such objects are freed by
|
|
a periodic voluntary, stop the world mark-and-sweep collection.
|
|
Mark-and-sweep is also used as the emergency garbage collector if
|
|
memory allocation fails.</li>
|
|
<li><b>Mark-and-sweep only</b>: reduces code footprint and memory footprint
|
|
(heap headers don't need to store a reference count), but there is more
|
|
memory usage variance than in the default case. The frequency of voluntary,
|
|
stop the world mark-and-sweep collections is also higher than in the default
|
|
case where reference counting is expected to handle almost all memory
|
|
management. Voluntary (non-emergency) mark-and-sweep can be disabled via
|
|
config options.</li>
|
|
</ul>
|
|
|
|
<p>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.</p>
|
|
|
|
<h2>Compiling</h2>
|
|
|
|
<h3>General guidelines</h3>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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:</p>
|
|
<ul>
|
|
<li>Compile Duktape together with your program without an explicit linking
|
|
step.</li>
|
|
<li>Compile Duktape as a static library, and link the static library with
|
|
your program.</li>
|
|
<li>Compile Duktape as a dynamic library, and link the dynamic library with
|
|
your program.</li>
|
|
<li>Compile Duktape as a dynamic library, install it system-wide, and use it
|
|
from several applications; see
|
|
<a href="https://github.com/svaarala/duktape/blob/master/doc/system-install.rst">system-install.rst</a>.</li>
|
|
</ul>
|
|
|
|
<p>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:</p>
|
|
<ul>
|
|
<li><b>Include <code>duktape.h</code> in application code</b>. This is
|
|
good practice in general, but without the header your compiler will
|
|
incorrectly assume that all Duktape API functions are actual functions
|
|
which will cause linking to fail.</li>
|
|
<li><b>Use the same prepared Duktape sources and headers when compiling
|
|
Duktape and your application</b>. This ensures Duktape and your application
|
|
are compiled with the exactly same Duktape version and configuration.
|
|
This is especially important when Duktape is compiled as a library in a
|
|
separate compilation step.</li>
|
|
<li><b>Use the same compiler when compiling Duktape and your application</b>.
|
|
Using a different compiler may affect e.g. type detection in the Duktape
|
|
<code>duk_config.h</code> header or function calling convention, and thus
|
|
compromise binary compatibility. In practice compilers can be mixed to
|
|
some extent, e.g. GCC and Clang are generally compatible.</li>
|
|
</ul>
|
|
|
|
<h3>Recommended compiler options</h3>
|
|
|
|
<p>Recommended compiler options for GCC/clang, use similar options for
|
|
your compiler:</p>
|
|
<ul>
|
|
<li><code>-std=c99</code>: recommended to ensure C99 semantics
|
|
which improve C type detection and allows Duktape to use variadic
|
|
macros.</li>
|
|
<li><code>-Wall</code>: recommended to catch potential issues early.</li>
|
|
<li><code>-Os</code>: optimize for smallest footprint, which is usually
|
|
desired when embedding Duktape. <code>-O2</code> is a good compromise
|
|
for performance optimized builds.</li>
|
|
<li><code>-fomit-frame-pointer</code>: omit frame pointer, further reduces
|
|
footprint but may interfere with debugging (leave out from debug builds).</li>
|
|
<li><code>-fstrict-aliasing</code>: use strict aliasing rules, Duktape
|
|
is compatible with these and they improve the resulting C code.</li>
|
|
<li>Configure.py with <code>--dll</code> is needed when Duktape is built as
|
|
a DLL, at least when compiling for Windows.</li>
|
|
</ul>
|
|
|
|
<h3>Compilation warnings</h3>
|
|
|
|
<p>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.
|
|
<code>-Wall</code> 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 <code>-Wextra</code> in gcc/clang or
|
|
<code>/W4</code> 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.</p>
|
|
|
|
<h3 id="duktape-cplusplus">Using a C++ compiler</h3>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>The <code>duktape.h</code> header contains the necessary glue to make all
|
|
of these combinations work. Specifically, all symbols needed by Duktape
|
|
public API are inside a <code>extern "C" { ... }</code> wrapper when compiled
|
|
with a C++ compiler. This ensures that such symbols are defined and used
|
|
without C++ name mangling. Specifically:</p>
|
|
|
|
<ul>
|
|
<li>When compiling Duktape itself with a C++ compiler, symbols needed by
|
|
Duktape public API are not mangled. Other Duktape internal symbols will
|
|
be mangled, but are not externally visible and should thus cause no
|
|
problems even if the application is compiled with a C compiler.</li>
|
|
<li>When compiling an application with a C++ compiler, the wrapper ensures
|
|
that Duktape public API symbols used by the application are looked up
|
|
without mangling.</li>
|
|
</ul>
|
|
|
|
<p>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:</p>
|
|
<pre>
|
|
$ 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
|
|
</pre>
|
|
|
|
<p>One fix is to use <code>g++</code> for linking:</p>
|
|
<pre>
|
|
$ 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
|
|
</pre>
|
|
|
|
<p>Because <code>duk_config.h</code> 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.</p>
|
|
|
|
<p>By default scope-based resource management (sometimes referred to as
|
|
<a href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a>)
|
|
won't work in Duktape/C functions because Duktape uses
|
|
<code>longjmp()</code> for internal long control transfers, bypassing
|
|
C++ stack unwind mechanisms. You can use <code>DUK_USE_CPP_EXCEPTIONS</code>
|
|
to cause Duktape to use C++ exceptions for internal long control transfers,
|
|
which allows scope-based resource management to work in Duktape/C functions.</p>
|
|
|