Прошивки часто пишут в Eclipse. Главная причина- это то, что Eclipse IDE бесплатная.
В Eclipse есть такая возможность, как дымовая завеса неиспользуемых макросов препроцессора. Якобы то, что не используется в коде становится серой зоной отчуждения.
Когда макрос HAS_WATCHDOG не определён, то дымовая завеса присутствует.
Когда макрос определён, то дымка исчезает (HAS_I2C, HAS_I2S)
В чём проблема?
Проблема в том, что если Вы собираете проект самостоятельно написанными make скриптами и не используете сборку из плагинов Eclipse, то есть мышкой не прописываете макросы в настройках проекта, то текстовый редактор Eclipse не видит ни одного макроcа. Всё становится серым.
Именно этот аргумент огромная fun база Eclipse плагинов и приводит в качестве главного за Eclipse плагины. Они приводят в качестве главного достоинства в выборе системы сборки вот эту пресловутую серую дымку подсветки макросов! Да, господа. Именно так.
Якобы то, что не используется в коде становится серой зоной. И поэтому надо собирать код именно из плагинов Eclipse.
Однако управлять этой дымкой можно и из make скриптов. Сейчас покажу как именно.
Постановка задачи
Надо сделать так, чтобы в текстовом редакторе Eclipse корректно работала дымка макросов. При этом сами исходники должны собираться из самостоятельно написнных Make скриптов.
Каков план?
1--Надо каким-то образом автоматически сгенерировать *.h файл, который будет содержать перечень всех макроопределений для данной сборки. Назовём его c_defines_generated.h, которые были переданы через опции -D в make скриптах компилятору gcc.
2--В сложном, напичканном макросами файле надо вставить строчку
#include "c_defines_generated.h"
чтобы проверить подсветку макросов.
Реализация
Что надо из софта?
Утилита |
Назначение |
Адрес |
make |
утилита управления программными конвейерами |
C:\cygwin64\bin\make.exe |
cpp |
утилита вставки и авто замены текста в текстовых файлах |
C:\cygwin64\bin\cpp.exe |
eclipse |
текстовый редактор на основе виртуальной машины Java |
C:\eclipse\eclipse.exe |
sort |
Утилита для сортировки текстовых строк |
C:\cygwin64\bin\sort.exe |
У меня в make скриптах все макросы сваливаются в переменную окружения CPP_FLAGS. Надо, чтобы макро определения как-то кристаллизировались потом в одном отдельном *.h файлике.
OPT += -DHAS_CLOCK
....
CSTANDARD = -std=c99
CPP_FLAGS += $(CSTANDARD) $(INCDIR) $(OPT)
Чтобы это произошло надо обратить внимание на следующие две опции консольной утилиты препроцессора cpp.exe
Опция утилиты cpp |
Назначение опции |
Назначение опции |
-E |
Preprocess only; do not compile, assemble or link. |
Отработать только препроцессору. Не собирать не компоновать. |
-dM |
Instead of the normal output, generate a list of ‘#define’ directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. |
Генерировать список макросов для всех макросов определённых во время выполнения препроцессора. Это дает вам способ выяснить, что предопределено в вашей версии препроцессора |
Теперь понятно, что надо запрограммировать вот такой конвейер. Создать пустой файл empty_sourсe.c и прогнать его через препроцессор с отладочными ключами.
Вот полный make скрипт генерирования списка всех макро определения в виде отдельной цели generate_definitions. Эту цель легко вмонтировать в общий скрипт сборки.
.PHONY: generate_definitions
generate_definitions:
$(info GenerateDefinitions...)
$(PREPROCESSOR_TOOL) $(CPP_FLAGS) $(WORKSPACE_LOC)empty_sourse.c -dM -E> c_defines_generated.h
$(SORTER_TOOL) -u c_defines_generated.h -o c_defines_generated.h
После генерирования списка макросов его по-хорошему следует отсортировать. Для наглядности. Это делает консольная утилита sort.exe c ключом -u. Получится примерно такой заголовочный файл c_defines_generated.h
Скрытый текст
#define AT32F435ZM 1
#define AT32F435ZMT7 1
#define HAS_AT32F435ZM 1
#define HAS_AUDIO 1
#define HAS_BIN_2_STR 1
#define HAS_BIT_SWAP 1
#define HAS_BOARD 1
#define HAS_BOARD_CUSTOM 1
#define HAS_BOARD_CUSTOM_COMMANDS 1
#define HAS_HEALTH_MONITOR_PROC 1
#define HAS_HEAP 1
#define HAS_HW_TESTS 1
#define HAS_I2C 1
#define HAS_I2C2 1
...
#define __UINT16_MAX__ 0xffff
#define __UINT16_TYPE__ short unsigned int
#define __UINT32_C(c) c ## UL
#define __UINT32_MAX__ 0xffffffffUL
#define __UINT32_TYPE__ long unsigned int
#define __UINT64_C(c) c ## ULL
#d
#define __UINT_FAST8_TYPE__ unsigned int
#define __UINT_LEAST16_MAX__ 0xffff
#define __UINT_LEAST16_TYPE__ short unsigned int
#define __UINT_LEAST32_MAX__ 0xffffffffUL
#define __UINT_LEAST32_TYPE__ long unsigned int
#define __UINT_LEAST64_MAX__ 0xffffffffffffffffULL
#define __UINT_LEAST64_TYPE__ long long unsigned int
#define __UINT_LEAST8_MAX__ 0xff
#define __UINT_LEAST8_TYPE__ unsigned char
#define __WCHAR_WIDTH__ 32
#define __WINT_MAX__ 0xffffffffU
#define __WINT_MIN__ 0U
#define __WINT_TYPE__ unsigned int
#define __WINT_WIDTH__ 32
#define __arm__ 1
Остается только добавить одну строчку #include "c_defines_generated.h" и подсветка включится. Успех!
Итоги
Как видите, сборка из make настолько гибкая, что вы ограничены разве, что своей фантазией. Можно не только собирать код, но также и автоматически синтезировать список для подсветки синтаксиса.
Надеюсь, что этот текст поможет другим программистам тоже улучшить свой инструментарий.
Словарь
Акроним |
Расшифровка |
CPP |
The C PreProcessor |
GCC |
GNU Compiler Collection |
Ссылки
Комментарии (19)
devprodest
28.08.2024 17:32+1Все это делается одной простой настройкой и все ваши самописные мэйкфайлы и константы из них подтягиваются и нормально отображаются а редакторе.
Под капотом эклипс делает тихую пустую сборку и уже на основе этого отображает верно.
Не нужно изобретать, нужно уметь пользоваться инструментом который выбрал.
Но, на мой взгляд, эклипс сейчас наихудший выбор для писанины кода.
aabzel Автор
28.08.2024 17:32Все это делается одной простой настройкой и все ваши самописные мэйкфайлы и константы из них подтягиваются и нормально отображаются а редакторе.
Как говорится: "Ровно было на бумаге.... "
Вот попробуйте сами написать инструкцию как это сделать без cpp.exe.
С удивлением для себя обнаружите, что не так всё просто.devprodest
28.08.2024 17:32Открываете настройки проекта и настраиваете провайдеры для препроцессора.
Отметил только тот который реализует функционал вашей статьи. Остальное тоже посмотрите, думаю пригодится.
aabzel Автор
28.08.2024 17:32Не факт, что Eclipse всё правильно распарсит. А мой метод гарантирует положительный результат.
Да и потом. Зачем привязываться к Eclipse? Дымка макросов наверняка присутствует и в других текстовых редакторах. Мой метод с ключами cpp гарантирует положительный результат везде.
devprodest
28.08.2024 17:32+2Да делайте, что хотите, изобретайте кучу странных скриптов и практик. Я вам показал путь без извращений, дальше сами.
Проблема с отображением затененных кусков кода это чисто проблема эклипса, в нем и нужно её решать.
aabzel Автор
28.08.2024 17:32Но, на мой взгляд, эклипс сейчас наихудший выбор для писанины кода.
А что лучше?
devprodest
28.08.2024 17:32+1Мне нравится vscode. Но в основном из-за его легкости, расширяемости и универсальности (один редактор для всего), удобством настроек в текстовом файле, а не монструозном ui
К тому же для vscode легко пишутся собственные расширения, что сильно подкупает.
Не призываю использовать, просто делюсь мнением.
Gay_Lussak
А можете подробно объяснить приемущества Eclipse + make, вместо того же CMake + VSCode/Qt?
aabzel Автор
Для меня Eclipse это просто пишущая машинка , не более.
А вот система сборки -это важный момент. Главное чтобы система сборки была на основе скриптов.
Все подробности тут.
https://habr.com/ru/articles/723054/
Gay_Lussak
Прочитал, приемуществ так и не увидел. Опять же, я наверное уже не мог всерьез читать после фраз про то как IDE отжирают много ресурсов.
rukhi7
Система сборки вроде всегда и везде была на основе скриптов. Например раньше самым распространенным языком скрипта был MAKEFILE. Разница только в том как вы этот скрипт формируете через визуальный интерфейс IDE или вручную пишете без всяких правил на своем любимом скриптовом языке или вообще сразу на нескольких языках.
Или я что то не правильно понял?
aabzel Автор
Эх если бы. В России мало кто знает языки make, ninjia, Cmake.
Поэтому часто Cи-код собирают в GUI-IDE с плагинами (IAR, Keil, CCS, ARM плагины Eclipse) и вместо скриптов щелкаю мышкой в оконных настройках GUI.
Вот отдельный текст про это.
aabzel Автор
Make много проще, чем CMake.
randomsimplenumber
А ассемблер проще чем питон ;)
aabzel Автор
Но на Python, тем не менее, не программируют микроконтроллеры.
randomsimplenumber
Вы не поверите.. ;)
rukhi7
это вряд ли, вы попробуйте написать программу для сложения двух чисел на питоне и на ассемблере. Хотя возможно в некотором смысле CMake все таки проще чем Make. Разве CMake не для того сделали чтобы жизнь была проще?
aabzel Автор
Нет, CMake сделали для подстройки под разные системы сборки.
Так как Cmake, в зависимости от опций, может генерить либо make, либо ninja, либо IDE проект.
Поэтому CMake получился очень сложным.
randomsimplenumber
Язык простой, но писать на нем не очень просто.