UE5 Build Configuration 을 이해해 보자 (DebugGame Editor ?)

에크까망·2024년 9월 21일

들어가기 전에

  • 단순화 하기 위해서 문체를 단정적으로 사용하지만 지극히 개인 의견일 뿐 입니다.
  • 본문과 관련해서 오류 지적이나 의견 있으시면 꼭 댓글 부탁드립니다.
  • 글 작성 시점은 2024/09 입니다.
  • 글 작성 기준은 UE5.4.4 입니다.

들어 가며

공식 문서1, 공식문서2 내용을 먼저 살펴 보고 오자. 잘못된 말은 없어 보이고 정리도 깔끔하고 다 좋은데... 뭔가 찜찜하다. 그 찜찜함을 같이 느낀다면 지극히 정상이다(라고 생각한다).

필요 배경 지식

Debug / Release Compile

디버깅할때 변수 값이 제대로 보이지 않는 경우가 있는데 이는 보통 Release 로 컴파일 하고 디버깅을 하기 때문이다.

디버그와 릴리즈 모드에서 가장 큰 차이점은 최적화 여부 이다. 최적화는 크게 두 부분에서 이루어 지는데, 메모리 사용량을 줄이고 코드 양을 줄이는 것이다.

#include <iostream>

int main() {
    int a = 5;
    int b = 10;

    // 릴리즈 모드에서는 이 줄이 최적화될 수 있습니다.
    int result = (a + b) / 2; 

    std::cout << "Result: " << result << std::endl;

    return 0;
}

int result = (a + b) / 2; 에서 변수 'a','b' 값이 Release 모드 에서는 보이지 않을 수 있다. 왜냐하면 변수 'a','b' 가 다른 곳에서 사용되지 않고 따라서 상수 취급 가능하기 떄문에 변수를 확보(Stack)하지 않고 해당 라인을 int result = 15 / 2; 로 변경할 수 있다. 이 경우 변수 'a','b' 자체가 어셈블리 코드에서 삭제 된다.

이는 특히 클래스 멤버함수 안에서 디버깅 할때 두드러 지는데 가끔 클래스 멤버 변수들이 제대로 값 추적이 안되는 경우가 있다. x64 아키텍쳐에서 Microsoft Visual C++ 컴파일러는 'class this pointer' 가 ECX 레지스터 에 저장되고 디버거에서도 ECX 레지스터를 기반으로 값을 보여 준다. 그런데 레지스터 는 정말 중요한 자원이다. 사용 레지스터를 줄일 수 있으면 최적화 여지가 많이 생긴다. 그래서 ECX 레지스터 를 재사용 하는 경우가 많다. 그렇게되면? 값이 제대로 보이지 않는다.

Exe with DLL

Windows OS 특징중 하나가 DLL (Dynamic-Link Library)의 적극 사용이다. 이름에 있듯이 동적으로 코드를 붙였다가 땠다가 할 수 있다. Windows 프로그래밍을 직접 해보면 바로 알 수 있는데 LoadLibrary 로 Dll 을 읽고 특정 Offset 에 있는 함수를 실행하는 식이다. C++ 에서는 .lib 를 이용해서 DLL 에 있는 Class 를 가져다 쓰기 편하게 지원하고 있다.

DLL 에 있는 함수를 사용하기 위해서는 DLL을 만들때 해당 함수를 노출 시켜야 한다. 노출된 함수는 DLL 을 TextEditor 로 열어보면 알아 볼 수 있게 적혀있다.

프로그래밍 하다 보면 우리가 만든 클래스 등에 다음과 같이 MYMODULE_API 붙이는데 class EKUE54_API AMyActor : public AActor 이게 DLL 에 노출하고, 또 떙겨오는 Keyword 이고 노출시킬때(DLL 생성) 사용할때(Load DLL) 약간 다른 키워드를 사용하게 된다. 이는 다른 포스팅에서 추가로 다루기로 하자.

UnrealEditor.exe + UnrealEditor_MyModule.DLL

그럼 우리가 .uproject 를 더블 클릭해서 editor 를 실행하게 되면 어떻게 돌고 있을까? 정답은 UnrealEditor.exe 가 실행되고 우리가 만든 게임코드가 UnrealEditor_MyModule.DLL 로 빌드된 상태에서 로딩 되어 작동한다. 또는 MyModule.exe 로 빌드해서 단독실행 가능하게 할 수도 있다.

이 내용들이 UnrealEngine Build Configuration 을 이해하는데 있어 필요한 사전 지식이다.

Build Configuration

Naming

처음 언급한 '공식 문서' 에 있는 naming 을 먼저 살펴 보자.

참 많다... 위에서 'Debug' 는 LauncherVersionEngine 을 사용할 때는 보이지 않고 Git 에서 Source를 받아 직접 엔진을 직접 빌드해야 볼 수 있다.

이제 하나씩 풀어 보자. 들어가기 에서도 말했지만 공식문서가 틀린 내용은 없으므로 지금부터 하는 말이 중언으로 들릴 수도 있다. 하지만, 에서 의문 부호를 때고 그냥 외우자. 왜냐하면 위 네이밍 규칙은 규칙성이 있음에도 묘하게 탈규칙적 이기 때문이다.

아래에서 Engine 는 언리얼 배포 엔진, Game 은 우리가 보통 만드는 게임 컨텐츠 부분을 뜻한다. LauncherVersion(InstalledVersion) 은 Game 만 변경할 수 있다. (Debug),(Release) 는 위에서 말한 Compile 타입을 말한다.

엄밀하 말해서 Deveopment, Test, Shipping 은 release 로 빌드 하지만 내용이 조금씩 다르다. 이는 Log,Profiling 기능을 어느정도로 담고 있을 거냐로 나뉜다. 하지만 컴파일 타입은 같다.

Client/Server 는 Dedicated Server 기능과 관련이 있는 것으로 여기서는 논외로 한다.

  • Debug : Engine(Debug), Game(Debug), MyModule-Win64-Debug.exe 생성
  • DebugGame : Engine(Release), Game(Debug), MyModule-Win64-DebugGame.exe 생성
  • DebugGame Editor : Engine(Release), Game(Debug), UnrealEditor-MyModule-Win64-DebugGame.dll 생성
  • Development : Engine(Release), Game(Release), MyModule.exe 생성
  • Development Editor : Engine(Release), Game(Release), UnrealEditor-MyModule.dll 생성
  • Shipping : Engine(Release), Game(Release), MyModule-Win64-Shipping.exe 생성

단독 실행

MyModule.exe 로 단독 실행(위에서 뒤에 Editor가 없이)할 때 필요한 내용중 하나가 Contents(Asset)가 Cooking 되어 있어야 한다는 것이다. Cooking 은 날것의 리소스(.uasset)가 해당 실행타겟에 필요한 내용으로 추려서 변경되어 있는 상태를 뜻한다. Cooking 하지 않고 실행하면 처음 보는 내용이

인데, GlobalShader 가 Cooking 되어 있지 않아서 보게 된다. Cooking 은 다음에서 할 수 있다.

그러면 다음 폴더가 생성된다

실행 상태

DebugGame

Development

Development Editor

DebugGame Editor

profile
Game Client Programmer

0개의 댓글