토요일, 5월 08, 2021

[B급 프로그래머] 윈도우 msys2는 완벽한 POSIX 호환 레이어인가?

최근에 강의 요청이 들어올 때 '실습 중심'으로 편성을 바꿔달라는 요청을 많이 받고 있다. 따라서 대면이거나 비대면이거나 실습을 염두에 두고 준비를 해야 하는데, 자바나 자바스크립트와는 달리 C인 경우에는 실습 조건을 갖추기가 살짝 어려운 경우가 있다. 예를 들어, 윈도우 환경만 지원하며 WSL2 등을 사용하지 못하는(여러 가지 이유로) 상황이 존재할 경우 선택지가 통합 개발 환경인 비주얼 스튜디오 블렌드 정도로 좁혀지는 어려움이 있는데, 통합 개발 환경을 사용할 경우 실습 과정에서 뭔가 꼬이면 이를 빠르게 해결해주기가 상당히 곤란하다. 따라서 명령행으로 컴파일이 가능한 환경을 생각하지 않을 수 없다(즉 gcc/clang - make 조합). 어차피 제한된 시간 내에 엄청나게 복잡한 프로젝트를 수행하지는 않을테니 편집기로 vim나 오픈소스로 제한없이 사용 가능한 NotePad++만으로도 충분하기 때문이다.

몇 가지 후보를 검토하다가 msys2를 선택하게 되었다. 컴파일 환경에 집중하는 mingw와는 달리 UNIX와 호환성을 지원하므로(즉, POSIX compliant), 리눅스 계열의 프로그램을 그대로(바이너리거나 오픈소스거나) 가져다 쓸 수도 있고 리눅스의 우수 사례를 쉽게 적용할 수 있기 때문이다. 그런데 msys2는 완벽한 POSIX 호환 레이어를 제공하지 않는다는 사실에 주목할 필요가 있다. 프로그램 중에서 키 입력을 위해 터미널 제어가 필요했기에 termios.h를 인클루드해서 컴파일을 하는데... 헤더 파일을 찾을 수 없다는 오류가 발생한다.

어지간한 프로그램은 대부분 빌드가 가능한데 하필 여기서 걸리는 이유는 무엇일까? Msys2 소개 글을 읽어보면 "The msys2 subsystem provides an emulated mostly-POSIX-compliant environment"라는 표현이 눈에 띈다. 즉 mostly지 completely는 아닌 셈이다. 뉴뉴

자 이제 상황을 파악했다면, 문제 해결을 위해 어떻게 할 것인가? 방법은 의외로 간단하다. msys2에서 패키지로 설치한 gcc 컴파일러는 POSIX 호환 유닉스 API 뿐만 아니라 윈도우에서 개발할 때 사용되는 conio.h와 Windows.h 헤더 파일도 인클루드해서 필요한 함수를 불러쓸 수 있다. 아주 복잡한 터미널 출력이 아니라면 간단하게 키 입력을 윈도우 버전에 맞춰 이식해서 돌릴 수 있는 방법이 존재한다. 다음과 같은 코드를 보면 이해가 갈 것이다(주의: 완벽하게 동작하려면 키 입력 시에 ECHO를 끄고 나중에 복구하는 등의 추가 작업이 필요하다).

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (WaitForSingleObject(hStdin, 1000) == WAIT_OBJECT_0 && _kbhit()) getchar();

결론: msys2는 완벽하게 유닉스(아니 리눅스)를 흉내내지 못한다. 정말 리눅스가 필요하면 WSL2를 고려하고 어느 정도 우회가 가능할 경우에는 msys2에 머물러도 좋다.

EOB

댓글 없음:

댓글 쓰기