Difference between revisions of "Cross-compiling Windows version from Linux"

From Armagetron
m (Cross-compiler moved to Cross-compiling Windows version from Linux: Not all cross-compiling targets Windows...)
(none of this stupid shit here worked so fucking get your shit together)
Tag: Replaced
Line 1: Line 1:
Just collecting cross-compilation notes.
+
this shit does NOT fucking work someone please fix this fucking garbage
 
 
=Autotools=
 
 
 
== Setting up the cross compiler under linux ==
 
 
 
Check your distribution for mingw packages.  If it has it, install them.  If not, try this:
 
 
 
http://www.libsdl.org/extras/win32/cross/
 
 
 
Export some environment variable:
 
 
 
export CC=i586-mingw32msvc-gcc
 
export CXX=i586-mingw32msvc-c++
 
export LD=i586-mingw32msvc-ld
 
export AR=i586-mingw32msvc-ar
 
export AS=i586-mingw32msvc-as
 
export NM=i586-mingw32msvc-nm
 
export STRIP=i586-mingw32msvc-strip
 
export RANLIB=i586-mingw32msvc-ranlib
 
export DLLTOOL=i586-mingw32msvc-dlltool
 
export OBJDUMP=i586-mingw32msvc-objdump
 
export RESCOMP=i586-mingw32msvc-windres
 
 
 
You might want those in a script.
 
 
 
== Libraries ==
 
 
 
You'll need to use the same configure command to configure and install the libraries.  Get libSDL and libxml2 and do this:
 
 
 
./configure --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc
 
 
 
Prefix is the location of your cross-compiler, it should have "bin", "lib", and "include" in it.
 
 
 
To get libxml2 to cross-compile, use this as your configure command:
 
 
 
./configure --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc --with-python=no
 
 
 
== Armagetron Advanced ==
 
 
 
You need to set some influential environment variables to make it configure.
 
 
 
XML2_CONFIG=/path/to/cross-compiled/xml2-config
 
SDL_CONFIG=/path/to/cross-compiled/sdl-config
 
 
 
Example:
 
 
 
XML2_CONFIG=/usr/i586-mingw32msvc/bin/xml2-config SDL_CONFIG=/usr/i586-mingw32msvc/bin/sdl-config ../../armagetronadnew/configure --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc --disable-sound
 
 
 
Currently it's failing for me with this line:
 
 
 
  checking for glVertex3f in -lopengl32... no
 
  OpenGL not found. Maybe it needs X11 to compile? Checking that...
 
 
 
== Dedicated Server ==
 
 
 
Same as above, only try this configure line instead:
 
 
 
 
 
XML2_CONFIG=/usr/i586-mingw32msvc/bin/xml2-config SDL_CONFIG=/usr/i586-mingw32msvc/bin/sdl-config CFLAGS="-I/usr/i586-mingw32msvc/include -DNO_SOCKLEN_T" CXXFLAGS="-I/usr/i586-mingw32msvc/include" ../../armagetronadnew/configure --host=i586-mingw32msvc --prefix=/home/dave/Projects/armagetronad/aabuild/win32install --disable-sound --disable-glout --disable-binreloc
 
 
 
This will configure and build the dedicated server with a recent trunk checkout.  The dedicated server that's built this way has a few issues to work out, but it'll run in Win98 and Wine, the difference being that in Wine you can't connect a client to it.
 
 
 
 
 
=CMake=
 
It is almost possible to cross-build a dedicated server on this branch with linux as build platform and windows as host, so I'm documenting this here
 
==Dependencies==
 
Many dependencies had cross-building packages in archlinux's user contributed repository, so I'm only documenting the ones I had trouble with.
 
===protobuf===
 
The build process of protobuf includes some .proto compiling with the protoc utility. Since you're going to build protobuf for windows on a linux box, you won't be able to use the protoc you'll build, so you need to have another protoc built for linux with the """same version""" as what you are building.
 
 
 
Once you have built it(or if it is in your system), you need to tell protobuf's configure script where prtoc is:
 
./configure --host=i486-mingw32 --with=protoc=/path/to/protobuf-x.x.x/src/protoc
 
 
 
One tiny bug will however cause protobuf 2.3.0 not to compile for windows on GCC. It is being fixed for protobuf 2.3.1[http://code.google.com/p/protobuf/issues/detail?id=155]. You can fix it by editing <code>src/google/protobuf/compiler/subprocess.h</code> at line <code>79</code>: Change
 
static string Subprocess::Win32ErrorMessage(DWORD error_code);
 
to
 
static string Win32ErrorMessage(DWORD error_code);
 
 
 
===FTGL===
 
FTGL's configure script has a bugger: It will look for libGL even though you're compiling for windows which uses libopengl32. Just go ahead and apply this patch of mine to <code>m4/gl.m4</code>
 
--- /home/epsy/SOURCES/ftgl/src/ftgl-2.1.3~rc5/m4/gl.m4 2008-05-05 16:48:57.000000000 +0200
 
+++ m4/gl.m4 2010-02-22 00:38:09.000000000 +0100
 
@@ -54,19 +54,23 @@
 
 
 
  AC_MSG_CHECKING([for GL library])
 
  if test "x$with_gl_lib" != "x" ; then
 
-    if test -d "$with_gl_lib" ; then
 
+    if test -d "$with_gl_lib" -a "x$host_os" != "xmingw32" ; then
 
          LIBS="-L$with_gl_lib -lGL"
 
+    elif test -d "$with_gl_lib"; then
 
+        LIBS="-L$with_gl_lib -lopengl32"
 
      else
 
          LIBS="$with_gl_lib"
 
      fi
 
-else
 
+elif test "x$host_os" != "xmingw32"; then
 
      LIBS="-lGL"
 
+else
 
+    LIBS="-lopengl32"
 
  fi
 
-AC_LINK_IFELSE([AC_LANG_CALL([],[glBegin])],[HAVE_GL=yes], [HAVE_GL=no])
 
+AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <GL/gl.h>],[glBegin(0)])],[HAVE_GL=yes], [HAVE_GL=no])
 
  if test "x$HAVE_GL" = xno ; then
 
      if test "x$GL_X_LIBS" != x ; then
 
          LIBS="-lGL $GL_X_LIBS"
 
