Разработка софта это не только про код. Разработка софта это во многом про Toolchain(ы). Прежде чем начать исполняться исходники проходят гигантский путь и с каждым годом выходят все более и более массивные системы сборки. Современные технологии разработки софта настолько многостадийные, что понять их не просто.
Toolchain это как длинный конвейер. Есть действия, которые следуют одни за другими. После чего получается результат (артефакты). Большинство IDE(IAR, KEIL, MsVisualStudio и пр.) скрывают весь этот конвейер преобразования файлов. И программисты, которые привыкли торчать в IDE(шках) часто даже не догадываются, что в программировании существует что-то кроме *.h и *.с файликов. В этом плане IDE оказывают своим покупателям медвежью услугу, так как программисты привыкшие работать только в IDE имеют тенденцию становиться очень слабыми разработчиками.
По-настоящему разобраться как варятся артефакты сложно. Как же это сделать?
Надо прибегнуть к народной мудрости. Как говорит английская пословица: «картинка стоит тысячи слов». Значит надо нарисовать картинку. Схему ToolChain(а).
Зачем еще нужны схемы ToolChain(ов)?
Схема может пригодиться для того чтобы ввести в курс дела новичков. Например фирма chip maker может получить преимущество на рынке, если у нее есть качественная, понятная, доступная и разнообразная документация.
Как же нарисовать схему ToolChain(а)? Тут есть 2 варианта:
[1] Рисовать схему самому, мышкой в программе Inkscape.exe.
Плюс:
a) Можно добиться очень высокой степени изобразительности и гибкости. Можно задействовать слои, линейки. Те кто учил в художественной школе композицию тут могут оторваться по-полной.
Минусы:
a) Ручное рисование весьма утомительно. Обязательно наступят боли в запястье.
b) Использование мышки в программировании вообще считается дурным тоном.
c) Трудно подвергнуть *.svg файл версионному контролю. Конфликты при git merge *.svg так как это в сущности *.xml(ка).
[2] Составить описание графа или дерева на языке разметки графов Dot и автоматически одноименной утилитой dot.exe сгенерировать схему графа.
Плюсы:
a) Быстро.
b) Четко.
c) Легко перерисовать.
d) Легко подвергнуть версионному контролю.
e) Легко распределить между разными разработчиками сложной блок-схемы.
Минусы:
a) Надо очень хорошо знать синтаксис и семантику языка Dot: кластеры, свойства вершин, свойства ребер, способы раскраски.
b) Схема может не скомпилироваться рендером, если есть ошибки в синтаксисе языка Dot.
c) Cхема может отрисоваться самым неожиданным образом.
Как по мне, второй вариант выглядит намного предпочтительнее и позитивнее так как надо меньше пользоваться мышкой.
Какой инструментарий потребуется для авто генерации блок схем?
Если коротко то это cpp, dot, make, chrome.
Прежде всего надо накатить компилятор Dot файлов. Советую брать с официального сайта https://graphviz.org/. Сейчас там версия 6.0.1. Можно конечно и из CygWin скачать Dot, но там версия устаревшая. Старый Dot может упасть в run-time из-за переполнения стека при отрисовке сложных графов. Не забываем прописать путь к dot.exe в переменную PATH.
Писать код на голом языке Dot это не эффективно. В реальных схемах слишком много повторяющихся синтаксических конструкций. Поэтому объединим Си(ишный) препроцессор (утилита cpp.exe) с языком dot. С препроцессору (cpp.exe) вообще все равно какой там язык (assembler, C++, DeviceTree, Kconfig). Задача утилиты cpp.exe это вставка и замена текста. Точка. Например деревья устройств в Linux тоже обрабатываются препроцессором cpp. И это всех более чем устраивает. Поэтому будем также использовать препроцессор cpp для языка dot.
В качестве примера исследуемого сложного ToolChain(а) рассмотрим Zephyr project.
Определим только несколько полезных макросов для языка dot
#define BINARY [fillcolor = turquoise1] #define GENERATED [fillcolor = moccasin] #define SRC [style="filled"][fillcolor = green] #define TOOL [shape = box][style="filled"] #define SCRIPT [shape = box][style="filled"] [fillcolor = plum1] #define FILE [shape = note][fillcolor = gold][style="filled"] #define DEVICE [shape = box][fillcolor = grey][style="filled"]
Определим файл *.doti с утилитами, которые будут участвовать в ToolChain(е). *.doti — значит, что это include.
menuconfig TOOL clang_format [label="clang-format.exe"] TOOL eclipse [label="Eclipse.exe"] TOOL eclipsec [label="eclipsec.exe"] TOOL bash [label="bash.exe"] TOOL hexdump [label="hexdump.exe"] TOOL browser [label="chrome.exe"] TOOL inkscape [label="Inkscape.exe"] TOOL nrfjprog [label="nrfjprog.exe"] TOOL Cppcheck [label="Cppcheck.exe"] TOOL dtc [label="dtc"] TOOL gen_defines_py [label="gen_defines.py"] SCRIPT readelf [label="readelf.exe"]TOOL jenkins [label="jenkins.exe"]TOOL cpp [label="cpp.exe"]TOOL chocolatey [label="chocolatey.exe"]TOOL git [label="git.exe"]TOOL buildprog [label="buildprog.py"]SCRIPT JLinkGDBServer [label="JLinkGDBServer.exe"]TOOL cpp_dot [label="cpp.exe"]TOOL guiconfig TOOL cpp_3 [label="cpp.exe (preproc)"] TOOL linker [label="ld.exe (linker)"] TOOL compiler [label="gcc.exe (ARM Compiler)"] TOOL NotePadPp [label="Notepad++.exe"] TOOL cmd [label="cmd.exe"] TOOL GDB [label="gdb.exe"] TOOL cMake [label="cmake.exe"] TOOL west [label="west.py"] SCRIPT GN [label="gn.exe"] TOOL scripts_kconfig [label="zephyr/scripts/kconfig.py"] SCRIPT nrfjprog [label="nrfjprog.exe"] TOOL Python [label="Python.exe"] TOOL make [label="make.exe"] TOOL ninja [label="ninja.exe"] TOOL objcopy [label="objcopy.exe"] TOOL as [label="as.exe"]TOOL nm [label="nm.exe"]TOOL addr2line [label="addr2line.exe"]TOOL dot [label="dot.exe"]TOOL ar [label="ar.exe"]TOOL { rank = same; ninja; make;}
Определим *.doti файл со списком расширений файлов, которые будут участвовать в ToolChain(е)
dtsi[label="*.dtsi"] FILE SRC DotConf[label="*.conf (Kernel configuration)"] FILE SRC bat_file[label="*.bat"] FILE SRC CMakeLists [label="CMakeLists.txt "] FILE SRC sh_file[label="*.sh"] FILE SRC ld_file[label="*.ld"] FILE SRC mk_file[label="*.mk"] FILE SRC h_file[label="*.h"] FILE SRC c_file[label="*.c"] FILE SRC dot_file[label="*.dot"] FILE SRC doti_file[label="*.doti"] FILE SRC yaml[label="*.yaml"] FILE SRC Kconfig [label="Kconfig"] FILE SRC dts[label="*.dts"] FILE SRC zephyr_dts_pre[label="zephyr.dts.pre"] FILE cproject [label=".cproject "] FILE project [label=".project (description file)"] FILE Kconfig_zephyr[label="Kconfig.zephyr"] FILE txt_file[label="*.txt"] FILE obj_file[label="*.o"] FILE CMakeCache_txt [label="CMakeCache.txt "] FILE map_file[label="*.map"] FILE a_file[label="*.a"] FILE elf_file[label="*.elf"] FILE hex_file[label="*.hex"] FILE bin_file[label="*.bin"] FILE build_ninja [label="build.ninja"] FILE json_file[label="*.json"] FILE svg_file[label="*.svg "] FILE west_yml[label="west.yml (manifest file)"] FILE MakeFile[label="Makefile"] FILE devicetree_generated_h[label="devicetree_generated.h"] FILE zephyr_dts[label="zephyr.dts "] FILE autoconfig_h [label="autoconfig.h"] FILE s_file [label="*.S"] FILE gn_file [label="BUILD.gn"] FILE cmd_file [label="*.cmd"] FILE pp_file [label="*.pp"] FILE DotConfig [label=".config"] FILE
Определим файл со связями утилит и файлов между собой.
digraph graphname { rankdir=TB; splines=ortho; #include "ToolChain_nRF5340_hardware.doti" subgraph cluster_NetTop { style=filled; color=aliceblue; label = "NetTop"; HostCpu HOST_USB subgraph cluster_Windows10 { style=filled; color=lightblue; label = "Windows10"; #include "ToolChain_nRF5340_tools.doti" #include "ToolChain_nRF5340_files.doti" NotePadPp->bat_file[label="*.bat"][dir="both"] NotePadPp->doti_file[label="*.doti"] [dir="both"] NotePadPp->sh_file[label="*.sh"][dir="both"] NotePadPp->mk_file[label="*.mk"][dir="both"] NotePadPp->c_file[label="*.c"][dir="both"] NotePadPp->h_file[label="*.h"][dir="both"] bat_file->cmd[label="*.bat"] sh_file->bash[label="*.sh"] subgraph cluster_JVM { style=filled; color=lightgreen; label = "JVM"; jenkins->bash eclipsec cproject->eclipse[label=".cproject"][dir="both"] project->eclipse[label=".project"][dir="both"] } subgraph cluster_BuildConfig { style=filled; color=khaki1; label = "Build Configuration (buildsystem)"; bash->buildprog cmd->buildprog Python->buildprog json_file->buildprog [label="*.json"] Python->west buildprog->west[label="?"] yaml->gen_defines_py[label="*.yaml"] dtsi->cpp[label="*.dtsi"] dts->cpp cpp->zephyr_dts_pre zephyr_dts_pre ->gen_defines_py[label="zephyr.dts.pre"] gen_defines_py->zephyr_dts[label="zephyr.dts"] gen_defines_py->devicetree_generated_h[label="devicetree_generated.h"] zephyr_dts->dtc CMakeLists->cMake[label="CMakeLists.txt"] west->cMake west->scripts_kconfig cMake->CMakeCache_txt[label="CMakeCache.txt"] [dir="both"] gn_file->GN GN->build_ninja cMake->build_ninja[label="build.ninja"] cMake->MakeFile menuconfig [label="menuconfig "] Kconfig->menuconfig [label="Kconfig"] Kconfig->Kconfig_zephyr Kconfig->guiconfig[label="Kconfig"] Kconfig->scripts_kconfig[label="Kconfig"] DotConf->scripts_kconfig[label="*.conf"] scripts_kconfig->autoconfig_h[label="autoconfig.h"] scripts_kconfig->DotConfig[label="*.config"] }//cluster_BuildConfig ld_file->git[label="*.ld"][dir="both"] sh_file->git[label="*.sh"][dir="both"] h_file->git[label="*.h"][dir="both"] c_file->git[label="*.c"][dir="both"] mk_file->git[label="*.mk"][dir="both"] doti_file->git[label="*.doti"][dir="both"] cproject->git[label=".cproject"][dir="both"] MakeFile->git[label="Makefile"][dir="both"] project->git[label=".project"][dir="both"] c_file->eclipse[label="*.c "] h_file->eclipse[label="*.h"] eclipse->c_file[label="*.c "] eclipse->h_file[label="*.h"] eclipse->MakeFile[dir="both"][label="Makefile"] eclipse->mk_file[dir="both"][label="*.mk"] subgraph cluster_BuildArtefact { style=filled; color=gray100; label = "Build Artefact"; build_ninja->ninja[label="Makefile"] ninja->cpp_3 h_file->cpp_3 c_file->cpp_3 autoconfig_h->cpp_3[label="autoconfig.h"] devicetree_generated_h->cpp_3 pp_file->compiler compiler->s_file [label="*.S"] s_file->as compiler->ar as->obj_file obj_file->linker [label="*.obj"] /*[tailport=s] [headport=n] */ obj_file->ar[label="*.o"] ar->a_file[label="*.a"] obj_file->nm[label="*.o"] ld_file->linker [label="*.ld"]//[headport=n] cmd_file->linker[label="*.cmd"] a_file->linker[label="*.a"] linker->elf_file[label="*.elf"] linker->map_file[label="*.map"] elf_file->addr2line[label="*.elf"] addr2line->eclipse[label=".txt"] elf_file -> objcopy objcopy->bin_file objcopy->hex_file elf_file->readelf[label="*.elf"] elf_file->GDB[label="*.elf"] GDB-> JLinkGDBServer[dir="both"][label="port:2331"] bin_file->hexdump[label="*.bin"] hexdump->txt_file[label="*.txt"] mk_file->make[label="*.mk"] MakeFile->make[label="MakeFile"] make->cpp_3 cpp_3 -> pp_file hex_file->nrfjprog } subgraph cluster_BuildDoc { style=filled; color=beige; label = "Build Documentation"; doti_file->cpp_dot cpp_dot->dot_file dot_file->dot dot->svg_file[label="*.svg"] svg_file->browser[label="*.svg"] svg_file->inkscape[label="*.svg"] } clang_format->c_file[label="*.c"][dir="both"] clang_format->h_file[label="*.h"][dir="both"] h_file->Cppcheck[label="*.h"] c_file->Cppcheck[label="*.c"] browser->jenkins[label="8080"] }//Win10 //NotePadPp->Monitor }//NetTop eclipse->Monitor nrfjprog->HOST_USB JLinkGDBServer->HOST_USB subgraph cluster_Board { style=filled; color=lightblue; label = "Board"; USB_CONNECTOR_BOARD Programmator TargetMcu } }
Теперь надо собрать, собственно, сам *.dot файл для утилиты рендера dot.exe, преобразовать *.dot в векторную графику *.svg и отобразить рисунок на экране монитора прямо в браузере. Вот такой микро-конвейер надо реализовать.

Тут нам как раз поможет утилита make. Вот ее код
CC=dot RENDER=chrome.exe CURRENT_DIR = $(shell pwd) $(info CURRENT_DIR= $(CURRENT_DIR) ) CURRENT_DIR := $(subst /cygdrive/c/,C:/, $(CURRENT_DIR)) $(info CURRENT_DIR=$(CURRENT_DIR) ) SOURCES_DOT += $(CURRENT_DIR)/ToolChain_nRF5340.doti SOURCES_DOT_RES += $(CURRENT_DIR)/ToolChain_nRF5340_res.dot SOURCES_DOT := $(subst /cygdrive/c/,C:/, $(SOURCES_DOT)) $(info SOURCES_DOT= $(SOURCES_DOT) ) ART_SVG := $(subst doti,svg, $(SOURCES_DOT)) ART_PDF := $(subst doti,pdf, $(SOURCES_DOT)) OPT += DOT_OPT +=-Tsvg DOT_OPT +=-v DOT_OPT +=-L1 #LAYOUT_ENGINE = -Kneato #LAYOUT_ENGINE = -Kfdp #LAYOUT_ENGINE = -Ksfdp #LAYOUT_ENGINE = -Ktwopi #LAYOUT_ENGINE = -Kosage #LAYOUT_ENGINE = -Kpatchwork LAYOUT_ENGINE = -Kdot preproc:$(SOURCES_DOT) $(info Preproc...) cpp $(SOURCES_DOT) $(OPT) -E -o $(SOURCES_DOT_RES) generate_pdf: preproc $(info route graph...) $(CC) -Tpdf $(LAYOUT_ENGINE) $(SOURCES_DOT_RES) -o $(ART_PDF) generate_svg: preproc $(info route graph...) $(CC) $(DOT_OPT) $(SOURCES_DOT_RES) -o $(ART_SVG) print_svg: generate_svg generate_pdf $(info print_svg) $(RENDER) -open $(ART_SVG) $(RENDER) -open $(ART_PDF) all: print_svg $(info All) clean: $(info clean) rm ToolChain_nRF5340_res.svg rm $(SOURCES_DOT_RES) #$(ART_SVG):$(ART_SVG)
Для любителей ninja я тоже накропал ninja скрипт
cflags = -Tsvg cur_dir = C:\projects\code_base_workspace\code_base_firmware\docs\toolchain_nRF5340\ RENDER="C:/Program Files/Google/Chrome/Application/chrome.exe" rule preproc command = cpp $in -E -o $out rule generate_svg command = dot $cflags $in -o $out rule print_in_browse command = $RENDER -open $cur_dir/$in rule clean_temp command = rm *_generated.svg command = rm *_res.dot rule svg2pdf command = dot.exe -Tpdf $in -o $out build clean: clean_temp build ToolChain_nRF5340_res.dot: preproc ToolChain_nRF5340.doti build ToolChain_nRF5340_generated.svg: generate_svg ToolChain_nRF5340_res.dot build ToolChain_nRF5340_generated.pdf: svg2pdf ToolChain_nRF5340_res.dot build make_svg: print_in_browse ToolChain_nRF5340_generated.svg build make_pdf: print_in_browse ToolChain_nRF5340_generated.pdf default make_pdf
В результате мы собрали вот такую замечательную блок схемку ToolChain для системы сборки Zephyr.

Успех! Теперь все как на ладони. Причем при просмотре *.svg из браузера даже Ctrl+F поиск есть! Супер!
Буквально пара слов про Zephyr. Видно, что Zephyr собирает проекты в два супер этапа. Сначала Zephyr собирает конфигурацию. Результат сборки конфигурации это Makefile или build.ninja плюс несколько заголовочных файлов *.h, затем собирают сами артефакты на основе собранной ранее конфигурации. На схеме все прекрасно видно. Рулит всем внутри фактически CMake.
Вот полный *.dot код с выхода препроцессора для тех, кто хочет изучить схему под увеличением
Hidden text
# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" # 1 "<built-in>" # 1 "<command-line>" # 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" digraph graphname { rankdir=TB; splines=ortho; # 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_hardware.doti" 1 Monitor [label="Monitor"] [shape = box][fillcolor = grey][style="filled"] Programmator [label="Programmator"] [shape = box][fillcolor = grey][style="filled"] TargetMcu [label="nRF5340 ARM Cortex-M33 2x"] [shape = box][fillcolor = grey][style="filled"] HOST_USB [label="USB"] [shape = box][fillcolor = grey][style="filled"] USB_CONNECTOR_BOARD [label="USB"] [shape = box][fillcolor = grey][style="filled"] HostCpu [label="X86 AMD64"] [shape = box][fillcolor = grey][style="filled"] HostCpu->HOST_USB HOST_USB->USB_CONNECTOR_BOARD[label="USB"] USB_CONNECTOR_BOARD->Programmator[label="USB"] Programmator->TargetMcu[label="SWD"] # 11 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2 subgraph cluster_NetTop { style=filled; color=aliceblue; label = "NetTop"; HostCpu HOST_USB subgraph cluster_Windows10 { style=filled; color=lightblue; label = "Windows10"; # 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_tools.doti" 1 menuconfig [shape = box][style="filled"] clang_format [label="clang-format.exe"] [shape = box][style="filled"] eclipse [label="Eclipse.exe"] [shape = box][style="filled"] eclipsec [label="eclipsec.exe"] [shape = box][style="filled"] bash [label="bash.exe"] [shape = box][style="filled"] hexdump [label="hexdump.exe"] [shape = box][style="filled"] browser [label="chrome.exe"] [shape = box][style="filled"] inkscape [label="Inkscape.exe"] [shape = box][style="filled"] nrfjprog [label="nrfjprog.exe"] [shape = box][style="filled"] Cppcheck [label="Cppcheck.exe"] [shape = box][style="filled"] dtc [label="dtc"] [shape = box][style="filled"] gen_defines_py [label="gen_defines.py"] [shape = box][style="filled"] [fillcolor = plum1] readelf [label="readelf.exe"][shape = box][style="filled"] jenkins [label="jenkins.exe"][shape = box][style="filled"] cpp [label="cpp.exe"][shape = box][style="filled"] chocolatey [label="chocolatey.exe"][shape = box][style="filled"] git [label="git.exe"][shape = box][style="filled"] buildprog [label="buildprog.py"][shape = box][style="filled"] [fillcolor = plum1] JLinkGDBServer [label="JLinkGDBServer.exe"][shape = box][style="filled"] cpp_dot [label="cpp.exe"][shape = box][style="filled"] guiconfig [shape = box][style="filled"] cpp_3 [label="cpp.exe (preproc)"] [shape = box][style="filled"] linker [label="ld.exe (linker)"] [shape = box][style="filled"] compiler [label="gcc.exe (ARM Compiler)"] [shape = box][style="filled"] NotePadPp [label="Notepad++.exe"] [shape = box][style="filled"] cmd [label="cmd.exe"] [shape = box][style="filled"] GDB [label="gdb.exe"] [shape = box][style="filled"] cMake [label="cmake.exe"] [shape = box][style="filled"] west [label="west.py"] [shape = box][style="filled"] [fillcolor = plum1] GN [label="gn.exe"] [shape = box][style="filled"] scripts_kconfig [label="zephyr/scripts/kconfig.py"] [shape = box][style="filled"] [fillcolor = plum1] nrfjprog [label="nrfjprog.exe"] [shape = box][style="filled"] Python [label="Python.exe"] [shape = box][style="filled"] make [label="make.exe"] [shape = box][style="filled"] ninja [label="ninja.exe"] [shape = box][style="filled"] objcopy [label="objcopy.exe"] [shape = box][style="filled"] as [label="as.exe"][shape = box][style="filled"] nm [label="nm.exe"][shape = box][style="filled"] addr2line [label="addr2line.exe"][shape = box][style="filled"] dot [label="dot.exe"][shape = box][style="filled"] ar [label="ar.exe"][shape = box][style="filled"] # 26 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2 # 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_files.doti" 1 dtsi[label="*.dtsi"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] DotConf[label="*.conf (Kernel configuration)"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] bat_file[label="*.bat"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] CMakeLists [label="CMakeLists.txt "] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] sh_file[label="*.sh"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] ld_file[label="*.ld"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] mk_file[label="*.mk"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] h_file[label="*.h"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] c_file[label="*.c"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] dot_file[label="*.dot"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] doti_file[label="*.doti"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] yaml[label="*.yaml"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] Kconfig [label="Kconfig"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] dts[label="*.dts"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green] zephyr_dts_pre[label="zephyr.dts.pre"] [shape = note][fillcolor = gold][style="filled"] cproject [label=".cproject "] [shape = note][fillcolor = gold][style="filled"] project [label=".project (description file)"] [shape = note][fillcolor = gold][style="filled"] Kconfig_zephyr[label="Kconfig.zephyr"] [shape = note][fillcolor = gold][style="filled"] txt_file[label="*.txt"] [shape = note][fillcolor = gold][style="filled"] obj_file[label="*.o"] [shape = note][fillcolor = gold][style="filled"] CMakeCache_txt [label="CMakeCache.txt "] [shape = note][fillcolor = gold][style="filled"] map_file[label="*.map"] [shape = note][fillcolor = gold][style="filled"] a_file[label="*.a"] [shape = note][fillcolor = gold][style="filled"] elf_file[label="*.elf"] [shape = note][fillcolor = gold][style="filled"] hex_file[label="*.hex"] [shape = note][fillcolor = gold][style="filled"] bin_file[label="*.bin"] [shape = note][fillcolor = gold][style="filled"] build_ninja [label="build.ninja"] [shape = note][fillcolor = gold][style="filled"] json_file[label="*.json"] [shape = note][fillcolor = gold][style="filled"] svg_file[label="*.svg "] [shape = note][fillcolor = gold][style="filled"] west_yml[label="west.yml (manifest file)"] [shape = note][fillcolor = gold][style="filled"] MakeFile[label="Makefile"] [shape = note][fillcolor = gold][style="filled"] devicetree_generated_h[label="devicetree_generated.h"] [shape = note][fillcolor = gold][style="filled"] zephyr_dts[label="zephyr.dts "] [shape = note][fillcolor = gold][style="filled"] autoconfig_h [label="autoconfig.h"] [shape = note][fillcolor = gold][style="filled"] s_file [label="*.S"] [shape = note][fillcolor = gold][style="filled"] gn_file [label="BUILD.gn"] [shape = note][fillcolor = gold][style="filled"] cmd_file [label="*.cmd"] [shape = note][fillcolor = gold][style="filled"] pp_file [label="*.pp"] [shape = note][fillcolor = gold][style="filled"] DotConfig [label=".config"] [shape = note][fillcolor = gold][style="filled"] # 27 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2 NotePadPp->bat_file[label="*.bat"][dir="both"] NotePadPp->doti_file[label="*.doti"] [dir="both"] NotePadPp->sh_file[label="*.sh"][dir="both"] NotePadPp->mk_file[label="*.mk"][dir="both"] NotePadPp->c_file[label="*.c"][dir="both"] NotePadPp->h_file[label="*.h"][dir="both"] bat_file->cmd[label="*.bat"] sh_file->bash[label="*.sh"] subgraph cluster_JVM { style=filled; color=lightgreen; label = "JVM"; jenkins->bash eclipsec cproject->eclipse[label=".cproject"][dir="both"] project->eclipse[label=".project"][dir="both"] } subgraph cluster_BuildConfig { style=filled; color=khaki1; label = "Build Configuration (buildsystem)"; bash->buildprog cmd->buildprog Python->buildprog json_file->buildprog [label="*.json"] Python->west buildprog->west[label="?"] yaml->gen_defines_py[label="*.yaml"] dtsi->cpp[label="*.dtsi"] dts->cpp cpp->zephyr_dts_pre zephyr_dts_pre ->gen_defines_py[label="zephyr.dts.pre"] gen_defines_py->zephyr_dts[label="zephyr.dts"] gen_defines_py->devicetree_generated_h[label="devicetree_generated.h"] zephyr_dts->dtc CMakeLists->cMake[label="CMakeLists.txt"] west->cMake west->scripts_kconfig cMake->CMakeCache_txt[label="CMakeCache.txt"] [dir="both"] gn_file->GN GN->build_ninja cMake->build_ninja[label="build.ninja"] cMake->MakeFile menuconfig [label="menuconfig "] Kconfig->menuconfig [label="Kconfig"] Kconfig->Kconfig_zephyr Kconfig->guiconfig[label="Kconfig"] Kconfig->scripts_kconfig[label="Kconfig"] DotConf->scripts_kconfig[label="*.conf"] scripts_kconfig->autoconfig_h[label="autoconfig.h"] scripts_kconfig->DotConfig[label="*.config"] } ld_file->git[label="*.ld"][dir="both"] sh_file->git[label="*.sh"][dir="both"] h_file->git[label="*.h"][dir="both"] c_file->git[label="*.c"][dir="both"] mk_file->git[label="*.mk"][dir="both"] doti_file->git[label="*.doti"][dir="both"] cproject->git[label=".cproject"][dir="both"] MakeFile->git[label="Makefile"][dir="both"] project->git[label=".project"][dir="both"] c_file->eclipse[label="*.c "] h_file->eclipse[label="*.h"] eclipse->c_file[label="*.c "] eclipse->h_file[label="*.h"] eclipse->MakeFile[dir="both"][label="Makefile"] eclipse->mk_file[dir="both"][label="*.mk"] subgraph cluster_BuildArtefact { style=filled; color=gray100; label = "Build Artefact"; build_ninja->ninja[label="Makefile"] ninja->cpp_3 h_file->cpp_3 c_file->cpp_3 autoconfig_h->cpp_3[label="autoconfig.h"] devicetree_generated_h->cpp_3 pp_file->compiler compiler->s_file [label="*.S"] s_file->as compiler->ar as->obj_file obj_file->linker [label="*.obj"] obj_file->ar[label="*.o"] ar->a_file[label="*.a"] obj_file->nm[label="*.o"] ld_file->linker [label="*.ld"] cmd_file->linker[label="*.cmd"] a_file->linker[label="*.a"] linker->elf_file[label="*.elf"] linker->map_file[label="*.map"] elf_file->addr2line[label="*.elf"] addr2line->eclipse[label=".txt"] elf_file -> objcopy objcopy->bin_file objcopy->hex_file elf_file->readelf[label="*.elf"] elf_file->GDB[label="*.elf"] GDB-> JLinkGDBServer[dir="both"][label="port:2331"] bin_file->hexdump[label="*.bin"] hexdump->txt_file[label="*.txt"] mk_file->make[label="*.mk"] MakeFile->make[label="MakeFile"] make->cpp_3 cpp_3 -> pp_file hex_file->nrfjprog } subgraph cluster_BuildDoc { style=filled; color=beige; label = "Build Documentation"; doti_file->cpp_dot cpp_dot->dot_file dot_file->dot dot->svg_file[label="*.svg"] svg_file->browser[label="*.svg"] svg_file->inkscape[label="*.svg"] } clang_format->c_file[label="*.c"][dir="both"] clang_format->h_file[label="*.h"][dir="both"] h_file->Cppcheck[label="*.h"] c_file->Cppcheck[label="*.c"] browser->jenkins[label="8080"] } } eclipse->Monitor nrfjprog->HOST_USB JLinkGDBServer->HOST_USB subgraph cluster_Board { style=filled; color=lightblue; label = "Board"; USB_CONNECTOR_BOARD Programmator TargetMcu } }
Вывод
Как видите синергия препроцессора cpp и языка разметки Dot может оказаться очень полезна и эффективна в разработке софта и документации. Это позволяет высвободить тонну времени от ручной перерисовки. Можно также из Dot генерировать схемы электрических цепочек, графы задач из task traker(а), нейронные сети, конечные автоматы, архитектуры систем на чипе SoC. Да всё, что только угодно, что имеет графо образную природу.
Язык Dot настолько хорош и универсален, что его следовало бы включить в университетскую программу обучения технических факультетов в качестве одной лабораторной работы по компьютерным технологиям.
Особенно советую обратить внимание на связку сpp/dot/make тем кто работает техническими писателями и схемотехниками. Это тот самый случай, когда программирование им тоже может нанести пользу.
Ссылки про язык Dot
https://habr.com/ru/post/682346/
https://habr.com/ru/post/499170/
https://habr.com/ru/post/337078/
ссылка на оригинал статьи https://habr.com/ru/post/688542/
Добавить комментарий