Keywords: UE4, Build.cs

How to get the current project directory

New way

using System.IO;
using UnrealBuildTool;  

public class MyProject : ModuleRules  
{
    private string ProjectRoot
    {
        get
        {
            return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../"));
        }
    }

    private string ThirdPartyPath
    { 
        get 
        { 
            return Path.GetFullPath(Path.Combine(ModuleDirectory, ProjectRoot, "ThirdParty")); 
        }
    }

    public MyProject(ReadOnlyTargetRules Target) : base(Target)
    {  

    }  
}

Reference:
https://answers.unrealengine.com/questions/237166/how-can-i-get-the-current-project-path-within-the.html

Old way (Removed in 4.21)

using System.IO;  
using UnrealBuildTool;  

public class MyProject : ModuleRules  
{  
    RulesAssembly r;  

    private string ModulePath  
    {  
        get { return Path.GetDirectoryName( r.GetModuleFileName(this.GetType().Name).CanonicalName); }  
    }  

    private string ThirdPartyPath  
    {  
        get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }  
    }  

    public MyProject(TargetInfo Target)  
    {  
        FileReference CheckProjectFile;  
        UProjectInfo.TryGetProjectForTarget("MyProject", out CheckProjectFile);  
        r = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile);  
    }
}
How to include third party libraries

Example:

using UnrealBuildTool;
using System.IO;

public class TestTD : ModuleRules
{
    private string ProjectRoot
    {
        get
        {
            return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../"));
        }
    }

    private string ThirdPartyPath
    { 
        get 
        { 
            return Path.GetFullPath(Path.Combine(ModuleDirectory, ProjectRoot, "ThirdParty")); 
        } 
    }

    public TestTD(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule" });

        LoadOpenCV(Target);
    }

    public bool LoadOpenCV(ReadOnlyTargetRules Target)
    {    
        // Start OpenCV linking here!
        bool isLibrarySupported = false;

        //Library path
        string PlatformString = null;
        string libSuffix = null;
        switch (Target.Platform)
        {
            case UnrealTargetPlatform.Win64:
            {
                PlatformString = "Win64";
                libSuffix = ".lib";
                break;
            }
            case UnrealTargetPlatform.Android:
            {
                PlatformString = "Android";
                libSuffix = ".a";
                break;
            }
        }

        bool isdebug = Target.Configuration == UnrealTargetConfiguration.Debug;
        string DebugLibNameFlag = "";
        if(isdebug)
        {
            DebugLibNameFlag = "d";
        }

        if (null != PlatformString)
        {
            //LibrariesPath value for Windows in Debug: D:\MyProj\ThirdParty\OpenCV\Libraries\Win64\opencv_world348d.lib
            string LibrariesPath = Path.Combine(ThirdPartyPath, "OpenCV", "Libraries", PlatformString, "opencv_world348" + DebugLibNameFlag + libSuffix);
            PublicAdditionalLibraries.Add(LibrariesPath);

            System.Console.WriteLine("++++++++++++ Set OpenCV Libraries: " + LibrariesPath + "\r");
        }

        //Include path
        string IncludePath = Path.Combine(ThirdPartyPath, "OpenCV", "Includes");
        PublicIncludePaths.Add(IncludePath);

        System.Console.WriteLine("++++++++++++ Set OpenCV Includes: " + IncludePath + "\r");

        PublicDefinitions.Add(string.Format("WITH_OPENCV_BINDING={0}", isLibrarySupported ? 1 : 0));

        return isLibrarySupported;
    }
}

If want to include a number of libraries, you can do like this:

// Add static library search path 
PublicLibraryPaths.Add(LibPath);

PublicAdditionalLibraries.Add("opencv_calib3d340.lib");
PublicAdditionalLibraries.Add("opencv_core340.lib");
PublicAdditionalLibraries.Add("opencv_cudaarithm340.lib");
PublicAdditionalLibraries.Add("opencv_cudabgsegm340.lib");

// Add shared library search path
PublicRuntimeLibraryPaths.Add(DllPath);

PublicDelayLoadDLLs.Add("opencv_calib3d340.dll");
PublicDelayLoadDLLs.Add("opencv_core340.dll");
PublicDelayLoadDLLs.Add("opencv_cudaarithm340.dll");
PublicDelayLoadDLLs.Add("opencv_cudabgsegm340.dll");

Reference:
[UE4]UnrealBuildTool APIs in common
https://dawnarc.com/2019/07/ue4unrealbuildtool-apis-in-common/

PublicLibraryPaths was renamed to PublicSystemLibraryPaths in v4.24.

How to disable compilication warning upon third party headers included

Example:

THIRD_PARTY_INCLUDES_START
#include "libwebsockets.h"
THIRD_PARTY_INCLUDES_END
How to shadow macros on Windows that are the same name as Unreal?

Example:

#include "Windows/AllowWindowsPlatformTypes.h"
#include <windows.h>
#include "Windows/HideWindowsPlatformTypes.h"
How to get Visual Studio Compiler Version
public class WebRTC : ModuleRules
{
    public WebRTC(ReadOnlyTargetRules Target) : base(Target)
    {
        //2019 or 2015, and so on.
        string VS_Version = Target.WindowsPlatform.GetVisualStudioCompilerVersionName();
    }
}
Macros on building mode

