들어가며
최근 CMake를 C++ 프로젝트를 빌드하면서 특정 Windows PC에서만 빌드 에러가 발생하는 흥미로운 버그를 만났다.
향후 비슷한 문제를 마주했을 때 빠르게 원인을 파악하고 대처할 수 있도록,
이번 트러블 슈팅 과정에서 배운 버그 발생 원인과 해결방법을 정리해 보려 한다.
문제 상황
이 빌드 에러는 다음과 같은 특정 환경에서만 발생했다.
- OS: Windos
- Windows 사용자 계정: 한글 이름 사용 (예: C:\Users\전인학\...)
- OS 설정: "시간 및 언어 > 언어 및 지역 > Beta: ...Unicode UTF-8" 옵션이 꺼져 있는 상태
원인 분석: 빌드 도구 간의 인코딩 불일치
사용자 계정명이 한글일 때 오류가 발생하는 원인을 조사해 보니,
빌드 파이프라인에 동원되는 각 도구별로 사용하는 인코딩(코드 페이지)이 달라서 발생하는 문제라는 걸 알았다.
예를 들어, MinGW를 이용해 컴파일 및 링킹을 수행하는 과정은 다음과 같다.
CMake → mingw32-make → g++ → ld → 실행파일(.exe) / 라이브러리(.dll)
여기서 문제는, 이 도구들이 문자열(경로, 인자 등)을 주고받을 때 작동하는 방식이다.
*인코딩 형식은 대부분 툴이 빌드될 때 결정되며, 최신 도구들은 자체적으로 UTF-8을 기본으로 사용하는 경우가 많다.

영어 알파벳, 숫자, 범용 특수문자(/, \, _, - 등)와 같은 ASCII 문자로만 이루어진 경로라면
읽는 쪽과 보내는 쪽이 UTF-8이든 UTF-16이든 문자가 깨질 일이 없다.
하지만 경로 중간에 한글이 섞여 있다면 어느 한 구간에서라도 양쪽 도구 간 파싱하는 인코딩이 어긋날 경우 텍스트가 깨지고,
파일을 찾지 못하는 치명적인 빌드 에러로 직결된다.
버그 검증 및 재현
제일 먼저 Windows OS의 활성 코드 페이지 설정을 확인했다.
Windows11 기준으로, cmd창에서 chcp 명령어를 입력하면 UTF-8 옵션 활성화 여부에 따라 코드페이지가 달라지는 것을 확인할 수 있었다.



원인 파악 후, Windows에 한글 유저 계정을 추가하고 간단한 C++ HelloWorld 프로젝트를 구성하여 버그를 재현할 수 있었다.
📜 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(TinyClassTest LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(tiny_test
src/main.cpp
)
📜 src/main.cpp
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
파일 생성 후 다음 명령어로 빌드를 수행해 보면, 옵션 활성화 여부에 에러 양상이 갈리는 것을 확인할 수 있다.
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Qt/Tools/mingw810_32/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.0s)
-- Generating done (0.0s)
-- Build files have been written to: C:/Users/전인학/Desktop/cmake-utf16-test/build
mingw32-make.exe[2]: *** No rule to make target 'C:/Users/전인학/Desktop/cmake-utf16-test/src/main.cpp', needed by 'CMakeFiles/tiny_test.dir/src/main.cpp.obj'. Stop.
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/tiny_test.dir/all] Error 2
mingw32-make.exe: *** [Makefile:90: all] Error 2
해결 방법
이 문제를 해결하기 위해 고민해 본 몇 가지 방법들이 있고, 나는 ①번 방식으로 버그를 해결할 수 있었다.
① ASCII 경로만 사용하기 (공용 폴더 활용 / ASCII Staging)
모든 프로젝트 경로와 인자에 한글이 포함되지 않는 ASCII 문자열만 사용하는 방식이다.
이 방식을 채택할 땐 경로의 접근 권한이 사용자 고유 권한인지 범용 공유 권한인지 잘 고려해야 한다.
| 예시 경로 | 설명 |
| C:\Users\전인학\... | '전인학' 사용자의 고유 위치로 인식되어 보안상 좋지만, 한글 경로 문제가 생길 수 있음 |
| C:\ProgramData\TempStage\ | 여러 사용자가 공유하는 범용 위치로 인식되며 경로에 한글이 없어 인코딩 충돌을 우회할 수 있음 |
② Windows의 subst 명령어 활용
Windows 커맨드인 subst를 사용하여 기존의 긴 경로를 가상의 논리 드라이브로 간단하게 매핑할 수 있다.
예: 커맨드 라인에 subst M: C:\Users\전인학\... 등록
이후 빌드 툴에는 "M:\TempStage"처럼 ASCII로만 이루어진 맵핑 경로만 전달되므로 문제를 회피할 수 있음.
③ 빌드 도구 인코딩 강제 일치시키기 (비추)
모든 빌드툴의 인코딩 방식을 강제로 일치시켜 해결하는 방법.
하지만 MinGW 대신 Ninja로 툴을 전환한다거나, 내부 구현을 알 수 없는 서드파티 툴이 파이프라인에 섞일 경우 제어가 불가능해지기 때문에 현실적인 문제가 많아 옳은 방식은 아닌 것 같다.
회고
이번 트러블 슈팅 과정에서 조금 어려웠던 점은,
현재 프로젝트의 경우 빌드가 사용자 PC환경에서 실행되고 빌드 툴 로그를 별도로 수집하지 않아 디버깅이 까다로웠다는 점이다.
하지만 결과적으로 Windows 환경에서는 사용자 계정 명에 한글이 자유롭게 쓰일 수 있다는 예외 상황을 경험해 볼 수 있었다.
이에 더해 빌드 툴들의 인코딩 처리 메커니즘, OS의 코드 페이지 동작 방식, 그리고 subst 나 공용 폴더 격리 같은 실용적인 회피 기법까지 다양하게 배울 수 있는 계기가 되었다.
직접 공부해서 다음 글로 정리해 보려고 합니다.
'개발' 카테고리의 다른 글
| Linux PREEMPT_RT 실시간성(Jitter) 측정 및 성능 비교 - RTOS (0) | 2026.04.06 |
|---|---|
| Antigravity 구독 취소 방법(환불정책) (3) | 2026.03.26 |
| Real-Time, RTOS, PREEMPT_RT, CPU Isolation 개념 정복 - 실시간 처리 (0) | 2026.03.19 |
| SW USB 동글 라이선스 인증 구현하기 - Sentienl API와 C++ 클래스 설계 (1) | 2026.03.13 |
| HW USB 동글 보안 시스템 구축하기 - Sentinel EMS 프로비저닝 실무 (2) | 2026.03.04 |