diff options
author | Jimmy Huang <jimmy.huang@intel.com> | 2018-02-01 10:54:42 -0800 |
---|---|---|
committer | Geoff Gustafson <geoff@linux.intel.com> | 2018-05-18 15:50:27 -0700 |
commit | 3ec5b47a6a72170e8ab57e0155b048fe09219dca (patch) | |
tree | a07d859ca3ebcab98df597801121f96d099bb030 | |
parent | 0f1ca5424d85131fd488b1baa9b8a3daa4fbafa8 (diff) |
[debugger] Added debugger support for Zephyr
Created shim layer for building against the POSIX network stack on
Zephyr which enables the debugger to run on the frdm_k64f board with
TCP IPV4 on port 5001.
Signed-off-by: Jimmy Huang <jimmy.huang@intel.com>
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | README.md | 47 | ||||
-rw-r--r-- | cmake/jerry.cmake | 22 | ||||
-rw-r--r-- | cmake/zjs.cmake | 45 | ||||
-rw-r--r-- | cmake/zjs_linux.cmake | 19 | ||||
-rwxr-xr-x | scripts/convert.py | 19 | ||||
-rwxr-xr-x | scripts/trlite | 8 | ||||
-rw-r--r-- | src/jerry-port/arpa/inet.h | 20 | ||||
-rw-r--r-- | src/jerry-port/zjs_jerry_port.c | 37 | ||||
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/zjs_common.h | 6 | ||||
-rw-r--r-- | src/zjs_console.c | 19 | ||||
-rw-r--r-- | src/zjs_debugger.json | 34 | ||||
-rw-r--r-- | tools/Makefile.snapshot | 2 |
14 files changed, 250 insertions, 60 deletions
@@ -10,6 +10,7 @@ OS := $(shell uname) BOARD ?= arduino_101 +SCRIPT_SIZE ?= 8192 RAM ?= 64 ROM ?= 144 V ?= 0 @@ -37,9 +38,11 @@ $(error ZJS_BASE not defined. You need to source zjs-env.sh) endif ifeq ($(DEBUGGER), on) -ifneq ($(BOARD), linux) -$(error Debugger only runs on linux, set BOARD=linux) +ifneq (,$(filter $(MAKECMDGOALS), linux arduino_101)) +$(error Debugger only runs on linux and arduino_101) endif +# debugger requires unminimized JS which will require much a larger script size +SCRIPT_SIZE = 16384 ifneq ($(SNAPSHOT), on) $(warning Debugger on, disabling snapshot) SNAPSHOT=off @@ -120,6 +123,8 @@ else SNAPSHOT ?= on endif +ZJS_FLAGS += -DMAX_SCRIPT_SIZE=$(SCRIPT_SIZE) + ifeq ($(FUNC_NAME), on) ZJS_FLAGS += -DZJS_FIND_FUNC_NAME endif @@ -130,6 +135,11 @@ else FORCED := $(FORCE),zjs_common.json endif +ifeq ($(DEBUGGER), on) +# debugger will require networking support +FORCED := $(FORCED),zjs_debugger.json +endif + # Settings for ashell builds ifneq (,$(filter $(MAKECMDGOALS),ide ashell)) ASHELL=zjs_ashell_$(ASHELL_TYPE).json @@ -308,6 +318,7 @@ analyze: $(JS) -DBLE_ADDR=$(BLE_ADDR) \ -DBOARD=$(BOARD) \ -DCB_STATS=$(CB_STATS) \ + -DDEBUGGER=$(DEBUGGER) \ -DJERRY_BASE=$(JERRY_BASE) \ -DJERRY_OUTPUT=$(JERRY_OUTPUT) \ -DJERRY_PROFILE=$(OUT)/$(BOARD)/jerry_feature.profile \ @@ -390,9 +401,13 @@ else ifeq ($(BOARD), linux) @./scripts/convert.py $(JS) $(OUT)/include/zjs_script_gen.h else +ifeq ($(DEBUGGER), on) + @./scripts/convert.py --full $(OUT)/$(JS_TMP) $(OUT)/include/zjs_script_gen.h +else @./scripts/convert.py $(OUT)/$(JS_TMP) $(OUT)/include/zjs_script_gen.h endif endif +endif # Run QEMU target .PHONY: qemu @@ -466,6 +481,7 @@ linux: generate -DDEBUGGER=$(DEBUGGER) \ -DV=$(V) \ -DVARIANT=$(VARIANT) \ + -DZJS_FLAGS="$(ZJS_FLAGS)" \ -H. && \ make -C $(OUT)/linux; @@ -282,12 +282,48 @@ breakpoints such as `b main` and `run` to start debugging as usual with gdb. ##### Debugging JavaScript code JerryScript has a built-in remote debugger which allows debugging JavaScript programs. At the moment only a Websocket-based implementation is provided by -JerryScript which transmits messages over TCP/IP networks. This implementation -requires a socket API which currently only work when running on Linux. The -socket API is not yet supported with NewLib when building with Zephyr natively. +JerryScript which transmits messages over TCP/IP networks, but it currently +only supports ethernet, so you'll need to run it on a board that has ethernet +support, for example, the FRDM-K64F or Linux. To enable the remote debugger for a particular JS application: ```bash +make BOARD=frdm_k64f DEBUGGER=on JS=xxx.js +``` + +When you flash and run the JS application, it will start in debugging mode, +running on 192.168.1.101:5001, and you will see the following on serial output: + +```bash +Debugger mode: connect using jerry-client-ws.py + +Waiting for client connection +``` +you might need to add a route on your PC to connect to the network if you +are connecting the board directly to your PC: + +```bash +ip route add 192.168.1/24 dev eno1 +``` + +Then you can use the jerryscript command line or html client to connect to the +debugger to debug your JS application: + +python jerryscript/jerry-debugger/jerry-client-ws.py --display 10 192.168.1.1 + +In the client, type 'help' to get a list of debugger commands, such as +adding breakpoints, stepping through JS sources, etc. + +Alternatively, we've created a client that integrates with Chome DevTools, +which lets you use the Chrome's built-in debugger to connect and you can +use it to set breakpoints and step through source from all within the browser. +Please see installation instructions on how to set it up from +[here](https://github.com/jerryscript-project/jerryscript-debugger-ts) + +##### Debugging JavaScript code on Linux: + +To enable the remote debugger on Linux: +```bash make BOARD=linux DEBUGGER=on outdir/linux/release/jslinux app.js --debugger ``` @@ -296,12 +332,9 @@ It will then be run on debugger mode waiting for client connection, you can then in another terminal, you can connect to it by running the python client in JerryScript: ```bash -jerry-debugger/jerry-client-ws.py +python jerryscript/jerry-debugger/jerry-client-ws.py --display 10 localhost ``` -In the client, type 'help' to get a list of debugger commands, such as -adding breakpoints, stepping through JS sources, etc. - #### Additional details See below for a few more tips, such as increasing the space available for your diff --git a/cmake/jerry.cmake b/cmake/jerry.cmake index a504c4e..20ae4c3 100644 --- a/cmake/jerry.cmake +++ b/cmake/jerry.cmake @@ -4,12 +4,16 @@ include(ExternalProject) # Additional build flags to work around JerryScript warnings set(jerry_cflags " \ - -Wall \ - -Werror \ -Wno-conversion \ -Wno-implicit-function-declaration \ -Wno-old-style-declaration \ - -Wno-undef" + -Wno-pedantic \ + -Wno-shadow \ + -Wno-sign-compare \ + -Wno-sign-conversion \ + -Wno-undef \ + -Wno-unused-parameter \ + -Wno-unused-variable" ) zephyr_get_include_directories_for_lang_as_string(C includes) @@ -17,8 +21,15 @@ zephyr_get_system_include_directories_for_lang_as_string(C system_includes) zephyr_get_compile_definitions_for_lang_as_string(C definitions) zephyr_get_compile_options_for_lang_as_string(C options) +# include the shim layer that ports the network API to build on Zephyr +if("${DEBUGGER}" STREQUAL "on") + set(net_includes + "-I${CMAKE_SOURCE_DIR}/src/jerry-port" + ) +endif() + set(external_project_cflags - "${includes} ${definitions} ${options} ${system_includes}${jerry_cflags}" + "${includes} ${definitions} ${options} ${system_includes} ${jerry_cflags} ${net_includes}" ) if("${SNAPSHOT}" STREQUAL "on") @@ -33,10 +44,11 @@ set(CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_COMPILER_WORKS=TRUE -DCMAKE_SYSTEM_NAME=Zephyr - -DENABLE_ALL_IN_ONE=${ALL_IN_ONE} + -DENABLE_ALL_IN_ONE=OFF -DENABLE_LTO=OFF -DEXTERNAL_COMPILE_FLAGS=${external_project_cflags} -DFEATURE_ERROR_MESSAGES=ON + -DFEATURE_DEBUGGER=${DEBUGGER} -DFEATURE_INIT_FINI=ON -DFEATURE_PROFILE=${JERRY_PROFILE} -DFEATURE_SNAPSHOT_EXEC=OFF diff --git a/cmake/zjs.cmake b/cmake/zjs.cmake index 3b7ba24..953b95d 100644 --- a/cmake/zjs.cmake +++ b/cmake/zjs.cmake @@ -56,22 +56,35 @@ target_compile_options(app PRIVATE -Wno-implicit-function-declaration ) -target_include_directories(app PRIVATE ./src) -target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers) -target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-core/include) -target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-core/jrt) -target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-ext/include) -target_include_directories(app PRIVATE ${CMAKE_BINARY_DIR}/../include) - -target_sources(app PRIVATE src/main.c) -target_sources(app PRIVATE src/zjs_callbacks.c) -target_sources(app PRIVATE src/zjs_common.c) -target_sources(app PRIVATE src/zjs_error.c) -target_sources(app PRIVATE src/zjs_modules.c) -target_sources(app PRIVATE src/zjs_script.c) -target_sources(app PRIVATE src/zjs_timers.c) -target_sources(app PRIVATE src/zjs_util.c) -target_sources(app PRIVATE src/jerry-port/zjs_jerry_port.c) +set(APP_INCLUDES + ./src + ${ZEPHYR_BASE}/drivers + ${JERRY_BASE}/jerry-core/include + ${JERRY_BASE}/jerry-core/jrt + ${JERRY_BASE}/jerry-ext/include + ${CMAKE_BINARY_DIR}/../include + ) + +set(APP_SRC + src/main.c + src/zjs_callbacks.c + src/zjs_common.c + src/zjs_error.c + src/zjs_modules.c + src/zjs_script.c + src/zjs_timers.c + src/zjs_util.c + src/jerry-port/zjs_jerry_port.c + ) + +if("${DEBUGGER}" STREQUAL "on") + add_definitions(-DJERRY_DEBUGGER) + add_definitions(-DZJS_DEBUGGER) +endif() + +target_include_directories(app PRIVATE ${APP_INCLUDES}) + +target_sources(app PRIVATE ${APP_SRC}) target_link_libraries(app jerry-core jerry-ext) diff --git a/cmake/zjs_linux.cmake b/cmake/zjs_linux.cmake index 21314ef..3fe4a92 100644 --- a/cmake/zjs_linux.cmake +++ b/cmake/zjs_linux.cmake @@ -77,12 +77,8 @@ set(APP_COMPILE_OPTIONS -std=gnu99 ) -if(CB_STATS) - add_definitions(-DCB_STATS=${CB_STATS}) -endif() - -if(DEBUGGER) - add_definitions(-DZJS_DEBUGGER=${ZJS_DEBUGGER}) +if("${CB_STATS}" STREQUAL "on") + add_definitions(-DZJS_PRINT_CALLBACK_STATS) endif() if("${VARIANT}" STREQUAL "debug") @@ -141,6 +137,17 @@ if(NOT APPLE) # these flags are needed to get rid of warnings in iotivity-constrained list(APPEND APP_COMPILE_OPTIONS -Wno-pointer-sign) + + if("${DEBUGGER}" STREQUAL "on") + list(APPEND APP_INCLUDES + ${JERRY_BASE}/jerry-core/debugger + ${JERRY_BASE}/jerry-core/ecma/base + ${JERRY_BASE}/jerry-core/jmem + ${JERRY_BASE}/jerry-core/lit + ) + add_definitions(-DJERRY_DEBUGGER) + add_definitions(-DZJS_DEBUGGER) + endif() endif() # build libjerry as a static library diff --git a/scripts/convert.py b/scripts/convert.py index 284e667..df40f8b 100755 --- a/scripts/convert.py +++ b/scripts/convert.py @@ -20,10 +20,18 @@ Uglify = collections.namedtuple("Uglify", ['content', 'used_uglifyjs']) def main(): args = parse_args() - minified_result = uglifyjs(args.input) + minified_result = None + if not args.full: + minified_result = uglifyjs(args.input) + if minified_result == None: + # full JS or couldn't uglify the JS, + # return content of the file as is + fp = open(str(args.input), "r") + content = fp.read() + fp.close() + minified_result = Uglify(content, False) write_minified(args.output, minified_result) - def write_minified(output_path, minified_result): """Write the minified output, escaping things as necessary @@ -61,6 +69,7 @@ def uglifyjs(input_path): :param input_path: A pathlib.Path() object of the input file. :returns: An Uglify() object """ + filename = str(input_path) # NOTE(jlvillal): The docs say that '-nc' is the same as '--no-copyright' # but in testing it is not. @@ -73,8 +82,8 @@ def uglifyjs(input_path): try: result = subprocess.call(cmd_line, stdout=subprocess.DEVNULL) except FileNotFoundError: - # We don't have uglifyjs, so return the contents of the file - return Uglify(input_path.read_text(), False) + # We don't have uglifyjs + return None if result == 0: # We have newer uglifyjs @@ -96,6 +105,8 @@ def parse_args(): "a C string format.")) parser.add_argument("input", metavar='INPUT_FILE') parser.add_argument("output", metavar='OUTPUT_FILE') + parser.add_argument("-f", "--full", help="Skip minimizing JS for debugging", + action="store_true") args = parser.parse_args() # Make all paths absolute and expand any "~/" usage. for arg_name in ('input', 'output'): diff --git a/scripts/trlite b/scripts/trlite index 7691ee2..cd68116 100755 --- a/scripts/trlite +++ b/scripts/trlite @@ -332,6 +332,11 @@ if [ "$RUN" == "all" -o "$RUN" == "2" ]; then write_modules_test $TMPFILE $MODULES $SENSORS try_command "k64f net" make $VERBOSE JS=$TMPFILE ROM=256 BOARD=frdm_k64f + # debugger test + MODULES=(buffer) + write_modules_test $TMPFILE $MODULE + try_command "k64f debugger" make $VERBOSE JS=$TMPFILE ROM=256 BOARD=frdm_k64f DEBUGGER=on + # OCF test echo "var ocf = require('ocf');" > $TMPFILE echo "var client = ocf.client;" >> $TMPFILE @@ -450,6 +455,9 @@ if [ "$RUN" == "all" -o "$RUN" == "3" ]; then # linux build tests try_command "linux" make $VERBOSE BOARD=linux + # linux debugger tests + try_command "linux debuger" make $VERBOSE BOARD=linux DEBUGGER=on + # linux unit tests try_command "unit tests" ./outdir/linux/release/jslinux --unittest diff --git a/src/jerry-port/arpa/inet.h b/src/jerry-port/arpa/inet.h new file mode 100644 index 0000000..1e4ff15 --- /dev/null +++ b/src/jerry-port/arpa/inet.h @@ -0,0 +1,20 @@ +// Copyright (c) 2018, Intel Corporation. + +// Zephyr network stack port +// JerryScript debugger includes <arpa/inet.h> but Zephyr has different headers + +#include <sys/fcntl.h> +#include <net/socket.h> + +#define SOL_SOCKET (1) +#define SO_REUSEADDR (201) + +#define setsockopt(sd, level, optname, optval, optlen) 0 + +char addr_str[NET_IPV4_ADDR_LEN]; + +#define socket(domain, type, protocol) socket(domain, type, IPPROTO_TCP) + +inline char *inet_ntoa (struct in_addr addr) { + return net_addr_ntop(AF_INET, &addr, addr_str, sizeof(addr_str)); +} diff --git a/src/jerry-port/zjs_jerry_port.c b/src/jerry-port/zjs_jerry_port.c index eaf59e0..a81432a 100644 --- a/src/jerry-port/zjs_jerry_port.c +++ b/src/jerry-port/zjs_jerry_port.c @@ -4,6 +4,11 @@ #include "jerryscript-port.h" #include <stdarg.h> +#ifdef ZJS_LINUX_BUILD +#include <unistd.h> +#else +#include <zephyr.h> +#endif // Stubbed out functions for jerry-port features @@ -24,19 +29,31 @@ void jerry_port_fatal(jerry_fatal_code_t code) while (1) {}; } -void jerry_port_console(const char *fmat, ...) +void jerry_port_console(const char *format, ...) { - va_list va; - va_start(va, fmat); - vprintf(fmat, va); - va_end(va); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); } -void jerry_port_log(jerry_log_level_t level, const char *fmat, ...) +void jerry_port_log(jerry_log_level_t level, const char *format, ...) { (void)(level); - va_list va; - va_start(va, fmat); - vprintf(fmat, va); - va_end(va); + va_list args; + va_start(args, format); +#ifdef JERRY_DEBUGGER + char buffer[256]; + int length = 0; + length = vsnprintf(buffer, 255, format, args); + buffer[length] = '\0'; + fprintf (stderr, "%s", buffer); + jerry_char_t *jbuffer = (jerry_char_t *)buffer; + jerry_debugger_send_output(jbuffer, + (jerry_size_t)length, + (uint8_t)(level + 2)); +#else /* If jerry-debugger isn't defined, libc is turned on */ + vfprintf(stderr, format, args); +#endif /* JERRY_DEBUGGER */ + va_end(args); } @@ -31,6 +31,7 @@ // JerryScript includes #include "jerryscript.h" +#include "jerryscript-port.h" // Platform agnostic modules/headers #include "zjs_callbacks.h" @@ -71,7 +72,12 @@ static bool ashell_mode = false; #endif #ifdef ZJS_DEBUGGER +#ifdef ZJS_LINUX_BUILD +// JS debugging on linux is toggled over cmdline static bool start_debug_server = false; +#else +static bool start_debug_server = true; +#endif static uint16_t debug_port = 5001; #endif @@ -189,6 +195,8 @@ int main(int argc, char *argv[]) char *script = NULL; #else const char *script = NULL; + file_name = "js.tmp"; + file_name_len = strlen("js.tmp"); #endif jerry_value_t code_eval; u32_t script_len = 0; @@ -279,6 +287,7 @@ int main(int argc, char *argv[]) #ifdef ZJS_DEBUGGER if (start_debug_server) { + ZJS_PRINT("Debugger mode: connect using jerry-client-ws.py\n\n"); jerry_debugger_init(debug_port); } #endif @@ -304,9 +313,6 @@ int main(int argc, char *argv[]) #ifdef ZJS_SNAPSHOT_BUILD result = jerry_exec_snapshot(snapshot_bytecode, snapshot_len, false); #else -#ifdef ZJS_DEBUGGER - ZJS_PRINT("Debugger mode: connect using jerry-client-ws.py\n"); -#endif result = jerry_run(code_eval); #endif diff --git a/src/zjs_common.h b/src/zjs_common.h index 390ba31..1386c5e 100644 --- a/src/zjs_common.h +++ b/src/zjs_common.h @@ -124,12 +124,6 @@ int zjs_get_ms(void); #define LPRINT(str) do {} while (0) #endif -// TODO: We should instead have a macro that changes in debug vs. release build, -// to save string space and instead print error codes or something for release. - -// this is arbitrary but okay for now; added to avoid plain strlen below -#define MAX_SCRIPT_SIZE 8192 - // board-specific #if defined(CONFIG_BOARD_ARDUINO_101) || defined(CONFIG_BOARD_ARDUINO_101_SSS) #define ADC_DEVICE_NAME "ADC_0" diff --git a/src/zjs_console.c b/src/zjs_console.c index 3548973..852c51b 100644 --- a/src/zjs_console.c +++ b/src/zjs_console.c @@ -12,6 +12,10 @@ #include "zjs_zephyr_port.h" #endif +#ifdef JERRY_DEBUGGER +#include "debugger.h" +#endif + #define MAX_STR_LENGTH 256 #ifdef ZJS_LINUX_BUILD @@ -118,17 +122,29 @@ static void print_value(const jerry_value_t value, FILE *out, bool deep, if (!value2str(value, buf, MAX_STR_LENGTH, quotes) && deep) { if (jerry_value_is_array(value)) { u32_t len = jerry_get_array_length(value); +#ifdef JERRY_DEBUGGER + jerry_debugger_send_output((jerry_char_t *)"[", 1, JERRY_DEBUGGER_OUTPUT_OK); +#endif fprintf(out, "["); for (int i = 0; i < len; i++) { if (i) { +#ifdef JERRY_DEBUGGER + jerry_debugger_send_output((jerry_char_t *)", ", 2, JERRY_DEBUGGER_OUTPUT_OK); +#endif fprintf(out, ", "); } ZVAL element = jerry_get_property_by_index(value, i); print_value(element, out, false, true); } +#ifdef JERRY_DEBUGGER + jerry_debugger_send_output((jerry_char_t *)"]", 1, JERRY_DEBUGGER_OUTPUT_OK); +#endif fprintf(out, "]"); } } else { +#ifdef JERRY_DEBUGGER + jerry_debugger_send_output((jerry_char_t *)buf, strlen(buf), JERRY_DEBUGGER_OUTPUT_OK); +#endif fprintf(out, "%s", buf); } } @@ -138,6 +154,9 @@ static ZJS_DECL_FUNC_ARGS(do_print, FILE *out) for (int i = 0; i < argc; i++) { if (i) { // insert spaces between arguments +#ifdef JERRY_DEBUGGER + jerry_debugger_send_output((jerry_char_t *)" ", 1, JERRY_DEBUGGER_OUTPUT_OK); +#endif fprintf(out, " "); } print_value(argv[i], out, true, false); diff --git a/src/zjs_debugger.json b/src/zjs_debugger.json new file mode 100644 index 0000000..8c753ef --- /dev/null +++ b/src/zjs_debugger.json @@ -0,0 +1,34 @@ +{ + "module": "debugger", + "depends": ["net_config_default"], + "virtualdeps": ["net-l2"], + "zephyr_conf": { + "all": [ + "CONFIG_INIT_STACKS=y", + "CONFIG_NETWORKING=y", + "CONFIG_NET_APP_SETTINGS=y", + "CONFIG_NET_IPV4=y", + "CONFIG_NET_IPV6=y", + "CONFIG_NET_TCP=y", + "CONFIG_NET_UDP=y", + "CONFIG_NET_SOCKETS=y", + "CONFIG_NET_SOCKETS_POSIX_NAMES=y", + "CONFIG_NET_STATISTICS=y", + "CONFIG_PRINTK=y", + "CONFIG_TEST_RANDOM_GENERATOR=y" + ], + "frdm_k64f": [ + "CONFIG_NET_APP_NEED_IPV4=y", + "CONFIG_NET_APP_NEED_IPV6=y", + "CONFIG_NET_APP_MY_IPV4_ADDR=\"192.168.1.1\"", + "CONFIG_NET_APP_MY_IPV6_ADDR=\"2001:db8::1\"", + "CONFIG_NET_MAX_CONTEXTS=10" + ] + }, + "zjs_config": [ + "-I${JERRY_BASE}/jerry-core/ecma/base", + "-I${JERRY_BASE}/jerry-core/jmem", + "-I${JERRY_BASE}/jerry-core/lit", + "-I${JERRY_BASE}/jerry-core/debugger" + ] +} diff --git a/tools/Makefile.snapshot b/tools/Makefile.snapshot index eb0242a..5ee644b 100644 --- a/tools/Makefile.snapshot +++ b/tools/Makefile.snapshot @@ -81,7 +81,7 @@ snapshot_copy: .PHONY: snapshot snapshot: setup snapshot_copy $(BUILD_OBJ) @echo "Building for snapshot $(BUILD_OBJ)" - cd deps/jerryscript; python ./tools/build.py --builddir=build $(JERRY_FLAGS) $(VERBOSE); + cd deps/jerryscript; python ./tools/build.py --builddir=build --jerry-libc=off $(JERRY_FLAGS) $(VERBOSE); gcc $(SNAPSHOT_INCLUDES) $(JERRY_LIB_PATH) -o $(BUILD_DIR)/snapshot $(BUILD_OBJ) $(SNAPSHOT_FLAGS) $(CFLAGS) $(SNAPSHOT_DEFINES) $(SNAPSHOT_LIBS) .PHONY: clean |