Pull to refresh

Почему важно собирать код из скриптов

Level of difficultyEasy
Reading time17 min
Views13K

В период с 199x по 202x на территории РФ развелось порядка двадцати тысяч программистов-микроконтроллеров, которые никогда в своей жизни не вылазили из всяческих GUI IDE (IAR, KEIL, Code Composer Studio, Atolic True Studio, CodeVision AVR, Segger Embedded Studio и прочие). Как по мне, дак это очень печально. Во многом потому, что специалист в Keil не сможет сразу понять как работать в IAR и наоборот. Другие файлы для настроек компоновщика. Другая xml настройки проекта. Миграция на другую IDE тоже вызывает большую трудность, так как это сводится к мышковозне в IDE-GUI. Каждая версия IAR не совместима с более новой версией IDE.

Это как если пилот летавший на Boeing 737 не сможет понять, как управлять AirBus A320 и наоборот. Там другой HMI. Нет штурвала, мониторы не на том месте и прочее. Всё как-то непривычно.

Дело в том, что GUI IDE появились в 199x...201x, когда не было расцвета DevOps(а), программист работал один и все действия выполнялись вручную. Мышкой. В то время работа в GUI казалась программистам-микроконтроллеров веселее, ведь в IDE много стразиков.

Но с усложнением кодовой базы, с увеличением сборок, с увеличением команд разработчиков появилась нужда в переиспользовании кода, нужда в автосборках, в авто тестах. Появилась методология

код отдельно, конфиги отдельно

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

Это мнение не оригинальное и уже много раз звучало в сообществе.

Подробнее про гаражный колхоз сборки из-под GUI-IDE можно почитать тут: Почему сборка из-под IDE это тупиковый путь

Какие недостатки сборки исходников из-под IDE?

  1. IDE монолитные и неделимые. Если Вы захотите поменять какую-то часть ToolChain(а): препроцессор, компилятор или компоновщик, а остальные фазы ToolChain(а) оставить как есть, то ничего из этого у вас не выйдет, так как капот IDE наглухо закрыт на замок.

  2. IDE стоят дорого, порядка 3500 EUR на один компьютер. Это лишняя дань и оброк для вашей компании. Оно вам надо?

    Cтоимость IAR 3690 EUR
    Cтоимость IAR 3690 EUR
  3. IDE(шные) xml очень слабо документированы или не документированы вовсе. У всех вендоров xml имеет свой особенный снобский xml-like язык разметки для конфигурации проекта. При внесении незначительных изменений появляется огромный git diff.

    Добавил в дерево IDE ссылку на одну папочку. Получился такой diff. Как думаете сколько часов его будут review(вить) ? Ответ: в среднем две недели
    Добавил в дерево IDE ссылку на одну папочку. Получился такой diff. Как думаете сколько часов его будут review(вить) ? Ответ: в среднем две недели
  4. Затруднена сборка из консоли. В основном инициировать сборку в IDE можно мышкой или горячими клавишами. Либо надо делать refresh мышкой из-под IDE.

  5. Обратная несовместимость с новыми версиями IDE.

  6. В условиях технологического Эмбарго и Санкций законно купить IDE европейского (Германия, Швеция, США) вендора невозможно. Они вас просто пошлют, так как у них Ваша территория числится как criminal state

  7. IDE отжирают какие-никакие но ресурсы компьютера, как RAM как и CPU, IDE же надо много оперативки, чтобы отрисовывать окошки со стразиками. IAR и Code Composer, например, раз в день стабильно напрочь зависают, что помогает лишь перезагрузка розеткой.

В общем распространение IDE это яркий пример известного ныне "технологического диктата" (vendor locking) запада для низкосортных народов из стран второго и третьего мира.

Навязывание GUI-IDE (Keil, IAR, CCS, плагинов Eclipse) это форма технологического диктата со стороны стран бывших метрополий. Они привыкли столетиями помыкать своими колониями и до сих пор продвигают эту подлую циничную политику подсовывая vendor loсking средств разработки во всякие страны как Кракожия, Такистан, Элбония, Западно-Африканская республика и прочее.

