23. MÄRZ 2020

ogre3d - 1.10.10 [win32]

Inhalt

Probleme beim Erzeugen von Ogre3D Version 1.10.10 für Windows32. Dieses Dokument enthält absichtlich keine Compiler-spezifischen KB_TAGS da sich diese für eine Problemlösung bei Bedarf ändern könnte.

Das Projekt basiert auf cmake. Es ist unbedingt notwendig das ein Toolchain-File verwendet wird um wichtige Umgebungsvariablen zu setzen! Die letzte Version dieser Datei: win32_toolchain.txt

Die Reihenfolge der Child-Dokumente dieses Dokuments spiegelt die Reihenfolge wieder in welcher die Probleme aufgetreten sind. Das neueste Child-Dokument spiegelt die zuletzt gültigen Erkenntnisse wieder. Frühere Child-Dokumente verwenden unter Umständen noch Parameter welche letztlich dann revidiert wurden!

Status: Das Projekt konnte nun erfolgreich kompiliert werden. Getestet wurde es allerdings noch nicht. Es sind auch noch Unschönheiten dabei, primär die Locale-Problematik da diese durch den Patch in https://www.wittnet.org/kb/build/23d07129-2982-4db5-aac0-c1bc8bf7fbbe komplett deaktiviert wurden.

Ogre3D/win32: unrecognized command line option ‘-rdynamic’

Beim Aufruf von cmake .. im build/-Verzeichnis:

/usr/bin/i586-mingw32msvc-gcc -I/home/win32/include -L/home/win32/lib
CMakeFiles/cmTC_c5cb9.dir/testCCompiler.c.o -o cmTC_c5cb9 -rdynamic

i586-mingw32msvc-gcc: error: unrecognized command line option
‘-rdynamic’
win32@gnome:/tmp/ogre-1.10.10/build_win32$ i586-mingw32msvc-gcc -v
Using built-in specs.
COLLECT_GCC=i586-mingw32msvc-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/6.3-win32/lto-wrapper
Target: i686-w64-mingw32
Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir='/usr/lib/x86_64-linux-gnu' --libexecdir='/usr/lib/x86_64-linux-gnu' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libgomp --enable-languages=c,c++,fortran,objc,obj-c++ --enable-lto --with-plugin-ld --enable-threads=win32 --program-suffix=-win32 --program-prefix=i686-w64-mingw32- --target=i686-w64-mingw32 --with-as=/usr/bin/i686-w64-mingw32-as --with-ld=/usr/bin/i686-w64-mingw32-ld --enable-libatomic
Thread model: win32
gcc version 6.3.0 20170516 (GCC)

2018-09-14 13:09 - Möglicherweise können hier Umgebungs-Variablen das Verhalten von cmake positiv beeinflussen. Das Problem ist das cmake davon ausgeht das es sich um ein Linux-Target handelt? Siehe auch https://cmake.org/cmake/help/v2.8.11/cmake.html#variable:CMAKE_HOST_SYSTEM für die Liste von möglichen CMake-Variablen.


2018-09-15 10:21 - Das Problem ist scheinbar das CMAKE_SHARED_LIBRARY_LINK_C_FLAGS falsch gesetzt wird. Warum wird überhaupt /usr/share/cmake-3.7/Modules/Platform/Linux-GNU.cmake aufgerufen? Dort wird diese Variable auf -rdynamic gesetzt.

Sehr nützlich in diesem Zusammenhand ist die --trace-Option von CMake. Sie wird wie folgt aufgerufen:

cmake --trace -DCMAKE_TOOLCHAIN_FILE=test ..

Hier sieht man auch die Einbindung eines Toolchain-Files wo ebenso Variablen gesetzt werden können. Allerdings werden diese dann von anderen Includes überschrieben.


2018-09-15 10:32 - Problem wurde gelöst. Es muss die Variable CMAKE_SYSTEM_NAME auf Windows gesetzt werden (Per Toolchain-File). Das Toolchain-File muss deshalb wie folgt aussehen:

