前言

  这次尝试在 VScode 进行引擎编译。
  网上一查发现,官方其实有做支持的,具体可以参考这篇文章 链接
  这篇文章传播甚广,可以参照和这个方式配置 VScode 编译。

https://www.youtube.com/watch?v=fydvKedIxKk
https://github.com/boocs/ue4-tellisense-fixes

C++ 编译过程

深度参考学习这边文章 https://ericlemes.com/2018/11/21/compiling-c-code/
鉴于本人的 C++ 水平一般,建议阅读原文

编译步骤

  C++ 编译可能会用到下面的文件。

  • .cpp 文件编译成 .obj
  • 生成静态库 .lib
  • 生成动态库 .dll
  • 生成可执行文件 executable

VS 工具链

  .sln 全称是 solution 解决方案,是 VS 的项目配置文件。 (整合了 .vcxproj .csproj)
  他可以同时配置多个项目,最后通过 MSBuild 来构建
  sln 包含了项目的各种头文件依赖,库引用等描述,执行顺序,通过这个 IDE 就知道怎么编译你的项目。

  Xcode 的情况也是类似的。
  其中比较特别的时 CMake ,通过 CMakeLists.txt 文件可以根据不同平台生成工程配置文件。

第一步 编译

输入:

  • Defines
  • Include 文件夹路径Include directories
  • 预编译头文件 (如果有用到的话)
  • 源代码

输出:

  • .obj 文件

  MSBuild 使用 CL.exe 进行 C++ 编译。 可能的路径 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\cl.exe
  需要安装 VS 或者用 choco 来安装

  编译的时候会根据 宏定义(比如 #ifdef)动态 改变编译行为
  通过这个方式可以在不同的平台编译出不同的行为。
  C++ 最终编译成对应平台的二进制,这个设计和 Java C# 都不同。

  头文件最终会拼接到 C++ 里面进行编译,所以需要加上 #pragma once 或者 #if 来避免多次定义。
  预编译头则可以生成 .pch 文件实现头文件复用。

第二步 链接

输入:

  • 一些源码生成 .obj 文件
  • 一些源码生成 .lib 文件
  • 第三方的 lib 和 obj 文件

输出:

  • .dll 或者 .exe

  这一步会将生成的中间文件合并成 dll 或者 exe
  这个过程会完成很多优化的步骤,把不运行的部分清理掉。
  最后会将一些平台的 lib 引入确保它在平台上可以运行,比如 wincrt (Windows C Runtime library) 等等
  并且 lib 也有很多种类,有 release 版本和 debug 版本等等。

Unreal Build Tool

https://ericlemes.com/2018/11/23/understanding-unreal-build-tool/

CS 配置文件说明

https://www.bilibili.com/read/cv15297017/

  Unreal 使用自己开发的 UnrealBuildTool 来编译自己的 C++ 代码
  与 💾CMake 类似的,UnrealBuildTool 会引用你需要在相应的模块添加 .build.cs 的代码文件来描述仓库链接的东西。
  .build.cs 之上配套了 Private Public 文件夹分别放置暴露和不暴露的代码。
  .target.cs 则可以用来定义输出的类型,有 Game Editor Client Server 几种类型。

生成工程文件

  当我们对 uproject 文件右键生成 project 的时候背后执行就是 UnrealBuildTool

image

1
C:/EpicGames/git/UnrealEngine-4.27/Engine/Binaries/DotNET/UnrealBuildTool.exe  -projectfiles -project="D:/EpicGames/test_plugin/test_plugin.uproject" -game -engine -progress -log="D:\EpicGames\test_plugin/Saved/Logs/UnrealVersionSelector-2022.07.12-15.50.08.log"

  UnrealBuildTool 会根据 .build.cs.target.cs 里面配置模块路径生成 sln 工程文件。

编译 C++

image

1
D:/EpicGames/UE_4.27/Engine/Binaries/DotNET/UnrealBuildTool.exe Development Win64 -Project="D:/EpicGames/Unreal_Playground/Unreal_Playground.uproject" -TargetType=Editor -Progress -NoEngineChanges -NoHotReloadFromIDE

  这个 Build.bat 背后还是调用 UnrealBuildTool.exe 通过它来编译 C++
  上面生成工程时候 .build.cs.target.cs 只是收集了路径。
  现在会再次读取这两个文件来获取一些编译用的属性。
  然根据配置解决各个模块的依赖关系。

  最后会运行 UnrealHeaderTool 将 UObject 的一些特性注入到 UObject 的 cpp 文件当中。
  这也说明了为什么需要引入 .generated.h 的头文件。
  准备好了所有代码之后再调用相应的编译工具去构建 C++。

VScode 编译配置

  了解了 C++ 编译和 Unreal 全家桶的编译逻辑之后。
  我们终于可以回归到本篇文章的正题。

http://jollymonsterstudio.com/2018/11/02/unreal-c-with-visual-studio-code/

  按照这里提供的文章就可以用 Unreal 官方的方式配置好 .vscode 目录的编译配置。
  后续只要 Ctrl + shift + B 就可以触发编译。
  编译背后的逻辑就在上面解释了。

  相应的我也可以用 python 脚本来触发编译。
  sln 工程并不是必须的,不过 VS 有 VA 查找代码比较快。