Сами они там у себя этим суррогатом нелепы не пользуются. Понимаете? У них там CMake, Make, Ninja скрипты сборки и полный DevOps в Docker контейнерах. Я работал в одной английской конторе и видел это всё своими глазами.

А туземцам в СНГ они суют эту тухлую песочницу в которой только кривые куличи лепить возможно.

Мы вам продаём песочницу (IDE), а вы сидите там за бортиками, улыбаетесь и лепите свои, никому даром не нужные, куличики (прошивки-паршивки).

иллюстрация программирования микроконтроллеров в IDE
иллюстрация программирования микроконтроллеров в IDE

Понятное дело, что разработчики IDE во всю пользуются ситуацией и добавляют всяческие программные закладки, такие как слив исходников в здание с пятью углами, удаленное отключение функционала, ограничение размера выходного бинарного файла до 32kByte и всё на, что им там только хватит их извращённой фантазии!

Понятное дело, что в таких жестких рамках на "сделать что-то серьезное" туземцам рассчитывать не приходится. Сборка в IDE это всегда мелкая серия. Всегда малый ассортимент. Всегда ручное развертывание.

А когда запад нас в очередной раз кинул пришлось начать думать как теперь дальше жить... Хорошим решением оказалось сделать шаг назад в 197x 198x когда на компьютерах всё делали из консоли. Даешь сборку сорцов из скриптов! Можно вообще *.bat файл написать и он, в общем-то, инициирует запуск нужных утилит, однако исторически Си-код собирали культовой утилитой make.

Дело в том, что makefile придумали в 1976 (Stuart Feldman), тогда, когда к компьютеры были дорогие (65k USD только за несколько сотен килобайт RAM) и к компьютерам подпускали только PhD профессоров из топовых университетов мира. Поэтому и появились такие гениальнейшие утилиты как awk, make, grep, find, gdb, sed, sort, tsort, uniq, tr и прочие.

Тогда в далеких 197x у школоты в принципе не было возможности хоть как-то влиять на ход развития софта и генерировать спагетти код и программные смеси как сейчас в 200x...202x.

Сейчас же в 201x...202x какой-нибудь 43-летний Junior-embedded программист-микроконтроллеров, привыкший к GUI-IDE, может логично провозгласить:

Я вообще не представляю, как без помощи IDE и зелёного треугольника вверху производить пошаговую отладку программы?

Тут есть 4+ ответа:
1--> Использовать связку GDB Client + GDB Server и отлаживать код из командной строки.
https://habr.com/ru/post/694708/

2--> Отлаживать код через интерфейс командной строки CLI поверх UART.
https://habr.com/ru/post/694408/

3--> В коем-то веке покрывать свой код модульными тестами
https://habr.com/ru/post/698092/

4--> Использовать другие косвенные признаки отладки кода: HeartBeat LED, Утилита arm-none-eabi-addr2line.exe, Assert(ы), DAC, STM Studio (Аналог ArtMoney из GameDev(a)), Health Monitor
https://habr.com/ru/post/681280/

Почему в программировании микроконтроллеров, да ещё и в России не особо прижились скриптовые системы сборки?

Ответ прост. Прошивки это маленькие программы. Типичные *.bit(арь) 128kByte. Даже самая крупная прошивка собирается максимум за 3 мин. Её всегда можно из-под IDE собрать кликнув курсором мышки на зелёный треугольник.

А скриптовые системы сборки прежде всего изначально использовались в циклопических программных продуктах: BackEnd сайтов, DeskTop ПО, CAD системы, GameDev. Там *.exe бинари могут запросто быть по 2Gbyte и более. Да и компы в 1970....1990 слабые были, не то что сейчас. Один проект мог собираться три часа.

Естественно проектов много и собирают артефакты крупных проектов по ночам, пока программисты спят. Утром чинят ошибки компиляции, днем пилят функционал, вечером делают коммиты. Собирают автоматически дергая скрипты сборки на сервере типа Jenkins.

