Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

Visual C++ 컴파일 오류 - error C2220: warning treated as error - no 'object' file generated

얼마 전에 공개된 윈도우 계산기의 소스 코드를,

Microsoft/calculator
; https://github.com/Microsoft/calculator

내려받아,

E:\git_clone> git clone https://github.com/Microsoft/calculator.git
Cloning into 'calculator'...
remote: Enumerating objects: 2939, done.
remote: Total 2939 (delta 0), reused 0 (delta 0), pack-reused 2939
Receiving objects: 100% (2939/2939), 20.09 MiB | 5.45 MiB/s, done.
Resolving deltas: 100% (1715/1715), done.

빌드하려면 Visual Studio 2019를 설치하고 다음의 구성 요소를 함께 선택해야 합니다.

Universal Windows Platform Development
	- C++ (v141) Universal Windows Platform tools
	- Windows 10 SDK (최신 버전)

이후 E:\git_clone\calculator\src\Calculator.sln 파일을 Visual Studio 2019에서 열어 툴바의 ARM64로 맞춰진 플랫폼을 x64로 바꿔줍니다.

src_encode_1.png

자... 이제 솔루션 빌드를 하면, 다음과 같은 에러 및 경고를 볼 수 있습니다.

1>------ Rebuild All started: Project: CalcManager, Configuration: Debug x64 ------
1>pch.cpp
...[생략]...
2>CalculatorButtonPressedEventArgs.cpp
2>CalculatorDisplay.cpp
2>ConversionResultTaskHelper.cpp
2>CopyPasteManager.cpp
2>e:\git_clone\calculator\src\calcviewmodel\common\copypastemanager.cpp(1): error C2220: warning treated as error - no 'object' file generated
2>e:\git_clone\calculator\src\calcviewmodel\common\copypastemanager.cpp(1): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss
...[생략]...
4>HistoryTests.cpp
4>e:\git_clone\calculator\src\calculatorunittests\currencyconverterunittests.cpp(1): error C2220: warning treated as error - no 'object' file generated
4>e:\git_clone\calculator\src\calculatorunittests\copypastemanagertest.cpp(1): error C2220: warning treated as error - no 'object' file generated
4>e:\git_clone\calculator\src\calculatorunittests\currencyconverterunittests.cpp(1): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss
4>e:\git_clone\calculator\src\calculatorunittests\copypastemanagertest.cpp(1): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss
4>e:\git_clone\calculator\src\calculatorunittests\copypastemanagertest.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\currencyconverterunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\historytests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\calcenginetests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\calcinputtest.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>CurrencyHttpClient.cpp
...[생략]...
4>StandardViewModelUnitTests.cpp
4>e:\git_clone\calculator\src\calculatorunittests\datecalculatorunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\calculatormanagertest.cpp(6): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>UnitConverterTest.cpp
4>UnitConverterViewModelUnitTests.cpp
4>e:\git_clone\calculator\src\calculatorunittests\module.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>UnitTestApp.xaml.cpp
4>e:\git_clone\calculator\src\calculatorunittests\standardviewmodelunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>UtilsTests.cpp
4>e:\git_clone\calculator\src\calculatorunittests\navcategoryunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>XamlTypeInfo.Impl.g.cpp
4>e:\git_clone\calculator\src\calculatorunittests\multiwindowunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\unitconverterviewmodelunittests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\unitconvertertest.cpp(6): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>e:\git_clone\calculator\src\calculatorunittests\utilstests.cpp(5): fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory
4>Done building project "CalculatorUnitTests.vcxproj" -- FAILED.
...[생략]...

항목이 많은데 대체로 다음의 2가지로 나뉩니다.

error C2220: warning treated as error - no 'object' file generated
warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss

fatal error C1083: Cannot open include file: 'CppUnitTest.h': No such file or directory

하나씩 해결해 볼까요? ^^




