Skip to main content

Configuring your project

With clang-tidy installed, it's now time to configure your project and enable the C++ checks that you want to use. clang-tidy for Unreal Engine ships with both the standard clang-tidy checks, plus Unreal Engine specific checks that help detect errors in your code.

All checks are turned off by default; this allows you to enable only the checks you want in your project.

Make sure Unreal Build Tool has clang-tidy extensions registered

When you run a build from your IDE or the command line, you should see this line in the output from Unreal Build Tool:

Hooked Windows platform with clang-tidy extensions...

If you do not see this, then the installation process isn't complete. If you followed all of the steps listed on that page and still can't see that line, please contact support.

In addition, clang-tidy currently only runs when you are targeting the Win64 platform. Make sure you are targeting that platform in your IDE when building in order for clang-tidy checks to run.

Creating a ClangTidy.lua file

clang-tidy for Unreal Engine is configured with a Lua script that you place in your project. clang-tidy settings apply on a per-module basis, so the recognised locations for a ClangTidy.lua file are:

  • <Project>/Source/Module/ClangTidy.lua: Applies to just the Module module.
  • <Project>/Source/ClangTidy.lua: Applies to all of the modules in the project. This location is not recommended however, because the ClangTidy.lua file will not appear in the Visual Studio Solution Explorer.
  • <Plugin>/Resources/ClangTidy.lua: Applies clang-tidy settings to a particular plugin.
  • <Project>/ClangTidy.lua: Applies to all of the modules in the project (not plugins). The recommended location for most configurations.

clang-tidy will try to find the ClangTidy.lua file in the order shown above. ClangTidy.lua files are not cumulative; the first one that is found is the one that is used and all others are ignored. You can however, include other files in Lua using the require directive. Refer to the Lua reference manual for more information on this.

To get started, let's create a ClangTidy.lua file in the root of your project, next to your .uproject file, and add the following content to it:

-- Enable a built-in check that detects unnecessary copies caused by
-- for range loops where the iterator is not by reference.
enable_checks("performance-for-range-copy")

-- Enable an Unreal Engine check where you incorrectly call Remove()
-- on an array reference that still points into the array.
enable_checks("unreal-broken-array-call")

-- Treat both of these as errors, not warnings.
treat_as_errors("performance-for-range-copy")
treat_as_errors("unreal-broken-array-call")

-- TIP: You can also use wildcards like "unreal-*" to enable all Unreal
-- Engine checks or treat all Unreal Engine checks as errors.
info

If you need a good starting point for your project, refer to Recommended starter script.

For a full list of checks you can enable, refer to Available built-in checks.

For information on how to write your own custom checks, refer to Writing custom checks.

Test clang-tidy in your project

With the checks enabled, let's make sure it's correctly picking up invalid code in your project. Find a function in any of the .cpp files located in your project's Source folder, and add the following test code to it:

TArray<FString> Arr;
for (auto Val : Arr)
{
Arr.Remove(Val);
}

Now when you build your project, you'll get an error about Val being a value type and causing an unnecessary copy. You can then fix this code by changing it to:

TArray<FString> Arr;
for (const auto& Val : Arr)
{
Arr.Remove(Val);
}

Now if you build your project, you'll get an error about Val being a reference passed directly into Remove() from an iterator on the for loop. It is a requirement of the Remove() API in Unreal Engine that the parameter is not a reference to the array's memory.

You can then fix this issue by changing the code to the final version:

TArray<FString> Arr;
for (int i = 0; i < Arr.Num(); i++)
{
Arr.RemoveAt(i);
}

Turning off clang-tidy on a per-module basis

If you've specified a ClangTidy.lua file for your whole project, you can individually turn off clang-tidy for certain modules by adding the following code to that module's .Build.cs file:

PrivateDefinitions.Add("ModuleName_ENABLE_CLANG_TIDY=0");

Replace ModuleName with the name of the module.

Next steps

If the tests above were picked up by clang-tidy, your project is configured correctly. You can now configure rules specific to your project by referring to: