Recent trends in inflight entertainment system development

Recently I had some chance to use a lot of airlines, and I found some airlines have inflight entertainment system with quite remarkable user interface/experience. I tried to find out who was behind, and all of them were found to be developed by Panasonic Avionics. And what? The company is one of the protagonists in "customer success stories" from Qt Company.

Man, in the world of C++, Qt becomes the de facto standard.

최근의 inflight entertainment system 개발동향(?)

근저 비행기를 많이 타봤기에, 몇몇 항공사의 간지나는 인터페이스를 가진 inflight entertainment system들을 좀 수소문해봤더니 개발사가 모두 Panasonic Avionics더군요. 그리고 Panasonic Avionics는 Qt의 가장 대표적인 customer success story입니다.

......C++의 세계에서 대세는 역시 Qt인가 봅니다.

The case of linker unable to find symbol for QtService in MinGW-w64 when developing a Windows service based on QtWebApp

QtWebApp includes QtService for developer's sake when developing Windows service or Linux daemon. QtService is quite well made in many sense, but it's also "abandoned" by Qt Company for years.

I'm using mingw-builds, one of personal builds in MinGW-w64 project, to use the same compiler between Windows and Linux, as well as make use of easy portability. In recent development with QtWebApp I found out that if I dynamic-link QtWebApp the linker cannot find symbol for QtService<QCoreApplication>. As the version for GCC shipped with Qt 5.7 is 5.3 so it's not due to older compiler...... And I found a solution.

Open QtWebApp/qtservice/qtservice.h and find the line below.

template <typename Application>
class DECLSPEC QtService : public QtServiceBase

And I changed the line like this:

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

The DECLSPEC changes library header structure using #define. That is changed into either Q_DECL_EXPORT or Q_DECL_IMPORT, and unless it's the time to build the library itself, the value is always Q_DECL_EXPORT. The problem is that QtService is a template class, meaning that the symbol should be changed according to the template details, but if the function is declared as Q_DECL_EXPORT, the compiler assumes that necessary symbols are already built. If you see comment out that DECLSPEC and review the result of the compilation, you can see object file for the header file named qtservice.o.

Well, I had hard time to find this small thing, but I'm relieved that I found it quite quicker than expected. Now I can respect LPGL once again. :)

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을 지키면서 마음놓고 개발할 수 있어요. :)

Short thought about IUP

IUP is a good library, but has one problem: many times it fails to compile.
More exactly, the problem seems to be requirements needed for IUP, e.g. CD or IM.

......And I succeeded again. What on earth?!

IUP에 대한 단상

IUP는 다 좋은데...... 컴파일이 잘 안되네요. OTL
정확히는 IUP 자체보다 IUP를 컴파일하기 위한 다른 구성요소들이 좀 문제인 듯 합니다. 이를테면 CD라던가 IM이라던가......

......이래놓고는 또 한번 빌드해봤더니 멀쩡하게 또 잘되는건 함정. 뭘까요.

Building IBPP on MinGW-w64

When building IBPP on MinGW-w64 MinGW complains that "Only Win32 is supported." Hey, I'm on Windows and we're building a Win32 executable!

But well, don't forget we're using an open source project and we're free to review the source code. Let's see _ibpp.h to find out why:
#if (defined(__GNUC__) && defined(IBPP_WINDOWS))
// UNSETTING flags used above for ibase.h -- Huge conflicts with libstdc++ !
#undef _MSC_VER
#undef _WIN32
#endif
As you see, if the compiler is found to be MinGW it #undefs _WIN32. It seems to be because of the compatibility against MinGW 3.0, yet in MinGW-w64 this is the very reason to block the "normal" build.

Hope this would help any Firebird users, who want to use it with IBPP under MinGW-w64.

P.S:
For relations and differences between MinGW and MinGW-w64, please refer to the URLs below:
https://sourceforge.net/p/mingw-w64/wiki2/History/
https://sourceforge.net/p/mingw-w64/wiki2/Feature%20list/

IBPP를 MinGW-w64에서 빌드하려면......

IBPP를 MinGW-w64에서 빌드하려면 갑자기 MinGW가 "Only Win32 is supported!"라는 에러를 내보내면서 빌드가 멈춥니다. Windows에서 빌드하는게 맞는데 Win32만 지원한다면서 투덜대면 이것도 참 황당한데요......

IBPP의 _ibpp.h를 보면 그 원인을 찾을 수 있습니다.
#if (defined(__GNUC__) && defined(IBPP_WINDOWS))
// UNSETTING flags used above for ibase.h -- Huge conflicts with libstdc++ !
#undef _MSC_VER
#undef _WIN32#endif
컴파일러가 MinGW라고 판단되는 경우 _WIN32를 undef하는 것을 보실 수 있습니다. 아마도 MinGW 3.0의 호환성 문제때문에 이렇게 설정한 것 같은데, MinGW-w64에서는 이 구문이 역으로 빌드를 막는 원인이 되는 듯 합니다.

국내에 Firebird를 쓰는 분들, 특히나 IBPP를 MinGW환경에서 사용하실 분들이 몇 분이나 되실지는 모르겠지만, 참고가 되셨으면 합니다.

P.S:
MinGW와 MinGW-w64 프로젝트의 관계 및 차이점에 대해서는 아래의 URL을 참고하세요:
https://sourceforge.net/p/mingw-w64/wiki2/History/
https://sourceforge.net/p/mingw-w64/wiki2/Feature%20list/

블로그를 이전합니다

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

Popular in Code{nested}