우선 가장 많이 나타나는 C1083 오류를 먼저 해결해 보겠습니다. 이 오류는 Visual Studio 2019만 설치했을 때 발생하는 오류인데요, CppUnitTest.h 파일은 실제로 다음과 같은 경로에 존재합니다.

[Visual Studio 2019 Community 버전인 경우]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\VS\UnitTest\include\UWP

하지만 CalculatorUnitTests 프로젝트의 Platform Toolset 값이 "Visual Studio 2017 (v141)"로 되어 있기 때문에 CppUnitTest.h 파일을 2017을 기준으로,

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\VS\UnitTest\include\UWP

찾게 됩니다. 따라서 이런 경우에는 "CalculatorUnitTests" 프로젝트의 속성 창에서 "General" 범주의 "Platform Toolset" 값을 "Visual Studio 2019 (v142)"로 맞춘 후 빌드하면 됩니다.




그다음 C2220 오류는 C4819 경고 때문에 발생하는 것으로 Calculator 관련 프로젝트들은 모두 경고가 발생한 경우 오류로 취급하라고 설정되어 있기 때문입니다. 따라서 해당 프로젝트의 속성 창에서 "C/C++" / "General" 범주의 "Treat Warnings As Errors" 옵션을 "No (/WX-)"로 바꾸면 오류는 없앨 수 있습니다.

물론, 그렇다고 해서 C4819 경고가 사라지는 것은 아닙니다. (Rebuild하면 C4819 경고가 발생합니다.) 이 경고는 해당 소스 코드 파일에 시스템의 Locale 설정으로는 표현할 수 없는 문자가 들어 있기 때문에 이를 알려주는 것인데요. 근본적인 원인은 해당 소스 코드를 만든 개발자가 파일의 Locale을 유니코드 처리를 하지 않았기 때문입니다. 예를 들어 위의 오류를 보면,

warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss

현재 Visual Studio가 실행되고 있는 윈도우 환경에서는 949 (확장 완성형) 코드 페이지로 설정되어 있지만 소스 코드 파일에는 949 코드 페이지에 속하지 않은 문자를 포함하고 있다는 것입니다. 그리고 해결책도 함께 알려주고 있는데요, 유니코드 포맷으로 변경해 저장하라는 것입니다.

여기서 문제라면, 유니코드 포맷으로 저장하는 것 자체가 좀 애매하다는 것이 문제입니다. 실제로 해당 경고가 발생한 "CopyPasteManagerTest.cpp" 파일은 UTF-8 포맷으로 저장된 상태이기 때문에 원래는 오류가 발생해서는 안 됩니다. 하지만 그 파일이 UTF-8 포맷으로 저장한 것인지 직접적으로 알 수 있는 방법이 없습니다. 윈도우 환경에서는 그동안 이 문제를 해결하기 위해 BOM을 명시적으로 파일의 선두에 쓰는 방법을 선호했는데, 따라서 UTF-8로 저장되었다는 것을 알리는 "ef, bb, bf" 바이트가 있어야 합니다.

그렇다면 왜 그 파일에는 BOM 바이트가 없을까요? 그 이유는, UTF-8의 경우 관행적으로 BOM을 표시하지 않는다는 데에 있습니다. 이 현상은 리눅스 진영에서 더 심한데, 리눅스 플랫폼에서는 UTF-8에 대해 BOM을 표시하지 않고 있으며 근래 마이크로소프트가 Linux 친화적인 환경을 도입하면서 이에 따라 마찬가지로 UTF-8에 대해 BOM을 표시하지 않는 문화로 점차 바뀐 것 같습니다.

어쩔 수 없이 이제 공은 비주얼 스튜디오의 편집기를 작성한 개발자에게 넘어갑니다. 편집기 개발자는 BOM도 없는 파일이 어떤 인코딩을 따르도록 작성된 것인지 유추를 해야 합니다. 당연히 이 유추 코드는 완벽할 수는 없으며 CopyPasteManagerTest.cpp 파일처럼 대부분의 문자가 영문으로 작성된 경우 그냥 윈도우 시스템의 로케일 설정을 따르는 것으로 판단을 하게 만든 듯합니다.

