2019/03/05

Windows에서 Qt5 쓰다 알게 된 몇 가지


우분투에 길들여져 있어서 Windows에서 뭘 하는 게 무척 서툴러 졌다. Windows 10 환경에서 Qt5를 갖고 노는데 잘 안되는게 많아서 삽질이다.

우선, Qt 5.12 최신 버전을 설치했는데, 하필이면 Qt Creator 4.8.1에 64bit MinGW / gcc 7.2가 딸려온다. 첨엔 32bit / 64bit 둘 다 만들 수 있으니까 좋겠다 싶었는데 그게 아니었다. 64bit MinGW 버전도 두 가지 형태로 배포되는데 32bit / 64bit 코드를 생성해 주는 배포판이 있고, 그렇지 않은 배포판이 있는데 Qt Creator에 딸려오는 놈은 64bit로 밖에 컴파일이 안된다. 참고로, Qt 5.11까지는 32bit MinGW가 기본이었다. MinGW 64bit가 기본이 되었다는 것은, Qt 5.12에 딸려오는 Qt library들도 모두 64bit 버전이 되었다는 것을 내포한다. 즉, 32bit 개발 환경이 필요하면 거꾸로 32bit MinGW와 32bit Qt library를 별개로 설치해야 한다는 의미이다. Qt Creator는 IDE(통합 개발 환경) Tool이기 때문에 여러 가지 조합을 kit로 만들어서 사용할 수 있도록 해준다. 일찌감치 64bit 환경이 된 우분투에서는 아예 신경도 안쓸 일을, 64bit Windows 10에서는 아직까지도 신경써야 한다는...

참고로, LLVM-7.0.1 64bit Windows 버전을 Qt Creator에서 사용하려면 Visual Studio 버전의 QT Library를 별개로 설치해야 한다. 걍 MinGW로 만족하는게 나을 듯...

아무튼, 삽질하다 보니 또 몇 가지 몰랐던 것들을 알게 되어 까먹기 전에 정리해 둔다.

Virtual Box Guest OS와 Host OS에서 생성한 Binary 성능 차이

사실, 이전엔 가상 머신을 애용했기에, 아무 생각없이 가상 머신 환경에서 만든 binary를 복사해서 Host OS에서 사용하곤 했었다. 그런데 최근에 장난감 chart를 Windows Host에서 돌려 보고는 깜짝놀랐다. 우분투 Host 보다 느려도 너무 느린 것이다. Virtual Box의 Windows에서 돌릴때는 가상 머신이라 느린 것을 당연하게 받아 들였지만, Windows Host에서는 그렇게까지 차이 날 이유가 없다. 그래서 Windows Host에 Qt 5.12를 설치하게 된 것이다. 마침내 새로 컴파일해서 돌려 보니 확실히 10배 가량 빨라졌다. 그런데 Qt가 문제인지 MinGW가 문제인지 Windows가 문제인지 확실하지 않지만, 장난감 chart의 성능은 우분투가 빠르다.

혹시나 해서 이번에는 Windows Host에서 생성한 binary를 복사해서 가상 머신에서 돌려 보았다. 이게 웬걸, 가상머신에서 돌려도 그렇게까지 느리지는 않다. Host의 80~90% 정도의 성능을 보인다. 헐~!!!

아무튼, 가상 머신에서 돌릴지라도 Host에서 생성한 binary로 돌리는 게 빠르다는 사실.

Windows Qt Creator에서 WSL에 설치된 git 사용

Windows의 Qt Creator는 Windows용 프로그램이기 때문에 같이 사용할 Tool들도 모두 Windows용 binary들이라야 한다. 하지만, Batch 파일을 사용하면 WSL(Windows Subsystem Linux)의 우분투에 설치된 git를 사용할 수 있을 것이라 생각해 왔다. 마침, 이번에 64bit MinGW를 설치했으니 다시 git.bat 파일을 사용해 보기로 했다.

chcp 65001
"C:\Windows\System32\wsl.exe" git %*

