Pages

Showing posts with label MinGW. Show all posts
Showing posts with label MinGW. Show all posts

Monday, September 23, 2019

Let's build DPDK in Windows with MinGW-w64

There's a library named DPDK(Data Plane Development Kit. https://www.dpdk.org). Previously led by Intel, now it's a project from the Linux Foundation. The aim of this project is to make a packet from NIC to bypass kernel and go to userspace right away. Though you need to make your hands quite dirty, it's worth it.

So what? DPDK started to support Windows from 19.05(ta-da!). Though it supports only the basics, the team plans to broaden supported features more and more.

Well, there's a problem, though - you need LLVM+MSVC+meson+ninja to build the library. Even the official documentation explains that way. But you know what? You can replace LLVM+MSVC to MinGW-w64. Yes, you can use MinGW-w64+meson+ninja as your toolchain to build DPDK in Windows.

First, let's see meson commmands.
  • set CC=gcc
  • meson -Dexample=helloworld -Dc_args="-D_WIN32_WINNT=0x0601" build
  • cd build
After this, when ninja.build file is created, replace /imp: to --out-implib, and remove -Wl containing /def.  After that, just run ninja to get your library ready to serve.

Quite easy, huh?

Windows에서 MinGW-w64로 DPDK를 빌드해보자

DPDK(Data Plane Development Kit)란 라이브러리가 있습니다(https://www.dpdk.org/). 과거에는 인텔이 주도했고, 지금은 리눅스 재단에서 열심히 밀어주고 있는 프로젝트죠. 이게 뭔가 하면, 네트워크 카드에서 패킷이 날아오면 이걸 커널을 통과하지 않고 바로 userspace로 보내줄 수 있는 환경을 만들어줍니다. 대신 잔손이 엄청 많이 가긴 하지만, 그럴만한 가치가 있는 라이브러리이기도 하죠.

그런데, 이 DPDK가 19.05부터는 Windows를 지원하기 시작했습니다(두둥). 지금 당장은 기본적인 기능밖에 지원되지 않습니다만, DPDK쪽에서는 차근차근 지원 가능한 기능을 늘려가겠다는 입장입니다.

단지 지금 당장 문제라면...... 이걸 빌드하려면 LLVM+MSVC+meson+ninja가 필요하다는 거죠. 공식 메뉴얼에도 저걸로 빌드하라고 되어 있고요. 그런데, LLVM+MSVC를 MinGW-w64로 대체할 수 있습니다. 즉, MinGW-w64+meson+ninja로 빌드가 가능합니다.

일단 meson쪽의 빌드 커맨드는 이렇습니다.
  • set CC=gcc
  • meson -Dexample=helloworld -Dc_args="-D_WIN32_WINNT=0x0601" build
  • cd build
이후 ninja.build 파일이 생성되면 /imp:를 --out-implib=으로 고치고, /def가 포함된 -Wl 구문을 모두 지워주시면 됩니다. 그 이후 ninja를 실행하면 빌드 완료!

어때요, 참 쉽죠? (..??)

Tuesday, June 12, 2018

MinGW 8.1.0 vs. VC++2017: performance benchmark

I don't know why, but after writing down that I'm going to VC++2017 yesterday I took a simple benchmark testing. No, it was not that much delicate: it reads a file via ifstream and in the memory it parses the data, and the performance was checked with GetTickCount(). The result was that MinGW was always 10~30% faster than VC++2017.

Hmmm...... Do I have to get back to MinGW?

MinGW 8.1.0 vs. VC++2017: 수행성능 비교

어제 VC++2017로 가겠다고 써놓고 무슨 바람이 불었는지 간단한 퍼포먼스 벤치마킹을 수행했습니다. 제가 능력이 출중해서 정교한 실험을 한 건 아니고, 그냥 ifstream으로 파일을 읽은 후 메모리에 올려서 약간의 parsing을 하는 작업을 GetTickCount()로 찍어서 체크해봤는데, 제 사용 사례의 경우에는 MinGW가 VC++2017보다 항상 10~30%정도 더 빠르더군요.

MinGW로 돌아가야 되나...... 싶습니다. -_-

Tuesday, August 9, 2016

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

Sunday, February 28, 2016

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/

Tuesday, June 9, 2015

mingw-builds 5.1.0R0으로 Qt Creator 3.4.1을 빌드하기

mingw-builds 5.1.0 Release 0으로 Qt Creator 3.4.1을 빌드하는 동안 발견되는 문제들과 그 해결방안(이라기보단 우회방안)을 정리했습니다.

----------------------------------------
[QString::QString(const char *) is private]
문제가 되는 부분은 src/lib/corelib/tools/filetime_win.cpp의 108번째 줄입니다. QT_NO_CAST_FROM_ASCII이 선언되었을때 QString의 헤더 파일과 관련되어 있는 것 같긴 한데, 자세한건 잘 모르겠네요.

일단 보시면, 해당 부분은 이렇게 생겼습니다:
const QString result = QString("%1.%2.%3 %4:%5:%6")

이 부분을 이렇게 바꾸면 어쨌든 해결됩니다:
const QString result = QString(QLatin1String("%1.%2.%3 %4:%5:%6"))

뭐 일단 컴파일이 되는게 중요하죠. ;)

----------------------------------------
[Psapi.lib is not found]
이 건 역시 qbs 빌드시 발생하는 오류입니다. 경우에 따라 src/shared/qbs/src/lib/corelib디렉토리에 있는 Makefile.Debug 또는 Makefile.Release 파일을 수정해야 합니다. 텍스트 에디터로 파일을 연 뒤 Psapi.lib를 찾아보면 다음과 같은 내용을 발견할 수 있습니다:

LIBS        =        -lglu32 -lopengl32 -lgdi32 -luser32 Psapi.lib -LD:/Components/Qt-5.4.2-MinGW32-5.1.0R0/qtbase/lib -lQt5Script -lQt5Gui -lQt5Xml -lQt5Core release\qbscore_resource_res.o 

아래와 같이 Psapi.lib-lpsapi로 바꿔주기만 하면 문제가 해결됩니다:
LIBS        =        -lglu32 -lopengl32 -lgdi32 -luser32 -lpsapi -LD:/Components/Qt-5.4.2-MinGW32-5.1.0R0/qtbase/lib -lQt5Script -lQt5Gui -lQt5Xml -lQt5Core release\qbscore_resource_res.o

아무래도 VC nmake에서 GNU makefile로 설정을 갖다붙이다가 실수한 것 같습니다. 어째 개발진 양반들이 파일 만들면서 딴생각을 한 것 같네요. :P

----------------------------------------
[MIB_TCP_STATE is not declared]
만일 Visual Studio를 쓴다면 단지 iphlpapi.h를 인클루드하는 것으로 모든게 해결됩니다만, MinGW에서는 이걸 손수 선언해줘야 합니다. src/lib/utils에 있는 tcpportsgatherer.cpp파일을 보시면 이런 내용을 보실 수 있습니다:
// Missing declarations for MinGW 32.
#if __GNUC__ == 4 && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2)
typedef enum { } MIB_TCP_STATE;
#endif

아무래도 GCC 버전이 4.X일때만 동작하는 것 같죠? #if 부분을 comment out하는 걸로 해결할 수 있습니다.
// Missing declarations for MinGW 32. 
//#if __GNUC__ == 4 && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2)
typedef enum { } MIB_TCP_STATE;
//#endif

이걸로 끝입니다. Qt Creator 3.4.1로 오신 여러분을 환영합니다!

Building Qt Creator 3.4.1 with mingw-builds 5.1.0R0

There are some issues in building Qt Creator with mingw-builds 5.1.0 Release 0. Here are compile errors and workarounds:

----------------------------------------
[QString::QString(const char *) is private]

The issue occurs in building qbs and on line 108 of file src/lib/corelib/tools/filetime_win.cpp. It seems to be related to QString header file when QT_NO_CAST_FROM_ASCII is defined, but I have no idea on details.

You can see the line looks like this:
const QString result = QString("%1.%2.%3 %4:%5:%6")


And you can change the line like this to workaround:
const QString result = QString(QLatin1String("%1.%2.%3 %4:%5:%6"))

Now it's resolved anyway. ;)

