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 명령을 실행하면 발생하는 오류 메시지로 확인하는게 훨씬 더 편하다.)

SQLite3 MSVC로 빌드시 주의사항

소스파일의 기준은 https://www.sqlite.org/download.html 이곳에서 sqlite-autoconf-VERSION.tar.gz 기준. (현재는 3380200)

소스파일 압축본 내 README.txt 파일과 https://www.sqlite.org/howtocompile.html 이곳을 참조하여 nmake "OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1" /f Makefile.msc 이렇게 빌드하였다.

이후 sqlite3.lib 파일로 링크하면 링크 오류가 발생하고 lib 파일을 열어다보니 export된 함수가 없다는것을 알 수 있었다. make 중 dumpbin /all sqlite3.lo 명령으로 sqlite3.def 파일을 생성하는 부분이 눈에 보이는데 단순히 버그인지 아니면 MSVC의 버전이 올라가면서 컴파일러 전처리기에 차이가 발생하는건지 sqlite3.def 파일에 export될 함수들이 없어 발생하는 문제인거같다.

stack overflow의 글(https://stackoverflow.com/a/71106434)을 참조하면 식별자 SQLITE_API로 dllexport를 지정하면 된다고 되어있으며 Makefile.msc 파일을 확인해본 결과 DYNAMIC_SHELL=1을 nmake 실행 시 지정하면 되는것으로 파악되었다.

결론: nmake "OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1" DYNAMIC_SHELL=1 /f Makefile.msc 이렇게 빌드하면 된다. sqlite3.h, sqlite3.lib, sqlite3.dll 파일들을 적당히 복사하여 사용하면 끗.

Boost 1.78.0 + Visual Studio 환경에서 빌드하기

이미 관련된 글을 남긴적이 있지만 조금 더 알게된것이 있고 장황하지 않고 짧게 기록하기위해 남기는 글. 콘솔 등 자잘한 내용은 기존의 글을 참조할 수 있으니 넘어가고 필요한 최소한의 내용만을 남긴다. (이전 글에서 문자열 ‘--‘은 ‘–‘로 치환되어 표시되고있으니 주의필요. 언젠가 수정할…지도?)

환경 및 빌드 대상
– Visual Studio Community 2019
– Boost 1.78.0
– 소스위치: D:\OpenSource\boost_1_78_0
– 설치위치: D:\OpenSource\boost

Boost Bootstrap
1. D:\OpenSource\boost_1_78_0\tools\build 폴더로 이동
2. bootstrap.bat 실행
3. b2 install --prefix=D:\OpenSource\boost 실행
4. D:\OpenSource\boost_1_78_0 폴더로 이동

환경변수 변경
set PATH=%PATH%;D:\OpenSource\boost\bin 명령을 실행하여 설치된 b2의 바이너리 경로를 PATH에 추가

Boost 빌드
b2 --build-type=complete toolset=msvc stage

Boost 설치
b2 --build-type=complete --prefix=D:\OpenSource\boost toolset=msvc install

Boost 사용
헤더와 라이브러리는 아래와같은 경로를 지정하여 사용하면 된다. 헤더는 버전별 폴더로 구분되어 있고 라이브러리나 dll은 파일명에 버전 넘버가 붙어있으니 다른 버전의 boost를 동일한 경로로 설치해도 헤더 경로만 사용하고 싶은 경로를 지정하여 사용하면된다.
헤더 경로: D:\OpenSource\boost\include\boost-1_78
라이브러리 경로: D:\OpenSource\lib

기타
1. 빌드와 설치를 개별 명령으로 실행하면 시간적으로 손해를 본다. 그냥 바로 Boost 설치 명령을 실행해도 된다.
2. --build-dir 옵션을 넣으면 stage 파일의 위치를 변경할 수 있다. 대신 Boost 빌드와 Boost 설치 실행 시 아래와같이 --build-dir 값을 동일하게 입력해야한다.
b2 --build-dir=D:\OpenSource\boost_build\1_78_0 --build-type=complete toolset=msvc stage
b2 --build-dir=D:\OpenSource\boost_build\1_78_0 --build-type=complete --prefix=D:\OpenSource\boost toolset=msvc install
3. --prefix 없이 설치하면 기본위치는 C:\Boost 이다.
4. Boost 소스폴더에서 b2 --help 를 실행하면 --layout 옵션을 볼 수 있다. 별별짓 다 해봤지만 윈도 환경에서는 기본값인 versioned로 빌드하여 설치하는게 가장 정신건강에 이롭다. 다른 값으로 빌드하면 헤더나 라이브러리 링크에서 정신건강에 해로울것이다.
5. 언제부턴가 32비트와 64비트 라이브러리가 기본적으로 함께 빌드되도록 변경된거같다. 특정 플랫폼만 대상으로 빌드한다면 address-model=32 또는 address-model=64 옵션을 함께 사용하면 된다. (toolset과 마찬가지로 -- 없이 address-model이다.)
6. 더 자세히 알고싶으면 이곳 Boost의 문서를 참조.

Qt 5.12.12 Arm 타겟 빌드 (Win32 호스트)

참조사항

Qt 버전별 툴체인 권장버전: https://wiki.qt.io/MinGW
MinGW-w64의 스레드 모델, 예외 처리 모델의 자세한 내용: http://blog.tcltk.co.kr/?p=3836

필요환경

Perl: https://strawberryperl.com/releases.html
Python: https://www.python.org/downloads/
MinGW: https://sourceforge.net/projects/mingw-w64/files/
GCC (Raspberry Pi): https://gnutoolchains.com/raspberry/

Perl이나 Python이 이미 시스템에 설치되어 있다면 환경변수에 경로가 설정되어 있는지 확인하여 그대로 사용하면 되며, 시스템에 설치하지 않고 Qt 빌드에 잠깐 사용을 원한다면 Perl은 Portable Edition, Python 3는 Embeddable Package로 받으면 된다.

이 글에서 압축을 푸는 위치는 D:\OpenSource를 기준으로 한다. 단 Python은 압축 파일 내 폴더없이 압축되어 있으므로 압축 해제 시 ‘여기에 압축 풀기’가 아닌 ‘python-3.9.9-embed-amd64에 압축풀기’와 같은 방법으로 해제한다.

환경변수

set PATH=D:\OpenSource\mingw64\bin;D:\OpenSource\strawberry-perl-5.32.1.1-64bit-portable\perl\bin;D:\OpenSource\python-3.9.9-embed-amd64;%PATH%

Perl 5.32.1.1 64bit Portable Edition, Python 3.9.9 Embeddable Package, MinGW 는 참조사항의 링크 내용을 따라서 버전을 선택하면 되며 현재 글에서 사용한 컴파일러 posix보다는 더 나은 퍼포먼스를 위해 x86_64-win32-seh 사용, GCC (Raspberry Pi)는 대상 OS에 맞는 버전으로 사용.

참고: 윈 10 최근 버전은 python 명령이 스토어에 연결된 단축 명령 형식으로 재공되므로 원하지 않는 오류가 발생할 수 있다. 이러한 경우가 발생하는것을 원하지 않는다면 시작 – 설정 실행, 앱 항목에서 ‘앱 및 기능’ 레이블의 하단 ‘앱 실행 별칭’ 링크로 이동하여 ‘앱 설치 관리자’항목으로 지정된 python.exe와 python3.exe 항목을 ‘끔’으로 변경하면 별칭과의 충돌을 피할 수 있다.

빌드설정

..\qt-everywhere-src-5.12.12\configure -opensource -confirm-license -platform win32-g++ -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=C:\SysGCC\raspberry\bin\arm-linux-gnueabihf- -sysroot C:/SysGCC/raspberry/arm-linux-gnueabihf/sysroot -prefix /opt/Qt5.12.12 -extprefix D:\OpenSource\Qt5.12.12.gcc-arm -hostprefix D:\OpenSource\Qt5.12.12.gcc-arm -release -eglfs -opengl es2 -no-use-gold-linker -nomake examples -nomake tests -skip qtscript

shadow 빌드를 기준으로 한다. (설정이 잘못되거나 처음부터 다시 빌드해야 할 경우 빌드 폴더를 지우고 다시 폴더를 만들어서 진행하면 make distclean보다 훨씬 깔끔하게 다시 빌드할 수 있기때문이다.)

Qt 소스경로: D:\OpenSource\qt-everywhere-src-5.12
Qt빌드경로: D:\OpenSource\Qt5.12.12.gcc-arm.build
Qt설치경로: D:\OpenSource\Qt5.12.12.gcc-arm

gold 링커가 더 성능 좋다고하지만 MinGW 쉘 환경이 아니라면 링커가 실행되지 않으므로 -no-use-gold-linker 옵션을 추가, device 값은 linux-rasp-pi3-vc4-g++도 있으나 손봐야 하는 환경도 있고 타겟 보드에 Qt를 빌드하여 넣는 것이 아닌 윈도에서 타겟 보드에서 실행할 프로그램을 크로스 빌드 하기위한 Qt 이므로 별 의미 없다.

examples는 필요한 예제를 나중에 따로 빌드해도 되고 꽤나 시간을 많이 잡아먹기때문에 nomake 처리하였고, 크로스 빌드에선 tests를 빌드하는지 모르겠지만 테스트도 보통 시간을 많이 잡아먹기 때문에 일단 nomake에 추가.

sysroot 옵션은 VideoCore의 그래픽 가속 라이브러리 링크를 위해서이다. 이 옵션이 없으면 OpenGL ES 인터페이스가 비활성화된다. X Window를 사용하지않고 eglfs를 사용한다면 필수.

sysroot 옵션을 지정할 경우 install 경로가 $sysroot/$prefix 으로 되므로 prefix는 임의로 /opt/Qt5.12.12 로 지정하였다. 실제 설치위치는 extprefix와 hostprefix로 지정한다. (extprefix는 라이브러리, hostprefix는 qmake등 호스트 레벨의 실행파일의 설치 위치)

device 옵션으로 pi3를 지정하면 이곳의 글 6번 항목 내용처럼 qtscript 모듈에서 빌드 오류가 뜬다. 쓰지않으니 skip 처리하였다.

빌드 및 바이너리 설치

아래와같이 명령어를 입력하면 된다. j옵션의 숫자는 CPU 스레드 수 또는 +1 정도면 적당하다.

mingw32-make -j6
mingw32-make install

DLL 복사

G++로 빌드된 바이너리는 libstdc++이 필요하다. 해당 런타임은 D:\OpenSource\mingw64\bin 폴더에서 libgcc_s_seh-1.dll, libstdc++-6.dll 두 파일을 D:\OpenSource\Qt5.12.12.gcc-arm\bin에 복사하면 된다. posix 모델을 사용하는 MinGW를 사용하였으면 libwinpthread-1.dll 파일도 필요할것으로 보인다.

Continue reading Qt 5.12.12 Arm 타겟 빌드 (Win32 호스트)