Настраиваем статический анализ Unreal Engine проекта

В PVS-Studio давно есть возможность анализировать Unreal Engine проекты. Но с момента последней заметки мы много работали над этим режимом. Поэтому хочу рассказать о том, как быстро настроить наш анализатор для проверки вашего проекта на Unreal Engine.

54df7488b71c64a732495c1846edf341.png

Лучше всего рассмотреть проверку Unreal Engine проекта на реальном примере. В качестве подопытного проекта возьмём Lyra — пример игры, который Epic Games представили вместе с выпуском Unreal Engine 5.0. Lyra является многомодульным проектом, который служит для знакомства с возможностями UE5.

Работа с проектом будет проходить на Windows. Cобирать будем с использованием Unreal Engine 5.3.2. Для анализа возьмём PVS-Studio 7.29.

Установка PVS-Studio

Сам инсталлятор PVS-Studio можно найти на этой странице. Для анализа Unreal Engine проектов способом, приведённым в этой статье, нужна Enterprise лицензия. Вы можете получить триальную Enterprise лицензию по этой ссылке. Процесс установки довольно прост: достаточно запустить инсталлятор и следовать его инструкциям. В качестве дополнительных компонентов потребуется только плагин для Visual Studio 2022. Процесс установки описан в документации. Запросить и ввести лицензию можно также сразу в инсталляторе.

Запуск анализа

Процесс анализа UE проектов отличается от анализа других проектов. При попытке запустить анализ стандартными методами, например, через плагин для Visual Studio, выведется предупреждение о невозможности выполнить анализ.

Такое поведение связано с особенностями организации запуска анализа UE проектов. Для их сборки используется UnrealBuildTool, и анализ запускается именно через него. Для того, чтобы провести именно статический анализ проекта, а не его сборку, сам проект нужно сконфигурировать.

Для Unreal Engine проектов есть три способа определения конфигурации:

  1. Передача флагов напрямую в UnrealBuildTool;

  2. Задание параметров в .target.cs файлах;

  3. Включение настроек в файл BuildConfiguration.xml (обычно находится в %appdata%\Unreal Engine\UnrealBuildTool).

Каждый вариант имеет свои особенности и подходит под разные сценарии использования.

Первый вариант позволяет задать настройки для конкретной конфигурации и конкретной команды (Build/Rebuild). Второй способ определяет конфигурацию для определённого типа таргетов (подробнее про таргеты можете узнать здесь). А третий вариант можно использовать для глобальных настроек UE проектов.

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

Для старта анализа нужно передать в UnrealBuildTool специальный флаг:

-StaticAnalyzer=PVSStudio

В Visual Studio это можно сделать, добавив этот флаг в NMake команду проекта и запустив сборку. Для этого откройте свойства проекта, выберите NMake и впишите флаг в поле Build Command Line.

658d4a7b1249dfd348cce93815364ed9.png

Анализ в этом случает заменит собой сборку проекта. Если добавлять флаг анализатора в команду Rebuild, то при каждом её вызове будет происходить анализ всего проекта. Если модифицировать команду Build, то при её запуске будут проверяться только изменённые файлы.

В полной документации вы можете подробнее узнать о сценарии запуска сборки и анализа проекта.

Запуск через NMake доступен, если открывать Unreal Engine проект через .sln файл.

В JetBrains Rider существует возможность запускать UE проекты напрямую через .uproject. В этом случае модификация NMake команд недоступна и используется вариант с указанием параметра StaticAnalyzer в .target.cs файле.

По умолчанию при анализе UE проекта отчёт не открывается в окне плагина PVS-Studio. Чтобы отчёт анализа загрузился в таблицу плагина, перед началом анализа нужно включить настройку AutoloadUnrealEngineLog. Сам отчёт сохраняется в подпапке проекта Saved/PVS-Studio (в случае Lyra — »\LyraStarterGame\Saved\PVS-Studio\LyraGame.pvslog»)

Запускаем анализ и видим перед собой такую картину:

8120b8312ce0f5d887155e1d7deb7b0b.png

Анализируются модули, а не исходные файлы проекта.

Плюс к этому в таблице находятся срабатывания, относящиеся не к проекту, а к ядру Unreal Engine.

f55bfe78fbd2151283eee41563928237.png

Давайте разберёмся, как получить более релевантный проверяемому проекту отчёт.

Настраиваем анализ

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

