2020/02/16

Unreal 4.2x 이후 Visual Studio 빌드 오류 인코딩 깨짐

집에서 설치판으로 가지고 놀다보니 답답하길래 대충 고쳤다.
utf8과 ascii를 섞어쓰는 양코백이 놈들이 잘못했다.

2020/02/16
4.24.2 설치형 + VS2019 기준으로 작성

Unreal Build Tool에서 입력 출력이 틀려먹었는데,
정확히는 DotNETUtilities에서 잘못 하고 있는게 맞다.

1. 출력
UBT 실행 결과를 VS로 던질 때 UTF-8로 던져야 한다.
Engine\Source\Programs\DotNETCommon\DotNETUtilities\Log.cs
@@ -232,6 +232,7 @@
                        IncludeCallingMethod = true;
                        IncludeCallingMethodForConsole = false;
                        ColorConsoleOutput = true;
+                       Console.OutputEncoding = Encoding.UTF8;
                }

                /// <summary>

2. 입력
컴파일러를 DotNETUtil의 ManagedProcess를 사용해 병렬 처리를 하는데,
실행되는 프로세스의 인코딩을 Console.OutputEncoding과 일치한다고 생각하고 사용하고 있다.
아쉽게도 우리는 cp949로 실행된다.

그래서 일단 두 군데를 고치는데,
ManagedProcess가 초기화 될 때 ReadStream 의 인코딩을 Encoding.Default로 지정해주고,
ReadAllLines에서 ReadStream.CurrentEncoding 을 이용해서 문자열을 해석 하도록 할 것이다.


UE_4.24\Engine\Source\Programs\DotNETCommon\DotNETUtilities\ManagedProcess.cs
@@ -481,7 +481,7 @@

                                        // Create the stream objects for reading the process output
                                        InnerStream = new FileStream(StdOutRead, FileAccess.Read, 4096, false);
-                                       ReadStream = new StreamReader(InnerStream, Console.OutputEncoding);
+                                       ReadStream = new StreamReader(InnerStream, Encoding.Default);

                                        // Wrap the process handle in a SafeFileHandle
                                        ProcessHandle = new SafeFileHandle(ProcessInfo.hProcess, true);
@@ -648,7 +648,7 @@
                                {
                                        if(NumBytesInBuffer > 0)
                                        {
-                                               OutputLines.Add(Console.OutputEncoding.GetString(Buffer, 0, NumBytesInBuffer));
+                                               OutputLines.Add(ReadStream.CurrentEncoding.GetString(Buffer, 0, NumBytesInBuffer));
                                        }
                                        break;
                                }
@@ -664,7 +664,7 @@
                                        {
                                                if(Buffer[Idx] != '\n' || LastCharacter != '\r')
                                                {
-                                                       OutputLines.Add(Console.OutputEncoding.GetString(Buffer, LastStartIdx, Idx - LastStartIdx));
+                                                       OutputLines.Add(ReadStream.CurrentEncoding.GetString(Buffer, LastStartIdx, Idx - LastStartIdx));
                                                }
                                                LastStartIdx = Idx + 1;
                                        }

이렇게 하면 나중에 readstream encoding만 변경하면 readalllines 도 같이 바뀌겠지
뭔가 조금 더 정리해서 적고 싶지만 졸리니까 나중에..

어쨌든 이걸 적용하면 UBT 등등 dotnetutils를 사용해서 외부 프로세스를 띄운 다음 로그를 받아서 에디터나 vs로 띄우는 과정에서 생기는 인코딩 오류가 전체적으로 사라질 것인다.
물론 외부 프로세스 자체가 utf-8 출력을 지원하는 경우에 또 ManagedProcess의 기본값이 Default이기 때문에 오동작 할 수 있을거 같은데 다른 방식으로 풀 수 있지 않을까 싶음