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

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

build logs как аудиторский артефакт

Почему это важно для SCA/OSA

В C/C++ единственный момент, когда состав зависимостей виден полностью и достоверно, — это сама сборка. После неё информация теряется: статическая библиотека растворяется в бинаре, символы стрипаются, флаги забываются. Поэтому полный лог компиляции и линковки — не служебный мусор, а ground truth о составе: он показывает каждый запуск компилятора, каждый -I/-L/-l, каждый входной .a/.o, переданный линкеру. Поздний скан готового бинаря этого не восстановит — он работает с тем, что от зависимостей осталось, а лог фиксирует, что в них входило.

Для аудита лог решает задачу доказуемости. Запись в SBOM «компонент X версии Y» приобретает вес только тогда, когда за ней стоит строка лога, где этот компонент реально передан компилятору/линкеру. Без такой привязки SBOM — декларация, с ней — доказательство.

Как это проявляется

Полный лог сборки получают принудительно verbose-режимом и сохраняют целиком; из него извлекают команды линковки и компиляции:

# Принудительно полные команды (иначе make/ninja прячут их за «CC app.o»)
make V=1 2>&1 | tee build.log
# или: ninja -v ; cmake --build . --verbose ; bear -- make   (compile_commands.json)

# Что реально слинковалось: входные .a/.o и флаги -l/-L в команде линкера
grep -E '\b(gcc|g\+\+|c\+\+|ld|clang\+\+)\b' build.log | grep -oE '[^ ]+\.a|[^ ]+\.o|-l[a-z0-9_]+|-L *[^ ]+'

# Какие заголовки и include path видел компилятор
grep -oE '\-I *[^ ]+' build.log | sort -u

# Compile DB как структурированный аналог лога
jq -r '.[].command' compile_commands.json | grep -oE '\-l[a-z0-9_]+' | sort -u

Каждая такая строка — кандидат на компонент SBOM и одновременно его доказательство (evidence).

Слепая зона или приём

Слепая зона — немой лог. По умолчанию make/ninja/CMake печатают только цели (CC app.o, LINK app), скрывая фактические команды. В таком логе ни одной зависимости не видно, и его легко принять за «ничего интересного». Второй провал — лог не сохраняют: сборка прошла в CI, контейнер удалён, evidence исчезло вместе с ним.

Приём: build-scan вместо пост-скана Перехват вызовов компилятора во время сборки (bear, compiledb, verbose-режим сборщика) даёт состав, который не восстановить из бинаря, — в частности статически слинкованные библиотеки, которые после линковки не оставляют DT_NEEDED. Сохраняйте полный лог как иммутабельный артефакт сборки рядом с бинарём и SBOM (см. статическая линковка).

Что делать на проекте

  1. Включите полный verbose-режим (make V=1, ninja -v, cmake --build . --verbose) и пишите лог целиком в файл.
  2. Снимите compile_commands.json (bear -- make / -DCMAKE_EXPORT_COMPILE_COMMANDS=ON) — структурированный, машиночитаемый источник состава.
  3. Извлеките из лога входные .a/.o, флаги -l/-L/-I и сопоставьте каждый с компонентом SBOM.
  4. Привяжите записи SBOM к строкам лога как evidence; то, что в логе есть, а в SBOM нет, — пропуск генератора (см. SBOM evidence occurrences).
  5. Сохраняйте лог как иммутабельный артефакт сборки (артефакт-репозиторий, хеш), а не как временный вывод CI.
  6. Для приёмки чужой сборки требуйте build-лог в составе поставки — без него полнота состава не доказуема (см. поставка от соисполнителя).

Связь