Для этого в настройках плагин PVS-Studio есть пункт Don’t Check Files > PathMasks. Добавим туда такую маску:

*.gen.cpp

Ещё одна проблема ненастроенного анализа — анализ исходных файлов ядра Unreal Engine. Если бы мы разрабатывали плагин для UE или модифицировали само ядро, то такая проверка была бы необходима. Но сейчас нам интересно проверить только проект. Поэтому добавим к настройке PathMasks путь до ядра Unreal Engine (по умолчанию в настройках выключена маска путей, соответствующая стандартному пути к Unreal Engine. Если вы используете Unreal Engine, собранный из GitHub, добавьте корректную маску).

7bb493010058a862ced72b7c3588d4fc.png

После перезапуска анализа получаем такой отчёт:

e4fac2fdc153f1e89e496a9f71d2101e.png

Предупреждений стало меньше, и с ними уже можно удобно работать.

Настройка через .target.cs

Теперь рассмотрим второй способ запуска анализатора PVS-Studio.

Как и другие настройки, включение анализа можно настроить в .target.cs файлах. Этот способ наиболее удобен в случае, если приходится часто перегенерировать проектные файлы. В этом сценарии модификация NMake команд не подходит, так как при новой генерации решения они не будут сохранены.

Для интеграции PVS-Studio в UE нужно добавить в .target.cs файл параметр StaticAnalyzer со значением StaticAnalyzer.PVSStudio.

В файле LyraGame.Target.cs это будет выглядеть так:

public class LyraGameTarget : TargetRules
{
  public LyraGameTarget(TargetInfo Target) : base(Target)
  {
    Type = TargetType.Game;
    
    ExtraModuleNames.AddRange(new string[] { "LyraGame" });

    StaticAnalyzer = StaticAnalyzer.PVSStudio; 

        LyraGameTarget.ApplySharedLyraTargetSettings(this);
  } 
  ....
}

В .target.cs файле можно указать ещё несколько настроек, специфичных для PVS-Studio, например, включение групп диагностик или тайм-аут анализа. Больше о настройках можете прочитать в документации. Эти же настройки можно указать и в интерфейсе плагина PVS-Studio.

3d000ec63edd19616721263491d8bfab.png

Ещё в .target.cs файле можно определить общие настройки UnrealBuildTool, которые будут исполняться только при анализе. Для этого добавьте такое условие:

if (StaticAnalyzer == StaticAnalyzer.PVSStudio)
{
  //Настройки
}

Одной из настроек, для которой применим этот сценарий, является отключение механизма unity build.

Механизм unity build — это метод ускорения сборки С++ проекта, при котором несколько единиц трансляции объединяются в одну. По умолчанию этот режим включён в UnrealBuildTool.

Так как С++ анализатор PVS-Studio проверяет именно единицы трансляции, то в логе анализа мы видим, что анализируются не исходные файлы, а объединённые файлы с префиксом Module.

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

Отключить этот режим только для анализа можно с помощью следующего кода:

if (StaticAnalyzer == StaticAnalyzer.PVSStudio)
{
  bUseUnityBuild = false;
}

На этом с настройкой анализа можно закончить.

Новые диагностики

В PVS-Studio начинают появляться специфичные для Unreal Engine проектов диагностики.

Например, диагностическое правило V1100. Оно говорит о том, что в классе, не унаследованном от UObject, было обнаружено поле в виде указателя на тип, унаследованный от UObject. Сборщик мусора Unreal Engine может уничтожить объект, адресуемый этим указателем.

Другой пример — диагностика V1102. В ней анализатор отмечает сущности, которые не соответствуют соглашению о именованиях для Unreal Engine проектов. Например, имена классов, наследуемых от UObject, следует начинать с префикса U, а перечисления следует начинать с префикса E. Соответствие соглашениям требуется для корректной работы Unreal Header Tool.

Заключение

Настроить работу анализатора PVS-Studio с Unreal Engine проектом довольно просто. В будущих релизах Unreal Engine и PVS-Studio появятся новые возможности по конфигурации анализа. Следите за нашими обновлениями.

Для тех, кто заинтересовался совместным использованием этих продуктов: по этой ссылке вы можете скачать анализатор, а здесь узнать больше об интеграции PVS-Studio c Unreal Engine.

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Mikhail Evtihevich. Setting up static analysis for Unreal Engine project.

© Habrahabr.ru