Qt 6.6.1 MSVC 2022로 빌드

MSVC 2022로 Qt 6.6.1버전 빌드 시 발생하는 오류 리스트

  1. 소스코드 파일 인코딩 오류 (비 유니코드 언어가 영어 (미국)이 아닌경우)
  2. qtwebengine/src/3rdparty/gn/src/gn/variables.cc 텍스트 오류 (1번 항목과 동일한 환경, 577번 라인의 0xA0(NBSP) 캐릭터에서 에러 발생하며 0x20(SPACE)으로 변경하면 해결)
  3. qtwebengine/src/3rdparty/chromium/third_party/webrtc/rtc_base/checks.h LogStreamer의 연산자 오류
  4. gperf 버전이 3.1이상일 경우 오류 발생 ((standard input):1915: warning: junk after %% is ignored 메시지 발생하며 파일이 정상처리 안됨)

크게 네가지 오류가 나타난다. 이 중 1, 2번은 이 글에서 “지역설정” 항목을 참조하여 변경하면 해결 된다. 3번 항목은 vcpkg 프로젝트에서 qtwebengine 패키지의 패치(clang-cl.patch, msvc-template.patch)를 그대로 적용하면 해결된다. 4번은 Qt 5.15.x 버전을 다운받은 후 gnuwin32\bin 경로를 PATH의 맨 앞으로 추가하여 clean & build 하면 해결된다.

만약 시스템 로케일 변경이 귀찮거나 재부팅을 하기에 곤란하다면 아래 소스코드를 빌드 후 실행하여 UTF-8 BOM을 추가하고 환경변수에 “PYTHONUTF8=1″을 추가(프롬프트에서 SET PYTHONUTF8=1 실행)하여 파이선의 파일 인코딩을 UTF-8로 인식하도록 설정한다.

아래 코드는 NBSP문자를 SPACE로 변환 및 확장 아스키 영역의 문자가 있을 경우 UTF-8 BOM을 추가한다.

/*
 * 파일명: CSourceSetUtf8Bom.cpp
 * 빌드명령: cl CSourceSetUtf8Bom.cpp /O2 /std:c++20 /EHsc
 * 실행: CSourceSetUtf8Bom <qt source path>
 * 실행 예: CSourceSetUtf8Bom D:\OpenSource\Qt6.6.1.src
 */

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>

static void fetch(const std::filesystem::path& source_path, std::size_t& count)
{
    std::cout << count << "\r";
    std::filesystem::directory_iterator it(source_path);

    for (; it != std::filesystem::end(it); it++)
    {
        if (std::filesystem::is_directory(*it))
        {
            fetch(*it, count);
        }
        else
        {
            std::string path = it->path().string();

            if (!path.ends_with(".c") && !path.ends_with(".cc") && !path.ends_with(".cpp") && !path.ends_with(".h"))
            //if (!path.ends_with(".py"))
            {
                continue;
            }

            count++;

            std::basic_ifstream<unsigned char> istream(path);
            std::basic_string<unsigned char> content((std::istreambuf_iterator<unsigned char>(istream)), std::istreambuf_iterator<unsigned char>());

            istream.close();

            if (content.size() >= 3 && content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF)
            {
                continue;
            }

            bool extended = std::find_if(content.begin(), content.end(), [](unsigned char c) { return c > 127; }) != content.end();
            if (!extended)
            {
                continue;
            }

            std::cout << count << ", " << it->path().string() << ", " << content.size() << " bytes\n";

            // replace NBSP -> SPACE
            std::replace(content.begin(), content.end(), 0xA0, 0x20);
            std::basic_ofstream<unsigned char> ofstream(path);

            ofstream << static_cast<unsigned char>(0xEF);
            ofstream << static_cast<unsigned char>(0xBB);
            ofstream << static_cast<unsigned char>(0xBF);
            ofstream << content;

            ofstream.close();
        }
    }
}

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        std::cout << argv[0] << " <FOLDER>\n";

        return EXIT_FAILURE;
    }

    std::size_t count = 0;
    std::filesystem::path source_root(argv[1]);

    if (!std::filesystem::is_directory(source_root))
    {
        return EXIT_FAILURE;
    }
    fetch(source_root, count);

    return EXIT_SUCCESS;
}

윈도우 11 22H2의 작업 관리자 성능 모니터링 문제

CPU의 스레드별 사용률을 프로그래밍으로 얻기위해 NtQuerySystemInformation 함수로 얻어진 카운터로 사용률 계산해보니 작업 관리자의 성능 모니터 값과 두배 이상 차이나는 현상이 발생하였다.

작업관리자의 프로세스와 성능 화면은 아래와같다.

ConsoleApp1의 사용률 약 42%
성능 모니터의 프로세서 사용률 약 43%
Continue reading 윈도우 11 22H2의 작업 관리자 성능 모니터링 문제

Qt ODBC 오류발생 및 조치사항

며칠 전 응용 프로그램에서 데이터가 표시되지 않는다는 연락을 받았다. 오류 메시지를 확인해보면 주로 아래와같은 메시지가 출력된다.

[Microsoft][ODBC SQL Server Driver]TDS 스트림에 프로토콜 오류가 있습니다.