В чем достоинства сборки С-кода из Make файлов?

  1. Makefile это самый гибкий способ управлять модульностью кодовой базы. Можно буквально одной строчкой (например FREE_RTOS=Y) добавлять или исключать один конкретный программный компонент (десятки файлов) из десятков сборок. В случае же сборки из-под IDE вам бы пришлось вручную мышкой редактировать .xml для каждой отдельной сборки.

  2. Вы можете спросить: "А зачем запускать Eclipse из консоли? " или "Зачем в принципе командная строка?" Ответ прост... Для автоматизации. Автоматика! Слыхали про такое? Вся суть любого программирования - это и есть пресловутая автоматизация чего либо. Даже автоматические построения самих проектов. Наработка артефактов.

    А сборку из Makefile очень легко автоматизировать. Достаточно в консоли выполнить make all и у вас инициируется процесс сборки, а через 3 мин в соседней папке будут лежать артефакты.

    При сборке из скриптов у вас будет одна кнопка. Жмакнул на *.bat скрипт - получил *.bin прошивку. Жмакнул на другой *.bat скрипт - прошил плату. Ну что может быть еще проще?

    Лично я хочу чтобы после комита мои 256 сборок в репозитории собрались пока я сплю.

  3. Если сборка на скриптах, то каждый может использовать абсолютно любой текстовый редактор или IDE. В этом основное достоинство сборки из скриптов. Я вот люблю текстовый редактор в Eclipse, сосед через стол не представляет жизни без Visual Studio Code от Microsoft. Мы собирали проект на GNU Make вообще без проблем. Мы оба для построения прошивки просто кликаем на built.bat скрипт, который запускает консольную команду make all.

  4. После сборки из скриптов вы получите полный лог сборки, в то время как IDE обычно показывают последние 3-4 экрана сообщений компилятора.

  5. Дело в том, что GNU Make скрипты пишутся только один раз. Потом только лишь так косметически меняются при добавлении очередных программных компонентов.

  6. В MakeFile очень просто менять компиляторы. Это, буквально, заменить одну строчку. С GCC на Clang или на GHS. Вот типичный основной makefile для любой сборки на ARM Cortex-Mxx

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
$(info Build  $(mkfile_path) )
BUILD_DIR = build

#@echo $(error SOURCES_C= $(SOURCES_C))
INCDIR := $(subst /cygdrive/c/,C:/, $(INCDIR))
#@echo $(error INCDIR=$(INCDIR))
SOURCES_C := $(subst /cygdrive/c/,C:/, $(SOURCES_C))
#@echo $(error SOURCES_C=$(SOURCES_C))
SOURCES_ASM := $(subst /cygdrive/c/,C:/, $(SOURCES_ASM))
LIBS  := $(subst /cygdrive/c/,C:/, $(LIBS))
LDSCRIPT := $(subst /cygdrive/c/,C:/, $(LDSCRIPT))
#@echo $(error SOURCES_ASM=$(SOURCES_ASM))

# binaries
PREFIX = arm-none-eabi-
GCC_PATH="C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin"
$(info GCC_PATH=$(GCC_PATH))

# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
  CC = $(GCC_PATH)/$(PREFIX)gcc
  AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
  CP = $(GCC_PATH)/$(PREFIX)objcopy
  SZ = $(GCC_PATH)/$(PREFIX)size
else
  CC = $(PREFIX)gcc
  AS = $(PREFIX)gcc -x assembler-with-cpp
  CP = $(PREFIX)objcopy
  SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
 
# float-abi
ifeq ($(NRF5340), Y)
    ifeq ($(CORE_NET), Y)
        FLOAT-ABI = -mfloat-abi=soft
        OPT += -fsingle-precision-constant
    endif
    
    ifeq ($(CORE_APP), Y)
        FLOAT-ABI = -mfloat-abi=hard
    endif
else
   FLOAT-ABI = -mfloat-abi=hard
endif

# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
#CSTANDARD = -std=c11
CSTANDARD = -std=gnu99
# AS defines
AS_DEFS = 

