Сборка Duktape для конкретной платформы (ARM 32/ ARM 64)

Я собираюсь использовать Duktape для оценки javascript для платформ ARM 32/64. Я хочу собрать Duktape только для конкретной платформы и архитектуры, а не для всего диапазона.

Кажется, что я могу построить это успешно:

python tools/configure.py \
    --source-directory src-input \
    --platform linux \
    --architecture arm32 \
    --config-metadata config/ \
    --option-file arm32_config.yaml \
    --output-directory /tmp/arm32    

arm32_config.yaml:

DUK_USE_32BIT_PTRS: true
DUK_USE_64BIT_OPS: false 
DUK_USE_FATAL_HANDLER: false

Сборка проходит обычно. Это здорово!

На Raspberry Pi (используйте его только для тестов):

У меня есть привет.c:

 #include "duktape.h"

 int main(int argc, char *argv[]) {
   duk_context *ctx = duk_create_heap_default();
   duk_eval_string(ctx, "print('Hello world!');");
   duk_destroy_heap(ctx);
   return 0;
 }

и файл Makefile.hello:

 DUKTAPE_SOURCES = src/arm32/duktape.c

 # Compiler options are quite flexible.  GCC versions have a significant impact
 # on the size of -Os code, e.g. gcc-4.6 is much worse than gcc-4.5.

 CC = gcc
 CCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer
 CCOPTS += -I./src/arm32  # for combined sources
 CCLIBS = -lm
 CCOPTS += -DUK_USE_32BIT_PTRS
 CCOPTS += -DUK_USE_64BIT_OPS
 CCOPTS += -DUK_USE_FATAL_HANDLER

 # For debugging, use -O0 -g -ggdb, and don't add -fomit-frame-pointer

 hello: $(DUKTAPE_SOURCES) hello.c
    $(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) hello.c $(CCLIBS)

Это тоже работает!

Но когда я пытаюсь запустить программу./ Привет, я всегда получаю: Ошибка сегментации

Не могли бы вы указать на мои ошибки? Что я пропустил? Заранее спасибо!

PS: GCC версия 4.9.2 (Raspbian 4.9.2-10)

1 ответ

Основная проблема, с которой вы, скорее всего, столкнулись, заключается в том, что вы работаете с мастером Duktape (который станет версией 2.0.0), который больше не предоставляет встроенную привязку "print()". Это вызывает ошибку, которая будет выброшена.

Эта ошибка необоснованна, потому что у вас нет защищенного вызова, заключающего в себе вызов eval, поэтому возникает фатальная ошибка. Так как вы не предоставляете обработчик фатальной ошибки (в duk_create_heap() или через DUK_USE_FATAL_HANDLER), который вызывает поведение фатальной ошибки по умолчанию, которое должно вызвать преднамеренную ошибку сегмента (это так, чтобы отладчик мог присоединиться).

Поэтому проще всего определить привязку print () и, возможно, добавить обработчик фатальных ошибок и / или защищенный вызов для eval. Вот пример добавления привязки print () (перед выполнением eval):

static duk_ret_t native_print(duk_context *ctx) {
    duk_push_string(ctx, " ");
    duk_insert(ctx, 0);
    duk_join(ctx, duk_get_top(ctx) - 1);
    printf("%s\n", duk_safe_to_string(ctx, -1));
    return 0;
}

/* ... before doing eval(): */
duk_push_c_function(ctx, native_print, DUK_VARARGS);
duk_put_global_string(ctx, "print");

Другие незначительные комментарии:

  • Duktape duk_config.h определяет платформу и цель, для которой вы строите; Duktape никогда не строит "для всех целей", что касается получаемого двоичного файла. Таким образом, наличие нескольких платформ в duk_config.h, к примеру, не увеличивает результат.
  • Вам не нужны значения в вашем arm32_config.yaml. ARM32 должен быть обнаружен автоматически.
  • Используемый вами Makefile.hello (адаптирован) из Duktape 1.x, а код, который вы компилируете, из Duktape master. Параметры CCOPTS будут игнорироваться мастером Duktape (они идут в tools/configure.py), и их пример неверен в примере, например -DUK_USE_FATAL_HANDLER определяет значение препроцессора UK_USE_FATAL_HANDLER,
Другие вопросы по тегам