Kategorien
Ohne Kategorie

Mit CMake + MinGW Windows-Ressourcen in die .exe bauen

Für den Bau einer Windows DLL oder EXE ist es meistens erforderlich, eine Ressourcendatei (.rc) zu integrieren. In dieser gibt man beispielsweise Versionsinformationen an oder versieht eine Anwendung mit einem Icon. Dazu übersetzt man die .rc-Datei mit dem Programm windres in eine Objektdatei und linkt diese in die ausführbare Datei.

CMake übernimmt diese Aufgabe automatisch, man muss lediglich die .rc-Datei als Quelldatei mit angeben:

add_executable(App main.c icon.rc version.rc)

So zumindest in der Theorie. So ganz automatisch ging das dann doch nicht, zumindest nicht bei mir. Zuerst musste ich CMake mitteilen, dass es die .rc-Dateien übersetzen soll:

enable_language(RC)

Damit funktioniert das ganze schon mal mit dem Microsoft-Compiler und dessen windres. Auch MinGW bringt den windres-Compiler mit, allerdings mit anderen Aufrufparametern. Daher schlug die Übersetzung der .rc-Dateien fehl. Um CMake den korrekten Aufruf mitzuteilen, war ein weiterer Befehl nötig:

if (${MINGW})
    SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif()

Eigentlich sollte CMake seit Version 2.8.7 auch mit MinGW-windres zusammenarbeiten, zumindest laut dem TigerVNC-Projekt. Trotz der von mir verwendeten Version 3.12 hatte ich jedoch nur mit obigem Workaround Erfolg.

Kategorien
Ohne Kategorie

Qt5 Anwendung mit MinGW 9 übersetzen

Versucht man eine Qt5 Anwendung mit MinGW-W64 zu übersetzen, stößt man sehr wahrscheinlich auf folgendes Problem:

In file included from /usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/bits/stl_algo.h:59,
                 from /usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/algorithm:62,
                 from /opt/Qt5/include/QtCore/qglobal.h:142,
                 ...

/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/include/c++/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
   75 | #include_next <stdlib.h>
      |               ^~~~~~~~~~
compilation terminated.

Hilfreich dabei war ein Blog-Eintrag von ocroquette: Die Fehlerursache liegt in den System-Includepfaden, die man gcc mit dem -isystem Schalter mitteilt. Leider fügt Qt5 seine eigenen Headerdateien selbst als System-Include hinzu und sorgt dadurch dafür, dass der Standard-Includepfad von MinGW32 nicht mehr von den Qt5 Headerdateien beachtet wird. Zur Lösung muss man diesen manuell hinzufügen, beispielsweise in CMake:

if (${MINGW})
    list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES /usr/x86_64-w64-mingw32/include)
endif()

Dieser Codeschnipsel sollte am besten nach dem Importieren von Qt5 und vor dem Definieren eigener Targets einfügen.

Nachtrag vom 14.10.2020:

Mit Qt 5.14 kommt ein weiteres Problem hinzu, hier kommt der Fehler schon beim importieren von Qt5::Core zum Vorschein, jedoch findet MinGW diesmal seine Standardbibliotheken nicht mehr:

CMake Error at /opt/Qt5/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:92 (message):
    Library not found: mpr
Call Stack (most recent call first):
    /opt/Qt5/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:272 (_qt5_Core_process_prl_file)
  /opt/Qt5/lib/cmake/Qt5/Qt5Config.cmake:28 (find_package)
  CMakeLists.txt:13 (find_package)

Auch hier bringt Qt5 wohl den Standardincludepfad durcheinander, und der Fix ist sehr ähnlich wie oben:

if (${MINGW})
    list(APPEND CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/x86_64-w64-mingw32/lib)
endif()