이쯤 되면 근본적인 해결책이 나옵니다. 해당 파일을 (한 예로 메모장으로) 열어서 명시적으로 "UTF-8"로 저장하면 됩니다.




간혹, 너무 많은 파일이 C4819 경고가 발생하면 저렇게 일일이 UTF-8로 저장하는 것도 여간 귀찮은 작업이 아닐 수 없습니다. 그런 경우에는 해당 폴더의 소스 코드 파일을 전부 읽어서 UTF-8로 저장하는 프로그램을 간단하게 만들어 사용하면 됩니다. 혹은 다른 방법도 있습니다. 결국 편집기 개발자가 파일을 유추해서 적당한 경우 시스템의 Locale 설정을 따른다는 점을 해결하면 됩니다. 즉, 시스템의 Locale을 UTF-8로 바꾸면 되는 것입니다. 다행히 이에 대한 옵션이 윈도우 10부터 (2019-04-05 기준) 베타 딱지를 달고 배포된 상태입니다.

영문 설정의 Windows 10 명령행 창(cmd.exe)의 한글 지원
; https://www.sysnet.pe.kr/2/0/11559

따라서 "Beta: Use Unicode UTF-8 for worldwide language support" 옵션을 켜 두면 UTF-8로 인한 C4819 경고는 없앨 수 있습니다.




참고로 Visual Studio에서 제공하는,

Visual Studio 의 '새 파일'을 UTF-8 인코딩으로 지정하는 방법
; https://www.sysnet.pe.kr/2/0/1349

"Save documents as Unicode when data cannot be saved in codepage" 옵션은 파일 자체의 인코딩을 UTF-8로 바꿔는 주는데 BOM은 붙이지 않습니다. (아마도 Microsoft의 개발자들이 이 옵션을 사용하고 있는 것이 아닌가 예상합니다.)




마지막으로, 간혹 운이 안 좋다면 C4819 경고는 엉뚱하게 컴파일 문법을 발생시킵니다. 아래의 경우가 그 사례입니다.

이번에 오픈소스로 공개된 계산기 엡에 관한 질문입니다.
; https://social.msdn.microsoft.com/Forums/ko-KR/be42cd32-47ec-4084-bdab-de7ea4a6372d/510604826450640-5072454536495484982847196-442774406046108?forum=vsko

중간에 보면 다음과 같은 경고가 나오는데요.

3>c:\users\c0001\source\repos\calculator-master\calculator-master\src\calculatorunittests\currencyconverterunittests.cpp(1): warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.
3>c:\users\c0001\source\repos\calculator-master\calculator-master\src\calculatorunittests\currencyconverterunittests.cpp(92): fatal error C1075: '{': 일치하는 토큰을 찾을 수 없습니다.