-        AC_LINK_IFELSE([AC_LANG_CALL([],[glBegin])],[HAVE_GL=yes], [HAVE_GL=no])
 
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <GL/gl.h>],[glBegin(0)])],[HAVE_GL=yes], [HAVE_GL=no])
 
      fi
 
  fi
 
  if test "x$HAVE_GL" = xyes ; then
 
@@ -103,12 +107,19 @@
 
  if test "x$FRAMEWORK_OPENGL" = "x" ; then
 
 
 
  AC_MSG_CHECKING([for GLU library])
 
-LIBS="-lGLU $GL_LIBS"
 
-AC_LINK_IFELSE([AC_LANG_CALL([],[gluNewTess])],[HAVE_GLU=yes], [HAVE_GLU=no])
 
+if test "x$host_os" != "xmingw32" ; then
 
+    LIBS="-lGLU $GL_LIBS"
 
+else
 
+    LIBS="-lglu32 $GL_LIBS"
 
+fi
 
+AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <GL/glu.h>],[gluNewTess()])],[HAVE_GLU=yes], [HAVE_GLU=no])
 
  if test "x$HAVE_GLU" = xno ; then
 
-    if test "x$GL_X_LIBS" != x ; then
 
+    if test "x$GL_X_LIBS" != x -a "x$host_os" != "xmingw32" ; then
 
          LIBS="-lGLU $GL_LIBS $GL_X_LIBS"
 
-        AC_LINK_IFELSE([AC_LANG_CALL([],[gluNewTess])],[HAVE_GLU=yes], [HAVE_GLU=no])
 
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <GL/glu.h>],[gluNewTess()])],[HAVE_GLU=yes], [HAVE_GLU=no])
 
+    elif test "x$GL_X_LIBS" != x; then
 
+        LIBS="-lglu32 $GL_LIBS $GL_X_LIBS"
 
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <GL/glu.h>],[gluNewTess()])],[HAVE_GLU=yes], [HAVE_GLU=no])
 
      fi
 
  fi
 
  if test "x$HAVE_GLU" = xyes ; then
 
 
 
You can do so with the patch command:
 
patch m4/gl.m4 patchfile
 
Then rerun ./autogen.sh and run ./configure with the --without-x argument.
 
./configure --without-x --host=i486-mingw32 --prefix=/usr/i486-mingw32/
 
Once that's done edit the Makefile and throw somewhere in the beginning
 
ECHO=echo
 
Finally run <code>make</code> and <code>make install</code> as usual.
 
 
 
==Armagetronad itself==
 
===Toolchain file===
 
This is the file one usually uses with cmake to tell it what tools to use and what platform to build for. It is optionnal to make one, but it is very convenient to do one and it is project-independent.
 
SET(CMAKE_SYSTEM_NAME i486-mingw32)
 
SET(CMAKE_SYSTEM_VERSION 1)
 
SET(CMAKE_C_COMPILER /usr/bin/i486-mingw32-gcc)
 
SET(CMAKE_CXX_COMPILER /usr/bin/i486-mingw32-g++)
 
SET(CMAKE_FIND_ROOT_PATH /usr/i486-mingw32/)
 
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
 
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 
 
 
You will also need to make a symlink from <code>/usr/i486-mingw32/usr</code> to <code>/usr/i486-mingw32/</code>, because cmake's model assumes usual prefix for cross-compiled is <code>/usr/i486-mingw32/usr/</code> while most applications actually use <code>/usr/i486-mingw32/</code>, which is somewhat indeed a weird choice.
 
ln -s /usr/i486-mingw32/ /usr/i486-mingw32/usr
 
===Configuring===
 
Configuring should go relatively flawlessy, since no results from the host platform should be needed.
 
 
 
Simply tell cmake you want to use the toolchain file you just created
 
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/your/toolchainfile.cmake -DDEDICATED=yes .
 
 
 
Note that if you do an outsourced build, you should make sure the source directory is empty of build files. Otherwise weird errors might pop up. You also won't be able to run armagetronad without installing it, as with a classical outsourced build.
 
 
 
===Buidling===
 
For the dedicated server (client doesn't configure properly yet), type
 
make armagetronad-dedicated
 

Revision as of 22:49, 1 March 2019

this shit does NOT fucking work someone please fix this fucking garbage