----------------------------------------
[Psapi.lib is not found]
One more build error when building qbs. You've got to manually edit either Makefile.Debug or Makefile.Release in src/shared/qbs/src/lib/corelib directory. Search for Psapi.lib with your favorite text editor, and you'll see this:
LIBS        =        -lglu32 -lopengl32 -lgdi32 -luser32 Psapi.lib -LD:/Components/Qt-5.4.2-MinGW32-5.1.0R0/qtbase/lib -lQt5Script -lQt5Gui -lQt5Xml -lQt5Core release\qbscore_resource_res.o 

Just change Psapi.lib to -lpsapi as shown below and it's done:
LIBS        =        -lglu32 -lopengl32 -lgdi32 -luser32 -lpsapi -LD:/Components/Qt-5.4.2-MinGW32-5.1.0R0/qtbase/lib -lQt5Script -lQt5Gui -lQt5Xml -lQt5Core release\qbscore_resource_res.o

It seems to be human error when copy-and-pasting VC nmake file to GNU makefile. Hey Trolls, WAKE UP!

----------------------------------------
[MIB_TCP_STATE is not declared]
If you're using Visual Studio, it's okay by just including iphlpapi.h in your source code, yet with MinGW you have to declare yourself. If you read the file tcpportsgatherer.cpp in src/lib/utils you'll see something like this:
// Missing declarations for MinGW 32.
#if __GNUC__ == 4 && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2)
typedef enum { } MIB_TCP_STATE;
#endif

Well, this seems to work only if you're using GCC version 4.X, not with 5.1.0. Just comment #if like this and you're done.
// Missing declarations for MinGW 32.
//#if __GNUC__ == 4 && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2)
typedef enum { } MIB_TCP_STATE;
//#endif

Now everything's done. Welcome to the world of Qt Creator 3.4.1! :)

Thursday, November 27, 2014

Windows에서 libssh2를 MinGW로 빌드하기

cmake를 사용하는 libssh와는 달리, libssh2는 Windows에서 리눅스와 같은 환경에서 프로그램을 컴파일하기를 요구합니다-이를테면 MSYS같은게 필요하죠. 인터넷에 보면 libssh2를 빌드하는 많은 방법들이 있습니다만, 이들 중 상당수는 소스코드나 빌드파일을 어느 정도까지는 스스로 고쳐야 합니다.

그래서…… 평소 성향대로, 이 포스팅에서는 좀 반대로 가려고 합니다.소스코드에 손대지 않고 빌드하는 방법을 소개합니다.

준비물은 아래와 같습니다:

  1. MSYS
  2. MinGW-w64 기반 빌드가 필요합니다. 제가 테스트한 환경은 두 군데입니다: MinGW-builds 64bit-winthreads-SEH exception build와 TDM-GCC 64bi
  3. 물론, libssh2의 소스코드도 필요합니다. :P
빌드는 다음 순서대로 진행합니다:
  1. 소스코드 압축을 해제합니다.
  2. 가장 중요한 단계입니다: configure에서 OpenSSL과 OpenSSL이 의존하는 Win32 라이브러리를 강제로 참조하도록 합니다. 이를테면 이런 식입니다:
    ./configure –with-libs-prefix=“/d/Components/openssl” –with-libssl-prefix=“/d/Components/z"  LDFLAGS=”-L/d/Components/openssl/lib -lssl -l crypto -lgdi32 -lws2_32"
  3. [Optional] 만일 64비트로 빌드해야 한다면 –build=amd64를 LDFLAGS 이전에 삽입해주세요. 이런 요령으로 하시면 됩니다:
    ./configure –with-libs-prefix=“/d/Components/openssl” –with-libssl-prefix=“/d/Components/z” –build=amd64 LDFLAGS=“-L/d/Components/openssl/lib -lssl -l crypto -lgdi32 -lws2_32”
  4. make 실행후 모니터를 감상해주세요. :)
  5. 빌드 끝!
별건 아닙니다만, 이 글이 libssh2를 손수 빌드하려는 길잃은 양(……)들께 도움이 되셨으면 합니다.

Compiling libssh2 in Windows with MinGW-builds

Unlike libssh, which uses cmake, libssh2 forces you to use Linux-like environment even in Windows, which eventually makes you to install MSYS on your system. You can find many ways are to build libssh2 in Windows on the net, but most of them requires you to manually edit configuration files in some way.

OK, here goes the opposite…… You’ll NOT MAKE ANY CHANGES in the source code.

