Differing CPP standards across modules

Hello,

We have been puzzled by a few build settings and were seeking some clarity on how to use them.

Exposed to target.cs files via TargetRules is a CppStandard and an CppStandardEngine.

What we want to do is compile the engine with the Default Cpp Version (Cpp20) and let our game module compile against latest (Cpp23/26). The above variables seem to suggest that we can do this, and there are even engine modules that seem to set their CppStandard to other values (such as Cpp17). But when we attempt to set these in our TargetRules, the entire engine builds with the CppStandard is set to, not what CppStandardEngine is set to.

So the question is: how are these two properties intended to be used. Can they be used together to split what CPP version is compiled across the engine and other modules? Or does something like this go against practices or not make sense?

Thanks,

Blake

Hi,

You should set the C++ Standard in your Build.cs for each module you want to change it. They are few *.Build.cs in the engine where the standard is explicitly specified. If you set it in the Target.cs, you set it for the entire build.

CppStandard = CppStandardVersion.Cpp20; // or CppStandardVersion.LatestCurrently, you cannot explicitly set Cpp23 or Cpp26 and the ‘Latest’ depends on the compiler:

D:\UE_5.6\Engine\Source\Programs\UnrealBuildTool\Platform\Windows\VCToolChain.cs

	case CppStandardVersion.Latest:
	Arguments.Add("/std:c++latest");

D:\UE_5.6\Engine\Source\Programs\UnrealBuildTool\ToolChain\ClangToolChain.cs

	case CppStandardVersion.Latest:
	Arguments.Add(CompilerVersionLessThan(13, 0, 0) ? "-std=c++20" : "-std=c++2b");

The engine is not tested with the latest standard, so you may encounter issues if you include UE headers into the C++ code you compile with the latest C++ standard.

Regards,

Patrick

Hi Blake,

Yes, that’s correct. I didn’t test it, but that’s how I expect it to work. Let me know if you have follow up questions. Be careful with the C++ standard if you need to deploy on many platforms. The compilers on various platforms doesn’t all have the same set of support.

Regards,

Patrick

By they way, if you want to verify which C++ standard is used to compile a file, you can look at the response file (.rsp) file generated by UBT. The .rsp file contains the compiler command line. They are found in the Intermediate folder (Ex: D:\UE_5.6\Samples\Games\Lyra\Intermediate\Build\Win64\x64\LyraGameNU\Development\Json\JsonTests.cpp.obj.rsp). See the screenshot for an example.

[Image Removed]

Hi,

I tried with Lyra. I modified D:\UE_5.6\Samples\Games\Lyra\Source\LyraGame\LyraGame.Build.cs

CppStandard = CppStandardVersion.Latest;Compiled the Win64/Development target with MSVS and it compiled successfully. I picked up a game .cpp and an engine .cpp that was listed in the build log and looked at their .rsp:

...
1>Compile [x64] Module.GeometryAlgorithms.2.cpp [ Time 49.38 s ]
1>Compile [x64] Module.LyraGame.1.cpp [ Wall Time 48.33 s / CPU Time 27.44 s ]
1>Compile [x64] Module.CommonUI.cpp [ Wall Time 47.03 s / CPU Time 56.70 s ]
1>Compile [x64] Module.Engine.60.cpp [ Wall Time 21.63 s / CPU Time 43.36 s ]
...

The game file Module.LyraGame.1.cpp is compiled with latest C++ standard: D:\UE_5.6\Samples\Games\Lyra\Intermediate\Build\Win64\x64\LyraGame\Development\LyraGame\Module.LyraGame.1.cpp.obj.rsp

...
/GR-
/std:c++latest
/Zc:preprocessor
/wd5054
...

The engine file Module.Engine.60.cpp is compiled with ++20: D:\UE_5.6\Samples\Games\Lyra\Intermediate\Build\Win64\x64\LyraGame\Development\Engine\Module.Engine.60.cpp.obj.rsp

...
/GR-
/std:c++20
/Zc:preprocessor
/wd5054
...

