Возникла задача автоматизировать статический анализ пакетов в составе дистрибутива. Наилучший инструмент для этого — PVS Studio, потому что умеет перехватывать вызовы компилятора с помощью strace, таким образом, не требуя никаких изменений в сборочных скриптах. Сначала под наблюдением pvs-studio-analyzer
запускается сборка, собирает лог, затем запускается анализатор этого лога и формируется отчет. Рассмотрим, как такое настроить, избежав внесения правок в каждый пакет.
В качестве операционной системы будем рассматривать rosa2019.1 (dnf + rpm4). Я использую сборки rootfs и systemd-nspawn (snr). Сначала установим необходимые для работы пакеты:
dnf install git-core bash abf basesystem-build how-to-use-pvs-studio-free
С помощью утилиты how-to-use-pvs-studio-free нужно в исходники добавить заголовки PVS Studio. Эти исходники затем будут отстрипаны от бинарников и попадут в debugsource-подпакеты, которые публикуются в репозиторий. Установим ее из репозитория:
sudo dnf install how-to-use-pvs-studio-free
Ставим саму PVS Studio:
wget https://files.viva64.com/pvs-studio-latest.rpm -O pvs-studio-latest.rpm sudo dnf install pvs-studio-latest.rpm
Включаем бесплатную лицензию:
pvs-studio-analyzer credentials PVS-Studio Free FREE-FREE-FREE-FREE
Теперь суть в следующем. Как известно, RPM превращает секцию спека %prep
в shell-скрипт /var/tmp/*.sh
и запускает его, аналогично делает с секциями %build
и %install
. Мы сделаем обертку, которая будет запускать эти скрипты вместо %_buildshell
(/bin/sh
).
Создаем файл /usr/bin/pvs-prep
со следующим текстом:
#!/bin/sh set -eu sh "$2" ( cd "$1" how-to-use-pvs-studio-free -c 2 -m . )
Этот скрипт будет на стадии %prep
добавлять шапку с рекламой PVS Studio в исходники.
Создаем файл /usr/bin/pvs-builder
со следующим текстом:
#!/bin/bash set -eu name="$1" script="$2" test -f "$script" [ -n "$2" ] /usr/bin/pvs-studio-analyzer trace -- /bin/bash -e "$script" mkdir -p "$HOME/pvs-logs/raw-logs" pvs-studio-analyzer analyze -o "$HOME/pvs-logs/${name}" -j "$(nproc)" #-C /usr/bin/clang rm -fr "$HOME/pvs-logs/html-logs/${name}" mkdir -p "$HOME/pvs-logs/html-logs/${name}" plog-converter -a GA:1,2 -t fullhtml "$HOME/pvs-logs/${name}" -o "$HOME/pvs-logs/html-logs/${name}" mv -v "$HOME/pvs-logs/html-logs/${name}/fullhtml"/* "$HOME/pvs-logs/html-logs/${name}/" rm -fr "$HOME/pvs-logs/html-logs/${name}/fullhtml"
Этот скрипт будет запускать скрипт %build
под трассировщиком PVS Studio, а затем создавать отчет.
Делаем их исполняемыми:
chmod +x /usr/bin/pvs-builder /usr/bin/pvs-prep
Не используем /usr/local/bin, поскольку он не входит в $PATH в RPM.
Теперь в файл /etc/rpm/macros
дописываем:
%__spec_prep_cmd /usr/bin/pvs-prep "%{_sourcedir}" %__spec_build_cmd /usr/bin/pvs-builder %{name}
(см. https://github.com/rpm-software-management/rpm/issues/1399)
И всё. Каждая сборка проекта на C/C++ будет создавать HTML-отчет в папке $HOME/pvs-logs/html-logs/имя_пакета.
Чтобы не мучиться с mock, можно собирать список пакетов так:
cat list_sec_sorted.txt | while read -r line; do pushd $line && dnf builddep --allowerasing -y *.spec && abf rpmbuild ; popd; done
т.е. ставить сборочные зависимости в ту же систему, но разрешать удалять лишние пакеты, если устанавливаемые зависимости текущего пакета конфликтуют с зависимостями одного из предыдущих пакетов.
Отправить ответ