
Windows 95부터 11까지 돌아가는 코드의 미학: Uxn32를 보며
Windows 95부터 11까지 지원하는 초경량 에뮬레이터 Uxn32를 통해 의존성 최소화와 소프트웨어 설계의 본질에 대해 탐구합니다.
김영태
테크리드

안녕하세요. 풀링포레스트 테크리드 김영태입니다.
개발자로서 연차가 쌓이다 보면 '레거시(Legacy)'라는 단어만 들어도 조건반사적으로 뒷목이 뻐근해지곤 합니다. 저 역시 얼마 전, 사내 인프라를 최신화하는 과정에서 얽히고설킨 의존성 지옥(Dependency Hell)을 맛보고 며칠을 앓아누웠습니다. "왜 이렇게 소프트웨어는 복잡하고 무거워야만 할까?"라는 회의감이 들 때쯤, 우연히 GitHub에서 Uxn32라는 프로젝트를 발견하고 신선한 충격을 받았습니다. 오늘은 이 작은 에뮬레이터가 저에게 던진 기술적 화두에 대해 이야기해 보려 합니다.
솔직히 말해 처음에는 그저 레트로 감성의 장난감인 줄 알았습니다. Uxn32는 Uxn이라는 가상 머신을 윈도우와 Wine 환경에서 돌려주는 에뮬레이터입니다. 그런데 README 파일을 읽어 내려가다 눈을 의심했습니다. 호환성 목록에 Windows 95부터 Windows 11까지 적혀 있었기 때문입니다. 심지어 1998년에 나온 Visual C++ 6.0(VC6) 컴파일러로도 빌드가 된다는 문구를 보고는 헛웃음이 나왔습니다. 요즘 세상에 30년 가까운 OS 스펙트럼을 커버하는 단일 바이너리라니요.
백엔드 개발자인 제가 이 프로젝트에서 주목한 지점은 '극한의 다이어트'와 '단순함의 힘'입니다. 우리는 흔히 MSA를 구축하고 컨테이너를 띄우면서 수백 메가바이트짜리 이미지를 당연하게 여깁니다. 하지만 Uxn32는 외부 의존성이 전혀 없습니다. 설치 프로그램도 필요 없고, 딱 하나의 .exe 파일만 있으면 됩니다. 소스 코드도 uxn32.c, uxn_core.c 등 파일 서너 개가 전부입니다. user32.lib, gdi32.lib 같은 아주 기본적인 윈도우 시스템 라이브러리만 링크해서 이 모든 호환성을 확보했습니다.
특히 인상 깊었던 기능은 선점형 실행(Pre-emptive execution) 구현 방식이었습니다. 에뮬레이터 안에서 돌아가는 프로그램이 무한 루프에 빠지더라도, 에뮬레이터 자체는 멈추지 않습니다. UI 스레드가 블로킹되지 않도록 설계된 것이죠. 이는 우리가 서버 사이드에서 Node.js나 Netty 같은 비동기 프레임워크를 다룰 때 항상 고민하는 '이벤트 루프 차단 방지'와 맥을 같이 합니다. 작고 가벼운 도구지만, 그 안에는 견고한 소프트웨어 아키텍처의 기본기가 단단히 자리 잡고 있었습니다.
리눅스 환경에서의 빌드 전략도 흥미로웠습니다. 보통 리눅스에서 윈도우 앱을 개발하려면 MinGW 같은 크로스 컴파일러를 복잡하게 세팅해야 합니다. 하지만 Uxn32는 Winelib을 사용해 리눅스의 GCC나 Clang으로 윈도우용 코드(PE 포맷이 아닌 ELF 포맷이지만)를 컴파일하고, 이를 Wine으로 실행하는 실용적인 접근법을 보여줍니다. winemaker과 make 명령어 두 번이면 리눅스에서도 윈도우용 코드를 테스트할 수 있다는 점은, 멀티 플랫폼 지원을 고민하는 개발자들에게 훌륭한 레퍼런스가 됩니다.
물론 현업의 복잡한 비즈니스 로직을 다루는 우리가 당장 모든 라이브러리를 걷어내고 C언어 파일 몇 개로 돌아갈 수는 없습니다. 생산성과 유지보수 측면에서 프레임워크의 도움은 필수적이니까요. 하지만 가끔은 덕지덕지 붙은 라이브러리 없이, OS의 기본 API만으로도 240Hz 주사율을 소화하고 수십 년간 호환되는 코드를 짤 수 있다는 사실을 상기할 필요가 있습니다.
막막했던 인프라 마이그레이션 작업을 다시 마주하며 다짐했습니다. "무조건 최신 기술, 무조건 많은 기능"을 좇기보다, 이 Uxn32처럼 꼭 필요한 기능에 집중하고 의존성을 최소화하는 방향으로 설계를 다듬어야겠다고 말입니다.
혹시 여러분의 프로젝트도 비대해진 의존성 때문에 신음하고 있지는 않나요? 머리를 식힐 겸, 이번 주말에는 Uxn32의 소스 코드를 한번 열어보시는 건 어떨까요. uxn32.c 파일을 들여다보는 것만으로도, 잃어버린 '소프트웨어의 야성'을 되찾는 기분이 드실 겁니다.
남은 한 주도 가볍고 단단한 코드 작성하시길 바랍니다.