set(CMAKE_SYSTEM_NAME "Windows")

/bin/sh: 1: windres: not found

win32@gnome:/tmp/ogre-1.10.10/build$ make
[  0%] Generating OgreWin32Resources.rc.obj
/bin/sh: 1: windres: not found
OgreMain/CMakeFiles/OgreMain.dir/build.make:62: recipe for target 'OgreMain/OgreWin32Resources.rc.obj' failed
make[2]: *** [OgreMain/OgreWin32Resources.rc.obj] Error 127

Obsolete: Das Toolchain-File muss wie folgt aussehen damit die richtige Version von windres verwendet wird:

set(CMAKE_SYSTEM_NAME "Windows")
set(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres")

Achtung Fehler! Oben wird die 64-bit Version verwendet welche dann letztendlich Fehler beim Linken produziert. Richtig muss es wie folgt aussehen:

set(CMAKE_SYSTEM_NAME "Windows")
set(CMAKE_RC_COMPILER "i586-mingw32msvc-windres")

Der Fehler wurde in der Doku zwecks Referenz belassen.

/usr/include/stdlib.h:62:5: error: conflicting declaration ‘typedef struct div_t div_t’

TODO: Es muss herausgefunden werden warum Autobuild hier unterschiedlich bei SDL2 reagiert. Warum werden hier die Linux-Versionen von SDL2 verwendet? Scheinbar spielt PKG_CONFIG_PATH hier eine große Rolle. Wird autobuild.env auskommentiert so dürfte der Build funktionieren.


Obwohl hier für Win32 kompiliert werden soll wird /usr/include/stdlib.h verwendet. Ob hier beim Initial cmake-Befehl noch etwas vergessen wurde oder ob diverse Makefiles hier nachträglich verwendet werden müssen ist unklar. Eventuell genügt es wenn Umgebungsvariablen entsprechend gesetzt werden?

[  0%] Building CXX object OgreMain/CMakeFiles/OgreMain.dir/src/OgreASTCCodec.cpp.obj
In file included from /usr/share/mingw-w64/include/sec_api/stdlib_s.h:9:0,
                 from /usr/share/mingw-w64/include/stdlib.h:694,
                 from /usr/lib/gcc/i686-w64-mingw32/6.3-win32/include/c++/cstdlib:75,
                 from /usr/lib/gcc/i686-w64-mingw32/6.3-win32/include/c++/ext/string_conversions.h:41,
                 from /usr/lib/gcc/i686-w64-mingw32/6.3-win32/include/c++/bits/basic_string.h:5417,
                 from /usr/lib/gcc/i686-w64-mingw32/6.3-win32/include/c++/string:52,
                 from /tmp/ogre-1.10.10/OgreMain/include/OgrePrerequisites.h:32,
                 from /tmp/ogre-1.10.10/OgreMain/include/OgreArchive.h:31,
                 from /tmp/ogre-1.10.10/OgreMain/include/OgreStableHeaders.h:42,
                 from /tmp/ogre-1.10.10/OgreMain/src/OgreASTCCodec.cpp:29:
/usr/include/stdlib.h:62:5: error: conflicting declaration ‘typedef struct div_t div_t’
   } div_t;

Ein Workaround wurde nun gefunden. Der Fehler steckt in der Datei includes_CXX.rsp welche sich im Build-Verzeichnis unter OgreMain/CMakeFiles/OgreMain.dir befindet. Löscht man dort den Eintrag mit -I/usr/include so tritt obiger Fehler nicht mehr auf.


Nachtrag: Es müssen alle Versionen von includes_CXX.rsp modifiziert werden, d.h. es muss überall -I/usr/include entfernt werden! Dies passiert am einfachsten mittels folgenden Befehl (Man muss sich im build/-Verzeichnis befinden!)

