MinGW-w64에서 QtWebApp 기반 Windows service 개발시 linker가 QtService의 symbol을 찾지 못하는 경우

QtWebApp은 Windows service나 Linux daemon 개발시 편의를 위해 QtService를 함께 탑재하고 있습니다. QtService는 꽤 잘 만들어진 라이브러리입니다만, Qt Company에서 몇년째 손을 놓고 있는, '버려진' 라이브러리이기도 합니다.

저는 Windows-Linux간 동일 컴파일러 사용 및 portability 이슈로 인해 MinGW-w64의 personal build 중 하나인 mingw-builds를 사용하고 있는데, 최근 QtWebApp으로 개발을 진행하던 도중QtWebApp을 dynamic link하면 linker가 QtService<QCoreApplication>의 symbol을 제대로 찾지 못하는 것을 발견했습니다. Qt 5.7에 탑재된 GCC가 5.3이므로 버전이 낮아서 생기는 문제는 아닌 듯 했는데, 결국 방법을 찾았습니다.

QtWebApp/qtservice/qtservice.h 파일에 보면 아래와 같은 내용이 있습니다.

template <typename Application>
class DECLSPEC QtService : public QtServiceBase

그리고 전 이 구문을 이렇게 바꿨습니다.

template <typename Application>
class /*DECLSPEC*/ QtService : public QtServiceBase

딱히 별건 아니고, 저 DECLSPEC은 #define을 통해 library의 header를 바꿉니다. 정확히는 Q_DECL_EXPORT나 Q_DECL_IMPORT 중 하나로 바뀌게 되는데, 라이브러리를 빌드할 때가 아니면 항상 Q_DECL_EXPORT로 선언되어 있습니다. 문제는 뭐냐 하면, QtService 자체는 template class라서 그때그때 symbol이 달라질 수밖에 없는데, 해당 함수를 Q_DECL_EXPORT로 선언해버리면 컴파일러는 해당 symbol이 이미 library로 export된 것으로 판단하고 별다른 조치를 취하지 않는다는데 있습니다. 실제로 저 DECLSPEC을 주석 처리한 뒤 컴파일 결과를 확인해보면 qtservice.o 파일이 별도로 생성된 것을 볼 수 있습니다.

이거 하나를 찾아내려고 꽤나 삽질이 많았습니다만, 그래도 생각보다 쉽게 찾아내서 다행입니다. 이제는 LGPL을 지키면서 마음놓고 개발할 수 있어요. :)

No comments:

Post a Comment

블로그를 이전합니다

뭐, 이런 작은 변방의 블로그에 관심있으신 분들은 아무도 없으시리라 생각합니다만...... (웃음) 블로그 플랫폼을 블로거에서 dev.to로 옮겼습니다. 새 URL은 아래와 같습니다: https://dev.to/teminian 새로운 거처에서 뵙겠습니...

Popular in Code{nested}