# AS includes
AS_INCLUDES = 

ifeq ($(DEBUG), Y)
    #@echo $(error DEBUG=$(DEBUG))
    CFLAGS += -g3 -gdwarf-2 -ggdb
    OPT += -O0 
else
    OPT += -Os
endif
OPT += -fmessage-length=0    
OPT += -fsigned-char
OPT += -fno-common
OPT += -fstack-usage
OPT += -finline-small-functions

#Perform dead code elimination
OPT += -fdce

#Perform dead store elimination
OPT += -fdse

# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS += $(CSTANDARD)
CFLAGS += -Wall
#CFLAGS += -Wformat-overflow=1
CFLAGS += $(MCU) $(OPT) -fdata-sections -ffunction-sections $(INCDIR)  

# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"

# LDFLAGS

# libraries
LINKER_FLAGS += -Xlinker --gc-sections 
ifeq ($(MBR), Y)
    #@echo $(error MBR=$(MBR))
    LIBS += -lnosys
    LDFLAGS += -specs=nano.specs
else
    LINKER_FLAGS += -u _scanf_float
    LINKER_FLAGS += -u _printf_float
endif
#LINKER_FLAGS += -lrdimon --specs=rdimon.specs

ifeq ($(LIBC), Y)
    #@echo $(error LIBC=$(LIBC))
    LIBS += -lc
endif

ifeq ($(MATH), Y)
    #@echo $(error MATH=$(MATH))
    LIBS += -lm 
endif


#@echo $(error LDSCRIPT=$(LDSCRIPT))
LIBDIR = 

LDFLAGS += $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections $(LINKER_FLAGS)

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin


