Существуют ли особые флаги компилятора, чтобы использовать gcc sync-builtins при кросс-компиляции для arm? - PullRequest
0 голосов
/ 15 октября 2019

Я пытаюсь кросс-компилировать программу, которая использует встроенные gcc, специфические __sync_val_compare_and_swap, __sync_add_and_fetch и sync_sub_and_fetch. Компиляция работает, но компоновщик показывает мне неопределенные ошибки ссылок. Например:

memory_layout.c:(.text.memory_uniqueid+0x1c): undefined reference to '__sync_val_compare_and_swap_4'
memory_layout.c:(.text.ipc_counter+0x18): undefined reference to '__sync_add_and_fetch_4'

Я использую набор инструментов st-gnu-arm-gcc-7-2018-q2-update_gdb-5_4-2016q3, который поставляется с eclipse и SW4STM32. Мой хост-компьютер - 64-битный Linux Mint. Программа построена с использованием CMake.

Необходимые функции определены в файле цепочки инструментов lib / gcc / arm-none-eabi / 7.3.1 / plugin / include / sync-builtins.def.

Я искал похожие ошибки, но предоставил решение (используйте -march = i486), но это не помогло. Другой обходной путь, который я нашел, состоит в том, чтобы скомпилировать необходимые функции в собственной библиотеке (http://vincesoft.blogspot.com/2012/04/how-to-solve-undefined-reference-to.html), но, похоже, это для более старых версий gcc.

Я также пытался вручную связать libgcc (который поставляется с набором инструментов), но безуспешно. Используются следующие команды:

add_library(GCC_LIB STATIC IMPORTED /home/toolchains/st-gnu-arm-gcc-7-2018-q2-update_gdb-5_4-2016q3/lib/gcc/arm-none-eabi/7.3.1/libgcc.a)
target_link_libraries(${PROJECT_NAME} ${GCC_LIB})

ошибка вызвана следующей функцией

static inline unsigned int atomic_inc(unsigned int v)
{
    /* atomic load, modify, store */
    return __sync_add_and_fetch(v, 1);
}

Нужно ли предоставлять некоторые специальные флаги компилятора или определять так встроенные функцииможно связать?

1 Ответ

0 голосов
/ 15 октября 2019

Как отметил @KamiCuk, мне пришлось самостоятельно реализовать необходимые функции. Функции disable_intterrups () и enable_interrupts () в его комментарии зависят от ОС. Когда я компилировал для Freertos, я использовал portENTER_CRITICAL и portEXIT_CRITICAL. Окончательное решение для __sync_add_and_fetch_4 выглядело так:

__sync_add_and_fetch_4(unsigned *v, unsigned add, ...) { 
portENTER_CRITICAL(); 
const unsigned ret = *v;
*v += add; 
portEXIT_CRITICAL(); 
return ret; }

Некоторые атомарные операции уже предоставлены заголовками FreeRTOS (atomic.h).

...