여러 윈도에서 확인해본 결과 해당 문제가 발생되는 윈도의 ODBC 드라이버 중 SQL Server의 날짜가 윈도 11은 2022-11-09 였으며 윈도 10은 2022-11-12 쯤 날짜였다. 업데이트 된 날짜는 해당 날짜와 동떨어져있는데 저 드라이버의 날짜가 왜 저런지는 알 수 없었다. (확인된 윈도가 5개 정도밖에 안되어 해당 드라이버 날짜와 밀접한 관계인지 명확하지는 않다. 단지 문제가 발생된 윈도에서 확인하면 공통적으로 2022년 11월로 되어있었다.)

QSqlQuery가 중첩되어 사용되어있는 코드여서 결국 문제가 발생한건가보구나 싶었는데 중첩된 코드를 풀었음에도 동일한 문제가 발생하여 새로운 Qt 프로젝트를 생성하여 쿼리를 실행해보았더니 동일한 문제가 발생하였다. 덕분에 하루종일 작업한 코드는 그저 삽질이였다.

결국 며칠 전 날짜로 변경 된 드라이버의 문제일것이라 생각되어 아래와같이 드라이버를 SQL Server Native Client 11.0으로 수정하여 실행하니 문제가 발생하지 않았다.

해당 드라이버는 클라이언트 PC에 설치된 드라이버가 아니므로 MS 공식 홈페이지에서 배포되는 ODBC Driver 17 for SQL Server를 설치하여 연결 문자열을 변경 후 프로그램을 빌드하여 업데이트 후 해결되었다.

아래는 드라이버 다운로드 링크.
https://learn.microsoft.com/ko-kr/sql/connect/odbc/download-odbc-driver-for-sql-server

아래와같은 애러가 발생하면 17버전을 사용하면 편하게 해결가능하다.

[Microsoft][ODBC Driver 18 for SQL Server]SSL 공급자: 신뢰되지 않은 기관에서 인증서 체인을 발급했습니다.\r\n [Microsoft][ODBC Driver 18 for SQL Server]클라이언트가 연결하지 못했습니다. QODBC: Unable to connect
참고링크: https://learn.microsoft.com/en-us/troubleshoot/sql/connect/certificate-chain-not-trusted

MS는 도대체 뭘 건들었길레 윈도에 기본 설치되는 ODBC 드라이버인 SQL Server가 갑자기 문제가 발생하게 된걸까. ODBC 드라이버 배포 페이지에 해당 안내도 없고 뜬금없이 업데이트에 문제가 발생하고 도저히 이해가 안된다. 덕분에 하루 반나절을 삽질했다. 이런 경우가 한두번이 아닌거같은데 기분탓인가?

MSVC로 ANGLE 빌드하기

참고내용
환경설정: https://chromium.googlesource.com/angle/angle/+/HEAD/doc/DevSetup.md
depot_tools: https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up
Windows SDK: https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/
빌드 캐시: https://github.com/mozilla/sccache/releases

빌드환경
MSVC 2019 (기본)
Windows SDK 10.0.20348.0 (2022-05-30 기준)
Python 3버전

구성
1. depot_tools 문서의 윈도 번들 파일인 이 링크 다운로드 (D:\OpenSource\depot_tools 로 경로를 가정)
2. 빌드 캐시를 사용할 경우 빌드캐시 링크에서 sccache-vx.y.z-x86_64-pc-windows-msvc.tar.gz 형식의 링크 다운로드 (D:\OpenSource\depot_tools에 sccache.exe를 위치시키는것으로 가정)
3. Windows SDK 설치
4. Python 3 설치
5. 소스코드는 D:\OpenSource\angle로 위치시키는것으로 가정

빌드
1. ‘x64 Native Tools Command Prompt for VS 2019’에서 D:\OpenSource\depot_tools로 이동 후 set PATH=%CD%;%PATH% 실행 (또는 set PATH=D:\OpenSource\depot_tools;%PATH% 실행)
2. set DEPOT_TOOLS_WIN_TOOLCHAIN=0 명령을 실행
3. D:\OpenSourceangle 폴더를 생성하여 이동 후 fetch angle 명령을 실행
4.1. 디버그 빌드는 gn gen out/Debug --sln=angle-debug --ide=vs2019 --args="is_component_build = true is_debug = true" 실행 후 autoninja -C out/Debug 명령을 실행
4.2. 릴리즈 빌드는 gn gen out/Release --sln=angle-release --ide=vs2019 --args="is_component_build = true is_debug = false" 실행 후 autoninja -C out/Release 명령을 실행

사용
1. Include 패스는 D:\OpenSource\angle\out\Debug\include 또는 D:\OpenSource\angle\out\Release\include
2. Lib 패스는 D:\OpenSource\angle\out\Debug 또는 D:\Opensource\angle\out\Release
3. 필요한 링크 파일은 libEGL.dll.lib libGLESv2.dll.lib 등 (상황에 따라 다르겠지만 이것들 외 링크가 필요하다면 이미 각자 필요한 파일이 무엇인지 알듯.)

기타
1. 빌드 캐시를 사용하려면 gn 명령 실행 시 gn gen out/Debug --sln=angle-debug --ide=vs2019 --args="is_component_build = true is_debug = true cc_wrapper = \"sccache\""와 같이 cc_wrapper = “sccache”를 추가하여 실행
2. 아래와같은 오류가 발생 할 경우 선택된 영역을 참고하여 필요한 버전의 SDK를 설치하여 gn 명령을 다시 실행 (환경설정 문서를 참고하면 vs_toolchain.py 파일에서 확인 가능하다고 하지만 그냥 gn 명령을 실행하면 발생하는 오류 메시지로 확인하는게 훨씬 더 편하다.)