# build the application
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_C:.c=.o)))
vpath %.c $(sort $(dir $(SOURCES_C)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_ASM:.S=.o)))
vpath %.S $(sort $(dir $(SOURCES_ASM)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@	
	
$(BUILD_DIR):
	mkdir $@		

# clean up
clean:
	-rm -fR $(BUILD_DIR)
  
# dependencies
-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

5--Когда вы собираете из Make вы можете не только собирать исходники, но и

Утилите make всё равно какие консольные утилиты вызывать. Понимаете? Это универсальный способ определения программных конвейеров.

Утилиту make можно использовать не только для дирижирования процессом сборки кода программ. Утилита make может также управлять авто генерацией преобразования расширений файлов для черчения или управлять сборкой документации, управлять DevOps(ом). Make можно использовать по-разному, как только фантазии хватит. Ибо Make совершенно инвариантен и абстрагируется от языка программирования как такового.

  1. Для каждой сборки надо самим писать крохотный Makefile

MK_PATH:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
#@echo $(error MK_PATH=$(MK_PATH))
WORKSPACE_LOC:=$(MK_PATH)../../

INCDIR += -I$(MK_PATH)
INCDIR += -I$(WORKSPACE_LOC)

#@echo $(error SOURCES_C=$(SOURCES_C))
include $(MK_PATH)config.mk
include $(MK_PATH)cli_config.mk
include $(MK_PATH)diag_config.mk
include $(MK_PATH)test_config.mk

include $(WORKSPACE_LOC)code_base.mk
include $(WORKSPACE_LOC)rules.mk
 

и конфиг для сборки.


mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
$(info Build  $(mkfile_path) )

TARGET=pastilda_r1_1_generic
#@echo $(error TARGET=$(TARGET))
AES256=Y
ALLOCATOR=Y

......

USB_HOST_HS=Y
USB_HOST_PROC=Y
UTILS=Y
XML=Y

Для каждого компонента *.mk файл. Язык make простой. Он, в сущности, очень похож на bash. Вот типичный *.mk файл для драйвера UWB радио-трансивера DW1000.

ifneq ($(DWM1000_MK_INC),Y)
    DWM1000_MK_INC=Y

    DWM1000_DIR = $(DRIVERS_DIR)/dwm1000
    mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
    $(info Build $(mkfile_path) )
    $(info + DWM1000)

    INCDIR += -I$(DWM1000_DIR)
    OPT += -DHAS_DWM1000
    OPT += -DHAS_DWM1000_PROC
    OPT += -DHAS_UWB

    DWM1000_RANGE_DIAG=Y
    DWM1000_RANGE_COMMANDS=Y

    DWM1000_OTP_COMMANDS=Y
    DWM1000_OTP_DIAG=Y

    SOURCES_C += $(DWM1000_DIR)/dwm1000_drv.c

    include $(DWM1000_DIR)/otp/dwm1000_otp.mk
    include $(DWM1000_DIR)/registers/dwm1000_registers.mk

    ifeq ($(DWM1000_RANGE),Y)
        include $(DWM1000_DIR)/range/dwm1000_range.mk
    endif

    ifeq ($(DIAG),Y)
        ifeq ($(DWM1000_DIAG),Y)
            $(info +DWM1000_DIAG)
            OPT += -DHAS_DWM1000_DIAG
            SOURCES_C += $(DWM1000_DIR)/dwm1000_diag.c
        endif
    endif

    ifeq ($(CLI),Y)
        ifeq ($(DWM1000_COMMANDS),Y)
            $(info +DWM1000_COMMANDS)
            OPT += -DHAS_DWM1000_COMMANDS
            SOURCES_C += $(DWM1000_DIR)/dwm1000_commands.c
        endif
    endif
endif
  1. Параллельное написание Make файлов и С-кода стимулирует придерживаться модульности, изоляции программных компонентов и к прослеживанию зависимостей между компонентами. Если вы пишите код и make файлы примерно параллельно, то очень вероятно, что у вас получится чистый, аккуратный репозиторий сам собой.

  2. Makefile(лы) хороши тем, что можно добавить много проверок зависимостей и assert(ов) на фазе отработки Make-скриптов прямо в *.mk файлах еще до компиляции самого кода, даже до запуска препроцессора, так как язык программирования make поддерживает условные операторы и функции. Можно очень много ошибок отловить на этапе отработки утилиты make.

  3. Язык Make очень прост. Во всяком случае много проще, чем тот же CMake. Вся спека GNU Make это всего 226 страниц. Для сравнения, спецификация CMake это 429 страниц!

  4. Makefile(лы) прозрачные потому что текстовые. Всегда видно, где опции препроцессора, где ключи для компилятора, а где настройки для компоновщика. Всё, что нужно можно найти утилитой grep в той же консоли от GIT-bash даже при работе в Windows 10.

  5. Скрипты сборки GNU make (или СMake) хороши тем, что в скриптах сборки вы всегда можете написать текстовые комментарии. Вы можете рядом с каждым ключом компилятора или опцией компоновщика явно указать себе и коллегам подсказку , что это значит и для чего было нужно. Понимаете?.. Одновременно с этим в GUI-IDE нет возможности в GUI форме указать в сombo-box-e, что значит тот или иной ключ GCC. И это делает *.xml конфиг абсолютно нечитаемым.

  6. Конфиг для сборки можно формировать как раз на стадии make файлов и передавать их как ключи для препроцессора. Таким образом конфиги будут видны в каждом *.с файле проекта и не надо вставлять #include(ы) c конфигами. Всё можно передать как опции утилите cpp (препроцессора).

  7. При сборке из makefile вам вообще всё равно для какой целевой платформы собирать код прошивки. Вы можете минимальными изменениями в makefile собрать прошивку и крутить её даже на x86. Вместо UART имитировать CLI в Windows консольном приложении на PC .

    эмулятор прошивки в консольном приложении
    эмулятор прошивки в консольном приложении
  8. Внутри makefile вы можете выполнить какой-нибудь полезный скрипт. Например подписать прошивку состоянием репозитория

    GIT_SHA := $(shell git rev-parse --short HEAD)
    OPT += -DGIT_SHA=0x0$(GIT_SHA)

затем в коде написать

    LOG_INFO(SYS,"GitSha: 0x%08x", GIT_SHA);

таким образом 3мя строчками вы сделаете то, что отдельными скриптами заняло бы 50+ строк.

  1. При сборке из скриптов (например из Make) очень легко добавить новую сборку. Достаточно только написать конфиг и 3 строчки в отдельном Makefile и вот у вас новая специфическая сборка. Одновременно с этим создание новой сборки в GUI-IDE сопряжено с многочисленной мышкавозней и дублированием конфигов!

Если проводить аналогию с атомной энергетикой то, сборка через GUI-IDE - это как реакторы на горизонтальных ТВЭЛах (сборках), а сборка из скриптов это реактор на вертикальных ТВЭЛах.

Горизонтальные реакторы неудобны, так как надо минимум две точки подвеса ТВЭЛа при загрузке топлива. Плюс нужны дополнительные усилия, чтобы проталкивать стержни в активную зону. Потом стержень может расплавиться и застрять. Тогда жди большой беды.

Напротив, вертикальные ТВЭЛы загружаются под действие силы тяжести и для транспортировке сборки нужна только одна точка подвеса. А расплавленные ТВЭЛы просто стекают в поддон. Easy!

Вот еще одна аналогия... Собирать код из-под GUI-IDE (IAR KEIL) и из-под скриптов (Make/CMake) - это как писать учебники в Microsoft Word или на языке разметки LaTex. Понятное дело, что выгода LaTex появляется, когда текста становится больше чем 3 экрана. А апологеты GUI-IDE (IAR, KEIL) сложнее Hello World в своей жизни ничего не писали, поэтому и топят за GUI-IDE.

CMake или GNU Make?

СMake (Сross-platform Make) был разработан для кросс-платформенности. Переводя на кухонный язык, это чтобы одну и ту же программу можно было собирать в разнообразных операционных системах Windows, Linux, MacOS, FreeBSD. Если же Вы все в своей организации работаете только в Windows 10, то вам CMake нужен как собаке бензобак. Да.. Именно так.. Вам много проще будет самим писать GNU Make скрипты, раз нужна только сборка по клику на *.bat файл.

Потом, если вы до этого никогда не писали никаких скриптов сборки, то сразу кидаться писать CMake пожалуй тоже нет резона. Дело в том, что CMake это даже не система сборки, а надстройка над всеми возможными системами сборки: Ninja, Make и проч. Как AutoTools. СMake, в зависимости от опций командной строки, сам генерирует скрипты сборки. СMake - это всего лишь кодогенератор. И вам будет с непривычки будет архи сложно разобраться с огромным калейдоскопом разнообразных и новых для себя расширений файлов: *.сmake, СMakeList.txt. *.c.in *.mk и прочие. CMake очень навороченная и переизбыточная система.

Если у вас цель просто собирать код дергая скрипы в Jenkins, то лучше сосредоточиться на GNU Make. Тогда у вас в репозитории фактически будут только три типа файлов для версионного контроля: *.c *.h и *.mk файлы. Easy!

СMake же - это очень навороченная утилита и там много избыточного функционала. Много того, что вам никогда даже не пригодится. В случае выбора CMake вам, например, придется помимо ошибок компилятора чинить ещё ошибки отработки CMake скриптов, которые по логу порой даже понять трудно, потом чинить ошибки GNU Make, потом чинить ошибки компилятора, чинить ошибки компоновщика. Ещё CMake перед сборкой занимается тестированием компилятора. В результате долго отрабатывает скрипт. CMake работает в два прогона. Да и сами скрипты сборки make которые выращивает CMake получаются очень грязными. С душком.... Да они работают, но читать их человеку просто не-ре-аль-но....

Лучше, быстрее и надежнее просто ликвидировать лишнюю стадию отработки CMake скриптов и просто самим взять и написать лаконичные скрипты сборки GNU Make. С точки зрения DevOps результат будет абсолютно тем же: сборка из скрипта, по клику. А раз так, то зачем платить больше? Не надо слишком сильно увлекаться FrameWork(о) строительством.

В GNU Make есть всё, что нужно для полноценной автоматизации: топологическая сортировка целей, регулярные выражения, выявление не поменявшихся файлов, функции, операторы. На GNU Make решаются 99,99% всех задач по DevOps(у).

Кто еще собирает код из скриптов?
Сборку из скриптов уже оценил ряд серьезных и успешных российских организаций. Вот, например, Whoosh написал даже текст про свой опыт настройки DevOps: Сборка и отладка прошивки IoT-модуля: Python, make, апельсины и чёрная магия. Ещё Wiren Board выступали на конференции с докладом CI/CD прошивок для микроконтроллеров в Wiren Board.

Я знаю и другие компании, которые пользуются этой фундаментальной технологией, но пока не пишут про это сообществах.

Вывод

В сухом остатке, в наше время бахвалиться навыками пользования всяческими IDE должно быть уже стыдно. Надо признать, что сборка средствами GUI-IDE (IAR, CCS, KEIL, Eclipse+Plugins) - это уровень кружка робототехники 8-9го класса средней общеобразовательной школы (ГОУ СОШ).

Сборка прошивок GUI-IDE плагинами, а также из-под Keil, IAR, ССS - это признак Junior разработчика.

А сборка из скриптов - это, господа, как ни крути, но фундаментальная технология, которая по плечу только программистам с качественным опытом. Не путать с количественным опытом, когда программист-микроконтроллеров просто просиживает штаны по 11 лет на одной работе-Богодельне.

Да, написание make скриптов требует некоторого образования и сноровки, но это плата за масштабирование, автосборки, единообразие, наследование конфигов и модульность репозитория. Усилия инвестированные в изучение make окупаются сторицей!

Потом санкционные реалии таковы, что настало время, чтобы российских программистов-микроконтроллеров из детского садика под названием "GUI-IDE" перевести, наконец, в школу (т.е. приучить к makefile или хотя бы к CMake). А дальше приобщать к полноценному DevOps(у). А в идеале к чему-то типа Yocto project.

При этом надо смотреть в сторону Make, CMake. Как вариант, Ninja.

Понимаете, хорошие вещи как классика не устаревают. Вы же сами каждый день пользуетесь пуговицами... А пуговицы, между прочим, вообще в средневековье придумали... Что теперь, давайте без пуговиц ходить что-ли? Make это как пуговицы. Старая, простая и очень полезная вещь.

Сборка программ из скриптов это фундаментальная технология, величайшее достижение нашей эпохи.

Скрипты сборки Make - это как стапели, но не для корабля, а для программы.

Откровенно говоря, только тех, кто умеет собирать проекты из скриптов и можно считать настоящими программистами. А те кто как бы числится программистом и не умеет читать писать скрипты сборки, это либо самозванцы, устроившиеся на работу по блату или обыкновенная шко-ло-та. Без обид, но, что есть, то есть.

Я естественно понимаю, что это может неприятно читать такое, особенно когда тебе уже далеко за 40 и ты всегда собирал прошивки через GUI-IDE, мышкой, и ещё не осилил в своей жизни никаких систем сборок. Даже СMake. Неграмотный в вопросах систем сборки. Однако учиться никогда не поздно. Для этого есть выходные, отпуски, государственные праздники. "Дорогу осилит идущий" - так ведь говорят?

Вы же не обижаетесь на некоторые не очень приятные явления природы. Например лютый мороз, радиоактивность, молнии, цунами, торнадо, наводнения, землетрясения и прочее. Но они, как ни крути, объективно существуют и к этому надо просто приспосабливаться.

При сборке из makefile прошивки для микроконтроллеров любых vendor(ов) собираются абсолютно одинаково. Будь-то RISC-V, ST(stm32), cc26x42, AVR (atmega8), Artery, Nordic (nrf53) или spc58nn. Надо просто открыть консоль и набрать make all. Easy! Как в песенке поется: "нажми на кнопку, получишь результат, и твоя мечта осуществится!"

Когда у тебя в организации только одна, максимум 4 прошивки, то в общем-то для работы и GUI-IDE достаточно. А скрипты так, полезный ликбез. Но вот если сборок много, десятки, сотни. Что чаще всего и получается. Когда надо поддерживать на плаву прошлые проекты. Когда организация выпускает большой ассортимент продуктов и разрабатывает новые версии. То тут, друг, как ни крути, но нужны уже скрипты сборки. Да... Не зря же их придумали в своё время.

Make скрипты - это как катализатор в химии. Благодаря GNU Make всё происходит быстрее.

Есть два культовых доклада в IT конференциях, которые поясняют откуда взялся этот график. Находятся по названиям по первым ссылкам.
1--CI/CD прошивок для микроконтроллеров в Wiren Board ( начало на 25:20)
2--Конвеерум #30: Эволюция рабочего окружения для embedded разработки

Собираете свои прошивки из самостоятельно написанных make скриптов, господа, в этом нет абсолютно ничего сложного!

Links

Так как make появился ещё в 1976, то это пожалуй самая изученная тема во всем Computer Science. Материалов для ознакомления, обучения и освоения make ну просто немерено. Океан информации.

Пояснение

URL

1

Эффективное использование GNU Make

https://www.opennet.ru/docs/RUS/gnumake/

14

CI/CD прошивок для микроконтроллеров в Wiren Board ( начало на 25:20)

https://www.youtube.com/watch?v=HEEVxZ4rBCo

2

Конвеерум #30: Эволюция рабочего окружения для embedded разработки

https://www.youtube.com/watch?v=vmuO4bHjTSo&t=7s

3

GNU Make может больше чем ты думаешь

https://habr.com/ru/post/47513/

4

Пример Makefile

https://habr.com/ru/post/111691/

5

Настройка ToolChain(а) для Win10+GCC+С+Makefile+ARM Cortex-Mx+GDB

https://habr.com/ru/post/673522/

6

Компактный make для STM32 с USB

https://habr.com/ru/post/724800/

7

Генерация Зависимостей Внутри Программы

https://habr.com/ru/articles/765424/

16

Сборка и отладка прошивки IoT-модуля: Python, make, апельсины и чёрная магия

https://habr.com/ru/companies/whoosh/articles/825330/

8

Эффективное использование GNU Make

http://citforum.ru/operating_systems/gnumake/

9

GNU Make

https://www.gnu.org/software/make/

10

How To Create A Makefile (C/C++) | Makefile Tutorial | Linux

https://www.youtube.com/watch?v=WDXG8gpuVqg&list=WL&index=1

11

GNU Make

https://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html

12

Техникум: Автоматическое Aрхивирование Aртефактов

https://habr.com/ru/articles/826730/

13

Директива vpath

https://runebook.dev/ru/docs/gnu_make/selective-search

15

Почему Сборка с Помощью Есlipse ARM GCC Плагинов это Тупиковый Путь

https://habr.com/ru/articles/794206/

17

Обновление Прошивки из Make Скрипта

https://habr.com/ru/articles/857416/

Only registered users can participate in poll. Log in, please.
Вы собираете код с помощью утилиты Make?
45.13% да88
54.87% нет107
195 users voted. 21 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете прошивки из-под IDE?
64.13% да118
35.87% нет66
184 users voted. 22 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете код с помощью СMake?
43.88% да86
56.12% нет110
196 users voted. 22 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете прошивки в IDE-IAR?
17.11% да13
82.89% нет63
76 users voted. 8 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете прошивки в IDE-Keil?
35.06% да27
64.94% нет50
77 users voted. 7 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете код прошивок с помощью самописных Ninja скриптов?
6.67% да5
93.33% нет70
75 users voted. 8 users abstained.
Only registered users can participate in poll. Log in, please.
Вы собираете программы из скриптов?
48.72% Да, я собираю программы из скриптов (Make/Ninja/Cmake и прочее). Сам пишу скрипты сборки.19
51.28% Нет. Я полностью доверяюсь GUI-IDE и просто нажимаю F11, а там и будь, что будет.20
39 users voted. 6 users abstained.
Tags:
Hubs:
Total votes 44: ↑12 and ↓32-18
Comments97

Articles