Engine\Source\Runtime\Core\Public\Misc\Build.h

/*--------------------------------------------------------------------------------
Build configuration coming from UBT, do not modify
--------------------------------------------------------------------------------*/

// Set any configuration not defined by UBT to zero
#ifndef UE_BUILD_DEBUG
    #define UE_BUILD_DEBUG                0
#endif
#ifndef UE_BUILD_DEVELOPMENT
    #define UE_BUILD_DEVELOPMENT        0
#endif
#ifndef UE_BUILD_TEST
    #define UE_BUILD_TEST                0
#endif
#ifndef UE_BUILD_SHIPPING
    #define UE_BUILD_SHIPPING            0
#endif
#ifndef UE_GAME
    #define UE_GAME                        0
#endif
#ifndef UE_EDITOR
    #define UE_EDITOR                    0
#endif
#ifndef UE_BUILD_SHIPPING_WITH_EDITOR
    #define UE_BUILD_SHIPPING_WITH_EDITOR 0
#endif
#ifndef UE_BUILD_DOCS
    #define UE_BUILD_DOCS                0
#endif
How to add macro in build.cs

1st way
Build.cs:

PublicDefinitions.Add("TEST");

C++:

#ifdef TEST
    //other code
#endif

2nd way
Build.cs:

PublicDefinitions.Add("TEST=1");

C++:

#if TEST
    //other code
#endif

using GlobalDefinitions.Add("TEST=1"); if want to give a global macro.

How to disable code optimization
public class MyProj : ModuleRules
{
    public MyProj(ReadOnlyTargetRules Target) : base(Target)
    {
        OptimizeCode = CodeOptimization.InNonDebugBuilds;
    }
}
How to disable function inline in certain modules
public class MyProjTarget : TargetRules
{
    public MyProjTarget(TargetInfo Target) : base(Target)
    {
        if (Configuration == UnrealTargetConfiguration.Debug || Configuration == UnrealTargetConfiguration.DebugGame)
        {
            bUseInlining = false;
        }
    }
}
How to disable function inline and code optimization for whole project

Add:

if (Target.Configuration != UnrealTargetConfiguration.Shipping)
{
    CompileEnvironment.bUseInlining = false;
    CompileEnvironment.bOptimizeCode = false;
}

in Engine\Source\Programs\UnrealBuildTool\Platform\Windows\VCToolChain.cs

Origin:

// Maintain the old std::aligned_storage behavior from VS from v15.8 onwards, in case of prebuilt third party libraries are reliant on it
AddDefinition(Arguments, "_DISABLE_EXTENDED_ALIGNED_STORAGE");

// Fix Incredibuild errors with helpers using heterogeneous character sets
if (Target.WindowsPlatform.Compiler >= WindowsCompiler.VisualStudio2015_DEPRECATED)
{
    Arguments.Add("/source-charset:utf-8");
    Arguments.Add("/execution-charset:utf-8");
}

// Do not allow inline method expansion if E&C support is enabled or inline expansion has been disabled
if (!CompileEnvironment.bSupportEditAndContinue && CompileEnvironment.bUseInlining)
{
    Arguments.Add("/Ob2");
}
else
{
    // Specifically disable inline expansion to override /O1,/O2/ or /Ox if set
    Arguments.Add("/Ob0");
}

New:

// Maintain the old std::aligned_storage behavior from VS from v15.8 onwards, in case of prebuilt third party libraries are reliant on it
AddDefinition(Arguments, "_DISABLE_EXTENDED_ALIGNED_STORAGE");

// Fix Incredibuild errors with helpers using heterogeneous character sets
if (Target.WindowsPlatform.Compiler >= WindowsCompiler.VisualStudio2015_DEPRECATED)
{
    Arguments.Add("/source-charset:utf-8");
    Arguments.Add("/execution-charset:utf-8");
}

if (Target.Configuration != UnrealTargetConfiguration.Shipping)
{
    CompileEnvironment.bUseInlining = false;
    CompileEnvironment.bOptimizeCode = false;
}

// Do not allow inline method expansion if E&C support is enabled or inline expansion has been disabled
if (!CompileEnvironment.bSupportEditAndContinue && CompileEnvironment.bUseInlining)
{
    Arguments.Add("/Ob2");
}
else
{
    // Specifically disable inline expansion to override /O1,/O2/ or /Ox if set
    Arguments.Add("/Ob0");
}
Check if target type is editor, or client, or server
if (Target.Type != TargetType.Server)
{
    PrivateDependencyModuleNames.AddRange(new string[]
    {
        "Imgui"
    });
}

Other ways:

if (Target.Type == TargetType.Editor)

if (Target.bBuildEditor)

我年轻时,听一位教授讲:“人生都只有一个想法,终其一生不过是不断丰富它。”我当时觉得:“一辈子只围绕一个念头转?这未免也太反动了!”五十岁时,我明白他是对的:我这一辈子都在追随一个想法,问题是我从来都不知道是哪个。──翁贝托·埃科《密涅瓦火柴盒》