Пиков / КАПО
Как читать авторский курс и нормативные материалы

Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.

П20. CMake dependency graph

Цель

Получить из CMake-проекта два машинных артефакта состава: compile_commands.json (что и с какими -I компилировалось) и граф целей (--graphviz), показывающий, какие библиотеки линкуются к исполняемому файлу. Проверяемый результат: оба файла на диске и осознанный ответ, какие узлы графа — внешние зависимости, а какие — собственные цели проекта.

Команда или действие

# 1. сконфигурировать проект и попросить CMake выгрузить базу компиляции
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

# 2. выгрузить граф зависимостей целей (target dependency graph)
cmake --graphviz=build/deps.dot -S . -B build

# 3. посмотреть, какие библиотеки реально подключаются к таргету app
grep -E 'target_link|->' build/deps.dot
# при наличии graphviz — отрисовать в PNG
dot -Tpng build/deps.dot -o build/deps.png

Что именно отдаёт CMake compile_commands.json — это массив записей вида «директория + команда компиляции + файл». Из него видны все -I и -D, но не линковка. Линковку показывает граф --graphviz: рёбра соответствуют target_link_libraries(...). Вместе они дают то, чего нет в #include: какая внешняя цель действительно прицеплена к бинарю.

Что вы должны увидеть

build/compile_commands.json — массив записей (фрагмент):

[
  {
    "directory": "/proj/build",
    "command": "/usr/bin/g++ -I/proj/include -I/usr/include/openssl -o main.o -c /proj/src/main.cpp",
    "file": "/proj/src/main.cpp"
  }
]

В build/deps.dot — узлы и рёбра целей; внешние библиотеки выглядят как листовые узлы без исходников:

"node0" [ label = "app", shape = egg ];
"node1" [ label = "OpenSSL::SSL", shape = septagon ];
"node0" -> "node1"   // app линкуется с OpenSSL::SSL
"node0" -> "node2"   // app -> z (zlib)

Ориентир: число рёбер app -> ... примерно равно числу аргументов target_link_libraries в CMakeLists.txt. Если в графе библиотек меньше, чем #include сторонних заголовков, — часть зависимостей подтянута транзитивно или вшита, проверяйте через П19. C C++ make build inventory.

Если не получилось

Критерий зачёта

Показать преподавателю: compile_commands.json и deps.dot (или deps.png), а также короткий разбор графа — какие узлы являются внешними зависимостями (OpenSSL, zlib и т.п.), какие — собственными целями проекта, и совпадает ли число внешних рёбер с числом сторонних #include. Расхождение нужно объяснить.

Нормативная связка

Декларативный граф целей CMake — это управляемая фиксация состава по ГОСТ Р 56939-2024 и практика PS.3.2 (NIST SP 800-218 SSDF): зависимости описаны в сборочной конфигурации, а не угадываются. Полнота и связность (dependency relationship) — критерии качества SBOM по BSI TR-03183-2 v2.1.0. Смежные практики модуля М09: П19. C C++ make build inventory, П21. Conan graph и package identity, П22. ELF dynamic dependencies. Шаблон: Порядок работы с неопознанной библиотекой.