DOS 시절엔 batch 파일도 잘 만들어 썼는데 안쓰니까 잊혀진다. 구글링으로 복습해서 위와 같이 만들고 Qt Creator의 git에 Path를 넣었는데, wsl 명령을 실행할 수 없다는 메시지...

뭐가 문제인지도 모르겠고 거의 포기하려다 문득, Qt Creator가 32bit가 아닐까 의심하게 되었는데 WSL 우분투의 file 명령을 이용해서 확인해 보니 추측이 맞았다. 당연히 MinGW와 Qt Library들이 64bit 버전이 됐으니까 Qt Creator도 64bit일 것이라고 생각했던 것이다. 헐~!!! 아무튼, 근거없는 추측에 의존하면 안된다.

대부분 알고 있는 사실은 64bit 운영체제에서는 32bit건 64bit건 상관없이 프로그램이 잘 돌아 간다. WSL은 64bit 프로그램이고 Qt Creator는 32bit 프로그램이다. Windows에서 32bit 프로그램이 64bit 프로그램을 호출하는 방법도 혹시 있지 않을까??? 구글링하다 단서를 못찾아 거의 포기하려던 순간에 %windir%\Sysnative를 사용해 보라는게 눈에 띄었는데 Windows 디렉터리 밑에 Sysnative는 아무리 찾아봐도 없다. 밑져야 본전이니 함 해 보자...

chcp 65001
"C:\Windows\Sysnative\wsl.exe" git %*

git.bat를 위와 같이 바꾸고 Qt Creator에서 실행했는데 git 명령이 먹힌다. 헐~!!! 세상엔 숨겨진 진실이 수없이 많구나.

구글링하다 보니 WSL을 Windows 환경에서 적극적으로 활용하려는 노력들이 참 가상하다. wslgit 도 그 중의 하나이다. Qt Creator에서 WSL의 git를 제대로 사용하려면 wslgit를 사용하는게 좋을 듯... Windows는 DOS 태생시절 부터 Unix와 다르다는 점을 내세우고 싶어 했는데 대표적인게 Path 사용 방식이다. 때문에 이게 근본적인 골칫거리 중의 하나가 되었다. 아무튼 wslgit는 git.bat와 함께 우분투 쪽에도 wslgit script를 사용하여 여러 문제를 해결하고 있다. 단, git.bat 파일을 Qt Creator에서 사용할 시에는 위의 Sysnative라는 가상 Path를 반드시 사용해야 한다.

MinGW에서 Windows System Call 사용

위의 git.bat 파일에서 chcp 65001은 CMD 창(shell)의 code page를 UTF-8로 바꾸라는 명령이다. 참고로, CMD 창의 기본 code page는 949(ks_c_5601-1987/EUC-KR)이다. WSL의 우분투도 CMD 창에서 실행되기 때문에 우분투 명령들은 UTF-8 환경에서 실행되지만, Windows 명령들은 EUC-KR 환경에서 실행되게 된다. 이를 UTF-8로 일치시키도록 하는 것이 chcp 65001의 역할이다. 가령, SQLite DB를 CMD 창에서 사용할 때 한글 문제가 발생하지 않도록 하려면 UTF-8 환경에서 사용해야 한다.  기본적으로 SQLite의 encoding 방식은 UTF-8이기 때문이다.

프로그램 개발 시에는 이런 명령을 프로그램에서 제어하는 것이 바람직한데 MinGW에서는 <windows.h> 헤더를 사용함으로써 Windows System Call을 사용할 수 있다. 이것은 Qt Library와는 관련이 없다.

void setConsoleCodePage()
{
#ifdef _WIN32
  SetConsoleOutputCP(65001); // CodePage: UTF-8
  std::cout << "Setting console CodePage to UTF-8 on default locale(C): 한글 테스트\n\n";
#endif
}

즉, SetConsoleOutputCP(65001) 시스템 함수를 MinGW 함수에서 사용함으로써 chcp 65001 명령을 대체할 수 있게 된다. 이외에도 Screen Saver의 실행을 막거나 절전기능을 막기 위한 용도 등으로 Windows System 함수들을 사용할 수 있다.