Автоматическое Выравнивание Отступов в Исходниках (clang-format + Make)
Есть такая утилита для автоматического выравнивания отступов в исходных кодах. Называется clang-format.exe. Надо признать, что сейчас де факто основной утилитой автоматического выравнивания отступов является именно утилита clang-format.exe изLLVM. Её достоинство в том что ей всё равно в каком текстовом редакторе вы пишите код. Что в Eclipse, что Notepad++, что MS Visual Code. Сlang-format он выровняет всё, что ему подадут на вход в соответствии с указанным конфигом в опциях командной строки.
Есть еще тоже консольный GNU indent, однако indent очень устарел и слаб. Плюс падает от обнаружения препроцессора.
Почему обычно делают форматирование отступов в исходниках?
На то я вижу минимум три причины:
1--Для однообразности и красоты. В каждой российской компании свой собственный, внутренний, ни на кого больше не похожий стандарт оформления исходных текстов программ на Си. Причем отличается обычно на 80%…90% от других организаций.
2--Чтобы был минимальный diff при сравнении разных по времени версий одного и того же куска Си кода
3--Чтобы можно было составлять простые и предсказуемые регулярные выражения для поиска шаблонов кусков кода утилитой grep и find в репозитории с кодом.
В чем проблема?
Проблем тут две:
1--Первая проблема в том, что вручную выставлять отступы это очень утомительно и рутинно. Однако эта проблема решается, как раз, утилитами автоматического выставления отступов.
2--Вторая проблема в том, что для автоматического форматирования кода утилитами приходится составлять *.bat файл и явно прописывать внутри какой файл надо форматировать. Это тоже очень рутинно с учетом, что файлов в сборке порядка нескольких сотен. Вот у меня типичная сборка собирает 237 с-файликов. И что, мне прописывать 237 строчки в bat файле что ли?
Очевидно же, что надо как-то автоматизировать процесс прогона с-файлов через утилиту форматировщик clang-format.
Решение
Попробуем запустить clang-format автоматически из скриптов сборки. Проще говоря, надо вмонтировать утилиту автоматического выравнивания прямо в систему сборки прошивки.
Что надо из софта?
# | Название утилиты | Назначение |
1 | grep | рекурсивный поиск по файловой системе |
2 | sed | утилита авто замены ключевых слов в файлах |
3 | make | утилита управления системой сборки |
4 | clang-format | утилита автоматического выравнивания исходных кодов |
Можно написать отдельный make файл для вызова этой утилиты. Вот по такой схеме.
Вот такой Make скрипт сам производит выравнивание тех же самых файлов, что участвовали в сборке прошивки.
$(info ClangFormatScript)
CLANG_FORMAT_TOOL =C:/cygwin64/bin/clang-format.exe
SOURCES_CF := $(subst .c,.cf, $(SOURCES_C))
#$(error SOURCES_CF=$(SOURCES_CF))
MCAL_STYLE="{
MCAL_STYLE+= BreakBeforeBraces: Attach,
MCAL_STYLE+= ColumnLimit: 120,
MCAL_STYLE+= IndentWidth: 4,
MCAL_STYLE+= PointerAlignment: Left,
MCAL_STYLE+= SortUsingDeclarations: true,
MCAL_STYLE+= SpaceBeforeParens: Never,
MCAL_STYLE+= SortIncludes: true,
MCAL_STYLE+= TabWidth: 4,
MCAL_STYLE+= UseTab: Never,
MCAL_STYLE+=}"
#$(error MCAL_STYLE=$(MCAL_STYLE))
%.cf: %.c
$(info RunClangFormat)
$(CLANG_FORMAT_TOOL) -verbose -i -style=$(MCAL_STYLE) $<
.PHONY: clang_format
clang_format: $(SOURCES_CF)
$(info ClangFormatDone)
Однако есть один момент. Не все файлы исходников следует подвергать автоматическому выравниванию. Дело в том, что если ты меняешь форматирование в файле, то ты, как бы, автоматически становишься владельцем этого кода. Оно тебе надо? Ты же не хочешь нести ответственность за этот странный чужой код просто потому, что ты там поменял TAB на 4 пробела? Поэтому существует такое негласное правило буравчика:
Ни в коем случае нельзя менять форматирование в чужом коде!
Очевидно, что в скриптах сборки надо как-то пометить те файлы сорцов, которые мы не будем форматировать. А в системе сборки make сделать это очень просто. Надо всего-навсего проиндексировать чужие сорцы в переменную окружения SOURCES_THIRD_PARTY_C.
ifneq ($(FAT_FS_MK_INC),Y)
FAT_FS_MK_INC=Y
FAT_FS_DIR += $(THIRD_PARTY_DIR)/fat_fs
#@echo $(error FAT_FS_DIR= $(FAT_FS_DIR))
INCDIR += -I$(FAT_FS_DIR)
INCDIR += -I$(FAT_FS_DIR)/src
INCDIR += -I$(FAT_FS_DIR)/src/options
SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/diskio.c
#SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/option/unicode.c
SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/option/ccsbcs.c
SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/ff.c
endif
Если лень это производить вручную, то можно применить этот bash скрипт
grep -rl SOURCES_C . | xargs sed -i 's/SOURCES_C/SOURCES_THIRD_PARTY_C/g'
Далее в rules.mk просуммировать те сорцы, которые мы форматируем SOURCES_C и те, которые мы не форматируем SOURCES_THIRD_PARTY_C в одну переменную окружения SOURCES_TOTAL_C
SOURCES_TOTAL_C += $(SOURCES_C)
SOURCES_TOTAL_C += $(SOURCES_THIRD_PARTY_C)
SOURCES_TOTAL_C := $(subst /cygdrive/c/,C:/, $(SOURCES_TOTAL_C))
Вот так получается, что THIRD PARTY код останется без изменений. Всё что надо — это открыть папку с проектом из консоли и набрать
make clang_format
Все нужные с-файлы станут с выровненными отступами. Автоматически…
Итоги
Как видите, сборка из скриптов (в частности make) дает такие преимущества как автоматическое выравнивание отступов исходного кода. Удалось встроить утилиту clang-format в основной конвейер сборки прошивки.
Словарь
акроним | расшифровка |
LLVM | Low Level Virtual Machine |
bash | Bourne again shell |
GNU | GNU«s Not UNIX |
sed | Stream EDitor |
grep | search Globally for lines matching the Regular Expression, and Print them |
Ссылки