find -iname "*includes*" | xargs -l1 sed -i "s#-I/usr/include##g"

Der obige Befehl findet auch includes_C.rsp Dateien wo diese Änderung auch passieren sollte!


Achtung: Es ist im Zuge der Autobuild-Integration ein neuer Fehler aufgetreten welcher zu der Problematik von diesem Dokument passt:

[ 65%] Building CXX object Components/Bites/CMakeFiles/OgreBites.dir/src/OgreAdvancedRenderControls.cpp.obj
i586-mingw32msvc-g++: error: /SDL2: No such file or directory
Components/Bites/CMakeFiles/OgreBites.dir/build.make:63: recipe for target 'Components/Bites/CMakeFiles/OgreBites.dir/src/OgreAdvancedRenderControls.cpp.obj' failed
make[2]: *** [Components/Bites/CMakeFiles/OgreBites.dir/src/OgreAdvancedRenderControls.cpp.obj] Error 1
CMakeFiles/Makefile2:687: recipe for target 'Components/Bites/CMakeFiles/OgreBites.dir/all' failed
make[1]: *** [Components/Bites/CMakeFiles/OgreBites.dir/all] Error 2
Makefile:149: recipe for target 'all' failed
make: *** [all] Error 2

Der Grund hierfür liegt beim obigen find-Befehl. Korrekt wäre

find -iname "*includes*" | xargs -l1 sed -i "s#-I/usr/include/SDL2##g"
find -iname "*includes*" | xargs -l1 sed -i "s#-I/usr/include##g"

Es tritt aber nur mit Autobuild auf. Möglicherweise sind noch andere Includes davon betroffen?

Update: Das eigentliche Problem dürfte bei SDL liegen. Scheinbar wird unter Verwendung von Autobuild das Linux-eigene SDL verwendet was beim direkten Kompilieren mit dem Win32-User nicht der Fall ist. Deshalb entsteht überhaupt auch das obige Include /usr/include/SDL2 was ja beim Testen ohne Autobuild nicht der Fall war.

/tmp/ogre-1.10.10/OgreMain/src/OgreStringConverter.cpp:43: undefined reference to `_create_locale'

[  0%] Linking CXX shared library ../bin/OgreMain.dll
CMakeFiles/OgreMain.dir/objects.a(OgreStringConverter.cpp.obj): In function `_static_initialization_and_destruction_0':
/tmp/ogre-1.10.10/OgreMain/src/OgreStringConverter.cpp:43: undefined reference to `_create_locale'
collect2: error: ld returned 1 exit status
OgreMain/CMakeFiles/OgreMain.dir/build.make:5315: recipe for target 'bin/OgreMain.dll' failed
make[2]: *** [bin/OgreMain.dll] Error 1

Die Funktion _create_locale() ist in den derzeit verwendeten MinGW-Libraries nicht vorhanden. Es sieht so aus als ob neuere Implementationen diese Funktion integriert haben.

Um das Problem temporär anders zu lösen müssen Änderungen im Source vorgenommen werden:

--- OgreStringConverter.cpp     2018-09-19 09:35:20.336551330 +0200
+++ /tmp/OgreStringConverter.cpp        2018-09-19 09:35:13.072576310 +0200
@@ -31,8 +31,11 @@
 #include "OgrePlatform.h"

 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT
+/*
 #   define LC_NUMERIC_MASK LC_NUMERIC
 #   define newlocale(cat, loc, base) _create_locale(cat, loc)
+*/
+#   define newlocale(cat, loc, base) 0
 #endif

 #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN

Obigen Text unter zB. /tmp/my.patch speichern und dann im Verzeichnis OgreMain/src den Befehl patch < /tmp/my.patch absetzen.



Keywords: todo
Dokumenten-ID: build/3f076fce-0eca-451e-a043-c4f0619001f2

Verweise:
ogre3d - 1.10.10 [win64]




Startseite - Keywords - Sitemap - Impressum