Lyra doesn’t use any C++ 23/26 feature and I used MSVC toolchain, but that’s how you should verify your setup. If you get error around C++ 23/26 features you are trying while you have with the expected standard set in the .rsp file, then maybe your compiler version don’t support yet that feature. You could probably look at clang documentation and check how to specify the standard and replace std=c++2b with the value specified in the compilateur documentation to enable C++23 or 26?

D:\UE_5.6\Engine\Source\Programs\UnrealBuildTool\ToolChain\ClangToolChain.cs

case CppStandardVersion.Latest:
Arguments.Add(CompilerVersionLessThan(13, 0, 0) ? "-std=c++20" : "-std=c++2b");

Regards,

Patrick

Hi Patrick,

Thanks for your help on this issue.

We were able to verify that compiling independent modules on separate C++ versions works as desired. However, as one would expect, any header files from the engine included in a module will be compiled using the module’s C++ version.

The issue is that C++26 officially deprecated arithmetic conversion on enumerations(P2864R2). The errors we get are exactly this. MSVC and Clang differ in their implementation status of C++23/26, specifically that the latest stable MSVC version has not yet implemented P2864R2. This explains why they are not showing up for you.

These errors show up in a many header-implemented classes, really any that use anonymous enum arithmetic, such as:

StatSystemTypes.h
SHMath.h
NetConnection.h
UnrealType.h

We have experimented with various combinations of Clang compile versions and C++ standards, but unfortunately, there is no combination that both meets our needs (our original reason for attempting to use a newer standard) and suppresses this compile error to a warning.

Moreover, the scope of the fix across the engine required for compliance with the new standard is extremely broad. There are too many for us to fix internally, so we want to put this on your radar, hopefully for future versions of UE.

Warmly,

Will

P.S

For clarity, you should be able to reproduce this issue with the following:

C:\Program Files\Microsoft Visual Studio\2022\Community>clang --version
clang version 19.1.5
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin

And, in `x.Target.cs`

CppStandard = CppStandardVersion.Latest;

Including standard core engine headers

Hi,

I was able to reproduce and I created a JIRA for it. Hopefully, it will get resolved quickly. The JIRA should become public in the next few days and should be under the available at: Epic Games - Sign In

Regards,

Patrick

Actually, the public link will be: Unreal Engine Issues and Bug Tracker (UE\-326372\). I pasted the internal one above.

Hi Patrick,

Thanks for your reply. Just to be confirm: I think you are staying that CppStandard value in the TargetRules will override the CppStandardEngine value, if it is set. This seems to be in line with how I read CreateModuleCompileEnvironment() in UEBuildModuleCPP.cs.

And furthermore, if we do want CppStandard changes these should be set in the ModuleRules not the TargetRules. Does this sound correct?

Thanks,

Blake

Hi Patrick,

Thanks for the insight and cautions. Below are some configurations we have tested and their results. Another note: we are compiling with Clang (still using the MSVC toolchain though).

---------------------------------------

GAME MODULE RULES: CppStandard NOT Set

TARGET RULES: CppStandard NOT set, CppStandardEngine NOT set

RESULT: Engine is built with Cpp20, no errors

---------------------------------------

GAME MODULE RULES: CppStandard set to latest

TARGET RULES: CppStandard NOT set, CppStandardEngine NOT set

RESULT: Engine fails to build with Cpp26 errors

---------------------------------------

GAME MODULE RULES: CppStandard set to latest

TARGET RULES: CppStandard NOT set, CppStandardEngine set to Cpp20

RESULT: Engine fails to build with Cpp26 errors

---------------------------------------

Curious to see if this is the behavior you are expecting. If I am looking at these RSP files correctly, I *think* the engine is being built in Cpp20, but maybe the includes in our Game Module are getting compiled in Cpp26, which is causing the errors. Guessing this is possible behavior?

We are simply trying to compile a few game modules with latest as we want to take advantage of some of the Cpp23/26 features. But guessing it may not be possible if the above theory is correct. In that case it would make sense that CppStandard and CppStandardEngine is really there to allow modules to downgrade the version they are using, not upgrade it.

Thanks,

Blake

Thanks for looking into this with us Patrick. We’ll be following issue. Hopefully it is addressed soon.

Thanks,

Blake