First, the requirements:

  1. MSYS
  2. MinGW-w64 based build. I used two variants: MinGW-builds 64bit-winthreads-SEH exception build, but TDM-GCC 64bit also works
  3. libssh2 source codes(of course! :P)
And the procedure:
  1. Decompress the source code.
  2. The most important step: force to add OpenSSL and Win32 libraries OpenSSL needs on configure step, something like this:
    ./configure –with-libs-prefix=“/d/Components/openssl” –with-libssl-prefix=“/d/Components/z” LDFLAGS=“-L/d/Components/openssl/lib -lssl -l crypto -lgdi32 -lws2_32”
  3. [Optional] If you’re building 64bit binary, dont forget to add –build=amd64 before LDFLAGS, like this:
    ./configure –with-libs-prefix=“/d/Components/openssl” –with-libssl-prefix=“/d/Components/z” –build=amd64 LDFLAGS=“-L/d/Components/openssl/lib -lssl -l crypto -lgdi32 -lws2_32”
  4. run make and enjoy. :)
  5. PROFIT!
Hope this helps some lost sheeps who want to build libssh2 in his/her own.

Monday, September 15, 2014

Building cURL under MinGW-w64 with zlib and SSL support under Windows

It’s simple:
mingw32-make mingw32-winssl-zlib

Do not use OpenSSL. Substitute it with Windows native SSL support. I have no idea on why but it seems to be related to linker.

Windows에서 MinGW-w64로 zlib와 SSL이 지원되는 cURL 빌드하기

간단합니다:
mingw32-make mingw32-winssl-zlib

핵심은 OpenSSL을 사용하지 않는 대신 Windows의 native SSL 지원으로 바꾸는 겁니다. 이유는 잘 모르겠지만 linker에서 뭔가가 잘못된 것 같더군요.

Wednesday, February 26, 2014

Windows에서 MinGW-builds(MinGW-w64)를 이용하여 libssh를 빌드하는 경우 유 의점

라이브러리 의존성: zlib, openssl

메모

  • zlib: 큰 문제 없음. mingw32-make -f win32/Makefile.gcc 한방으로 해결 가능
  • openssl: www.mingw.org에서 MSYS를 다운로드받은 후, 소스코드를 MSYS의 tar로 풀어낼것. 그렇지 않은 경우 tarball 안에 있는 symlink가 제대로 처리되지 않음
  • libssh: 두가지 유의사항이 있음
    1. 빌드 디렉토리는 소스코드 디렉토리가 아닌 다른 곳이어야 함
    2. 소스코드 직접 수정 필요: return pthread_self().p를 return pthread_self()로 수정해야 함. 이는 MinGW-builds와 www.mingw.org 양쪽 경우에 대해 pthread 드라이버의 구현 방식이 다르기 때문일 것으로 추측함(소스코드를 비교해보지는 않았음)

Monday, February 24, 2014

Memo on building libssh in Windows with MinGW-builds(MinGW-w64)

Requirements: zlib, openssl

Remarks

  • zlib: Just mingw32-make -f win32/Makefile.gcc and that’s all
  • openssl: Install MSYS from www.mingw.org and use tar on that MSYS package to untar the source tarball. If not, the links on the tarballs are not adequately managed
  • libssh: two things
    1. The build directory should be other than the source tree
    2. You’ve got to edit source code to return pthread_self(), rather than pthread_self().p, which is used under #ifdef _WIN32_. This seems to be because of the differences of pthread implementations between mingw.org and mingw-w64 (though not I didn’t compare the source codes)

Sunday, January 8, 2012

How to make import library from DLL(for Visual C++ or MinGW)

Just a note for myself.

How to refine VC++ import library LIB files for DLLs created from Lazarus or MinGW:
  • dumpbin /exports file.dll(dumpbin is included in VC++)
  • Use a text editor to write a def file(e.g. file.def) like the content below:
    EXPORTS
    functiona
    functionb
    functionc
    ……
  • lib /def:file.def to create lib file
  • use the lib file in compilation of application to make the application aware of DLL entry points

To use DLLs from Visual C++ to MinGW, the def files from dumpbin can be compiled into .a files(library files for GCC) with DLLTOOL in MinGW:
  • dlltool -U -d file.def -l file.a
Compatibility note: for compatibility with other compilers and languages(e.g. C++ vs. Pascal), always use stdcall for calling convention and extern “C” in C++ side.