949 코드 페이지에서 표현할 수 없는 문자가 들어있는데, 하필 그것이 2바이트 이상의 UTF-8 인코딩의 조합과 엮이게 되면 그다음 바이트와 합쳐져서 한 글자를 이루게 되는 것입니다. 즉, 위의 경우에는 "}" 글자와 합쳐진 선행 문자가 있는 것입니다. 다행히 이번 경우에는 파일 자체가 UTF-8로 인코딩되어 있기 때문에 명시적으로 UTF-8 BOM이 있는 파일로 저장해 주면 해당 문제는 사라질 것입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 11/24/2020]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  [154]  155  156  157  158  159  160  161  162  163  164  165  ...
NoWriterDateCnt.TitleFile(s)
1203정성태12/21/201125587제니퍼 .NET: 18. MEF가 적용된 ASP.NET 웹 사이트를 제니퍼 닷넷으로 모니터링 해본 결과! [6]
1202정성태12/21/201126086오류 유형: 144. The database '...' cannot be opened because it is version 661.
1201정성태12/14/201141132디버깅 기술: 47. .NET Reflector를 이용한 "소스 코드가 없는" 어셈블리 디버깅 [4]
1200정성태12/11/201126967디버깅 기술: 46. Windbg 확장 DLL 만들기 (2) - Debugger Extension API 사용파일 다운로드1
1199정성태12/11/201128374VC++: 55. JNI DLL 컴파일 시 x86과 x64의 Export된 함수의 이름이 왜 다를까요? [2]파일 다운로드1
1198정성태12/9/201132195디버깅 기술: 45. Windbg 확장 DLL 만들기 (1) - 스레드를 강제 종료시키는 명령어 [2]파일 다운로드1
1197정성태12/9/201129966.NET Framework: 282. Shader 강좌와 함께 배워보는 XNA Framework (2) - RenderMonkey의 Shader/Model 파일 연동파일 다운로드2
1196정성태12/9/201133159.NET Framework: 281. Shader 강좌와 함께 배워보는 XNA Framework (1) - 기초 프로그램 구조 [3]파일 다운로드2
1195정성태12/8/201147802오류 유형: 143. DXSDK_Jun10.exe 설치 시 "Error Code: S1023" 오류 해결하는 방법 [4]
1194정성태12/8/201135585개발 환경 구성: 137. Visual C++ 런타임 구성요소에 대한 디버그 버전 설치하는 방법
1193정성태12/8/201122637오류 유형: 142. Windows Phone SDK 7.1 설치 시 Expression Blend 제거를 요구하는 경우
1192정성태12/8/201125669개발 환경 구성: 136. Windows 7 SP1의 IIS에서 사용자 프로파일을 로드하는 방법
1191정성태12/6/201126825.NET Framework: 280. MVC3에서 JavaScriptSerializer 재정의하는 방법파일 다운로드1
1190정성태12/6/201129990오류 유형: 141. Visual C++ 컴파일 오류 - error C2275: 'xxxxx' : illegal use of this type as an expression [1]
1189정성태12/6/201137060VS.NET IDE: 70. Visual Studio에서 프로젝트 로드가 안된다면?
1188정성태12/3/201126159개발 환경 구성: 135. 마이크로소프트 TFS 호스팅 서비스 - Preview [3]
1187정성태12/2/201130817개발 환경 구성: 134. Robocopy 오류 및 종료 코드
1186정성태12/1/201132680.NET Framework: 279. WPF - 그리기 성능 및 Blurring 문제파일 다운로드1
1185정성태11/29/201123404.NET Framework: 278. WPF - Content의 Changed 이벤트에 해당하는게 뭔가요?파일 다운로드1
1184정성태11/29/201126208.NET Framework: 277. F#과 WPF가 어울리지 못하는 근본적인 이유 [2]
1183정성태11/26/201121714오류 유형: 140. Visual Studio 2010 - Floating된 에디트 윈도우가 사라지지 않는 경우 [2]
1182정성태11/25/201157435.NET Framework: 276. 중복 없는 숫자를 랜덤으로 배열하는 방법 [5]파일 다운로드1
1181정성태11/24/201127922디버깅 기술: 44. windbg의 mscordacwks DLL 로드 문제
1180정성태11/23/201137707.NET Framework: 275. 레지스트리 등록 및 Interop DLL 없이 COM 개체 사용하는 방법 [2]파일 다운로드1
1179정성태11/22/201128289.NET Framework: 274. ReaderWriterLockSlim은 언제 쓰는 걸까요? [4]파일 다운로드1
1178정성태11/19/201124806.NET Framework: 273. 설치된 .NET 버전에 민감한 코드를 포함하는 경우, 다중으로 어셈블리를 만들어야 할까요?파일 다운로드1
... 151  152  153  [154]  155  156  157  158  159  160  161  162  163  164  165  ...