G ++ не компилирует мой исходный код с -O0, но с -O2 -DNDEBUG, как я могу это решить? - PullRequest
1 голос
/ 12 января 2012

Пишу прошивку для ARM микроконтроллера. Я создал кросс-компилятор без системных вызовов, фактически моя ОС RTOS (ChibiOS) обеспечивает простую реализацию системных вызовов.

Весь мой код написан на C, за исключением некоторых частей, где я использую только C ++ для связи с библиотекой Eigen (библиотека шаблонов C ++ для линейной алгебры, это только заголовки).

Если я скомпилирую исходный код с помощью -O2 -DNDEBUG (насколько я знаю с NDEBUG, код не требует assert ()), все скомпилируется нормально, и прошивка работает.

Если я скомпилировал исходный код примера с -O0, у меня будет следующее:

Linking build/ch.elf
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2    /../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-abort.o): In function `abort':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb /cortex-m4/newlib/libc/stdlib/../../../../../../../gcc-4.6.2/newlib/libc/stdlib  /abort.c:63: undefined reference to `_exit'
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-signalr.o): In function `_kill_r':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb/cortex-m4/newlib/libc/reent/../../../../../../../gcc-4.6.2/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-signalr.o): In function `_getpid_r':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb/cortex-m4/newlib/libc/reent/../../../../../../../gcc-4.6.2/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
collect2: ld returned 1 exit status
make: *** [build/ch.elf] Error 1

Неважно, если я поставлю -DNDEBUG, у меня такой же вывод. Я также использую эти флаги, -fno-exception и fno-rtti. Если я не использую / не связываю библиотеку Eigen (единственное, что есть в C ++), g ++ прекрасно компилирует исходный код даже с -O0.

На самом деле, я реализовал простые функции _kill _getpid и _exit, и код компилируется, но код переходит от 13 КБ к 130 КБ, и он вылетает (возможно, я плохо написал эти функции).

Что я хочу, это удалить этот материал из моего кода (прервать и т. Д.), Если я использую -O0, как это делается (я думаю) с -O2.

Большое спасибо. Дайте мне знать, если вам нужна дополнительная информация.

Ответы [ 2 ]

5 голосов
/ 12 января 2012

Эти ссылки почти наверняка связаны с использованием assert(); это вызовет abort() в случае сбоя, который, в свою очередь, попытается подать сигнал (используя системный вызов kill() в этой реализации), чтобы прервать процесс. Очевидно, что это невозможно, если вы не можете делать системные вызовы.

Сборка с -DNDEBUG (как вы делаете в оптимизированной версии) исправит это; он заставляет макрос assert() не генерировать код, поэтому ссылки на abort() не будут. Сам уровень оптимизации не должен иметь никакого значения.

В качестве альтернативы, если вы хотите сохранить свои утверждения, вы можете реализовать свой собственный макрос assert(), который не требует никаких системных вызовов.

1 голос
/ 12 января 2012

Вы можете просто реализовать заглушки для этих отсутствующих системных вызовов и связать их с вашим кодом.Это будет держать компоновщик тихим, но вы можете заставить заглушки делать что-то разумное или полезное.exit () может отключить прерывания и выполнять бесконечный цикл или вызвать сброс._kill () может подключиться к вашей ОСРВ для завершения потока или просто вызвать _exit (), а _getpid () может вернуть какое-то фиктивное значение или идентификатор потока RTOS.

...