Author Topic: Cross-compiling: Linux to Windows  (Read 5390 times)

0 Members and 1 Guest are viewing this topic.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Cross-compiling: Linux to Windows
« on: November 28, 2016, 01:33:38 AM »
I am in the process of setting up nightly builds for Simutrans-Experimental, using my Linux virtual server. I have managed to get it to work so far to produce Linux binaries and the paksets (see here), but I am having some trouble working out how to cross-compile for Windows, and I should be grateful for any help.

I have managed to download mingw-64 for Linux (apparently, this package includes both 32-bit and 64-bit cross-compiling build tools), but I cannot work out how to use them. All the tutorials that I can find are specific to pre-existing projects (e.g. how to cross-compile emacs), and rely on pre-written makefiles which, I assume, have already been configured to make use of mingw on Linux.

What I cannot find is:

(1) how to configure the makefile to use the mingw cross-compiler when a particular flag is set in the config file; and
(2) how to tell make to use something other than config.default (so that I can use a shell script to run Linux build and then a Windows build in the same code directory without having to maintain two separate directory structures just for different config.default files).

I should be very grateful indeed for any information on this. Thank you.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline TurfIt

Re: Cross-compiling: Linux to Windows
« Reply #1 on: November 28, 2016, 02:31:07 AM »
(1) Why? Seems needlessly complicated. Normally just override the defaults with environment vars and stick your cross toolchain in the path before invoking make. e.g.
Code: [Select]
export CC=x86_64-w64-mingw32-gcc
export CXX=x86_64-w64-mingw32-g++
export PATH="/usr/x86_64-w64-mingw32/bin:$PATH"
(2) Env vars again. If using e.g. config.mingw, then set CFG=mingw. See first line of the Makefile...

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #2 on: November 28, 2016, 02:44:18 AM »
Thank you very much for that. I am rather new to cross-compiling or indeed doing anything other than basic building with the makefile; can you assist, therefore, as to what commands that I will actually need to issue in order to set up and use these environment variables to cross-compile? I presume that the code extract above is intended to go into the path, if not already there?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #3 on: November 28, 2016, 06:12:52 AM »
(1) Why? Seems needlessly complicated. Normally just override the defaults with environment vars and stick your cross toolchain in the path before invoking make. e.g.
Code: [Select]
export CC=x86_64-w64-mingw32-gcc
export CXX=x86_64-w64-mingw32-g++
export PATH="/usr/x86_64-w64-mingw32/bin:$PATH"
(2) Env vars again. If using e.g. config.mingw, then set CFG=mingw. See first line of the Makefile...

In my experience, modifying PATH is not necessary. And I set CC and CXX in config.mingw (or whatever I call the relevant config.template copy). Then it's just a matter of CFG=mingw make to build Simutrans. Things may be different with the "new" autoconf(-like) set-up.

One also need to set up the dependencies (bzip and zlib if memory serves me right, optionally SDL) for cross-compilation. I don't remember how I did that, and it may be distro specific.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #4 on: November 28, 2016, 12:31:47 PM »
I did try simply setting the OS to mingw and running make, but that did not work.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #5 on: November 28, 2016, 04:53:10 PM »
I did try simply setting the OS to mingw and running make, but that did not work.

If you are referring to OSTYPE, neither of us claimed that would be enough. (In fact, none of us even mentioned it, perhaps because we found it to be an obvious thing.) Otherwise, I have no idea what you mean by "setting the OS to mingw".

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #6 on: November 29, 2016, 09:13:55 PM »
Apologies for being unclear previously: I was using a smartphone on a train; yes, I did just change the OSTYPE to mingw (after having installed the cross-compiler). It failed with an error to the effect that it did not recognise "mingw" or something of the sort (I cannot recall the exact words now; I can check if this is important). What is not clear to me is how to instruct make to invoke, not the normal Linux G++, but the MinGW version, as I believe that, when I attempted to change it just by modifying the OSTYPE string, it did not do this.

You refer to a config.mingw file: do I understand this to be a file similar to config.default that provides the settings for a mingw build, whereas config.default provides the settings for the default Linux build? For some reason that I cannot fathom, I am having enormous difficulty in finding documentation on how to use make in this way. Do you happen to know of any?

Likewise, when you refer to "set[ting] CC and CXX in config.mingw", can you elaborate on what you mean by that? All the settings in config.default that I can identify are BACKEND, OSTYPE, DEBUG, OPTIMISE, PROFILE, VERBOSE, WITH_REVISION, MULTI_THREAD, WIN32_CONSOLE, BUILDDIR, MAKEOBJ_PROGDIR, NETTOOL_PROGDIR, PROGDIR and FLAGS. Are there other things that can be set, or do I need to set a specific flag?

Apologies for the somewhat basic level of these questions, but I am afraid that I have never cross-compiled before. Thank you very much for your help so far.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 8685
  • Total likes: 294
  • Helpful: 228
  • Languages: De,EN,JP
Re: Cross-compiling: Linux to Windows
« Reply #7 on: November 29, 2016, 09:23:36 PM »
you can write something like

CC=x86_64-w64-mingw32-gcc
CXX=x86_64-w64-mingw32-g++

into your config.default

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #8 on: November 30, 2016, 12:10:48 AM »
Thank you for that. How would I tell makeobj to use a config.mingw instead of config.default, or is the only way of doing this by renaming the files?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Vladki

Re: Cross-compiling: Linux to Windows
« Reply #9 on: November 30, 2016, 12:18:02 AM »
env CFG=whatever make

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #10 on: November 30, 2016, 12:30:47 AM »
That is very helpful, thank you.

Edit: I have made progress, but I am still having great difficulty. For the main executable, I am getting a compile error when trying to compile the line:

Code: [Select]
pthread_cleanup_pop(1);

The error given is:

Code: [Select]
error: second operand to the conditional operator is of type âvoidâ, but the third operand is neither a throw-expression nor of type âvoidâ
  pthread_cleanup_pop(1);

I do not understand why this line of code is generating an error, as pthread_cleanup_pop is a standard part of the pthreads library.

I can compile nettool without error (although I have not tried to run it), but when compiling makeobj, I get a linker error:

Code: [Select]
/usr/bin/i686-w64-mingw32-ld: cannot find -lz

This is despite me having zlib-devel installed:

Code: [Select]

root@438242:/usr/share/games/nightly/simutrans-experimental/makeobj# locate libz
/lib/x86_64-linux-gnu/libz.so.1
/lib/x86_64-linux-gnu/libz.so.1.2.8
/usr/lib/x86_64-linux-gnu/libz.a
/usr/lib/x86_64-linux-gnu/libz.so
/usr/lib32/libz.so.1
/usr/lib32/libz.so.1.2.8
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzfs
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzfs_core
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzpool
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzfs/Makefile.in
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzfs_core/Makefile.in
/usr/src/linux-headers-4.4.0-45/zfs/lib/libzpool/Makefile.in
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzfs
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzfs_core
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzpool
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzfs/Makefile.in
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzfs_core/Makefile.in
/usr/src/linux-headers-4.4.0-47/zfs/lib/libzpool/Makefile.in
/usr/x86_64-w64-mingw32/lib/libzoneoc.a

My config.mingw file so far looks like this:

Code: [Select]
#BACKEND = allegro
#BACKEND = gdi
#BACKEND = opengl
BACKEND = sdl
#BACKEND = sdl2
#BACKEND = mixer_sdl
#BACKEND = posix

#COLOUR_DEPTH = 0
COLOUR_DEPTH = 16

#OSTYPE = amiga
#OSTYPE = beos
#OSTYPE = cygwin
#OSTYPE = freebsd
#OSTYPE = haiku
#OSTYPE = linux
OSTYPE = mingw
#OSTYPE = mac

#DEBUG = 3    # Level 1-3, higher number means more debug-friendly, see Makefile
OPTIMISE = 1 # Add umpteen optimisation flags
#PROFILE = 1  # Enable profiling
#PROFILE = 2  # Enable profiling with optimisation flags, can be used with `OPTIMISE = 1'

#WITH_REVISION = 1 # adds the revision from svn; required for networkgames
# if you do not use SVN, add -DREVISION="1234" to the FLAGS below

#WIN32_CONSOLE = 1 # adds a console for windows debugging

MULTI_THREAD = 1 # Enable multithreading

# Define these as empty strings, if you don't have the respective config program
#ALLEGRO_CONFIG = allegro-config
#PNG_CONFIG     = pkg-config libpng
SDL_CONFIG     = sdl-config
#SDL2_CONFIG    = sdl2-config

#VERBOSE = 1

# The following useful conditional compilation flags exist
#
# Needed to compile:
# USE_C: no assembler for copying (required for not using GCC on x86)
# SIM_BIG_ENDIAN: MUST be set for PPC/Motorola byte order! (old mac, amiga)
# NO_INTPTR_T: must be set if intptr_t is not available
#
# Changing appearance:
# USE_SOFTPOINTER: emulate mouse pointer (set automatically in Makefile)
#
# Useful for debugging:
# DEBUG_ROUTES: show routing calculation information in minimap
# SHOW_FORE_GRUND: show which objects are drawn as foreground
# DEBUG_FLUSH_BUFFER: show the dirty areas on the screen
# USE_VALGRIND_MEMCHECK: make valgrind-memcheck aware of the memory allocation stuff in dataobj/freelist
# SYSLOG: send debug output to syslog
#
# Following flags alter game engine (and are off for standard builds)
# OTTD_LIKE: Enables half height tiles and crossconnects all industries
# AUTOMATIC_BRIDGES and AUTOMATIC_TUNNELS: will be built also for player
# AUTOJOIN_PUBLIC: stations next to a public stop will be joined to it
# USE_DIFFERENT_WIND: different airplane approach directions over the map
# DESTINATION_CITYCARS: Citycars can have a destination (enabled automatically - cannot be disabled)
#
# In order to use the flags, add a line like this: (-Dxxx)
# FLAGS = -DUSE_C

# Output directories:
#
# use this put objects file in same directory, where the sources are (not recommended):
# ... otherwise defaults to 'build/default')
#
# BUILDDIR = $(shell pwd)
#
# use this to specifiy the target directory for the executable:
# .. otherwise defaults to BUILDDIR
#
# MAKEOBJ_PROGDIR = $(shell pwd)
# NETTOOL_PROGDIR = $(shell pwd)
# PROGDIR  = $(shell pwd)

FLAGS = -fno-delete-null-pointer-checks -fno-strict-aliasing -std=c++11 -march=i686 -I/usr/share/games/nightly/simutrans-experimental/utils/openttd/ -I/usr/share/games/simutrans-experimental
# -I/usr/local/include -I/usr/include

LDFLAGE='-L/usr/lib32 -R/usr/lib32'

CC=i686-w64-mingw32-gcc
CXX=i686-w64-mingw32-g++

Any assistance with these issues would be much appreciated. Thank you all very much for your help so far.
« Last Edit: November 30, 2016, 01:39:18 AM by jamespetts »
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #11 on: November 30, 2016, 06:51:24 AM »
Code: [Select]
/usr/bin/i686-w64-mingw32-ld: cannot find -lz

This is despite me having zlib-devel installed:

I must have terrible communication skills. As I have already written: You must also have the dependencies for cross-compilation. Having zlib installed for Linux does not do any good when you are compiling for Windows. How this is done depends on what kind of Linux system you have, which you have not stated as far as I can see. (Well, I guess there is a generic solution, but bypassing the package manager makes it a pain to uninstall it later.)

Offline Vladki

Re: Cross-compiling: Linux to Windows
« Reply #12 on: November 30, 2016, 07:49:58 AM »
And perhaps doing make clean before compiling with different config should be done

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #13 on: November 30, 2016, 12:45:30 PM »
Thank you both for your replies, and apologies if I had not understood correctly earlier. I had searched extensively for solutions to the issue online specifically including the "mingw" keyword, and all of them referred to having zlib installed in the usual way.

To answer your question, the server runs Ubuntu 16.04 (presumably in a VM). Are the correct libraries to be found in the OpenTTD files?

I have already tried make clean, which has not helped (I think that this is automatic when switching configurations in any event).

Does anyone have any idea about the pthreads issue?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #14 on: November 30, 2016, 04:14:03 PM »
For my x86_64-w64-mingw32 (on Windows, in case that matters), pthread_cleanup_pop is defined as

Code: (pthread.h) [Select]
#define pthread_cleanup_pop(E)\
    (*pthread_getclean() = _pthread_cup.next, ((E) ? (_pthread_cup.func((pthread_once_t *)_pthread_cup.arg)) : (void)0));}

That third argument is as void as it gets. Maybe this is broken in some other version. Or it's dragging in pthread for the wrong environment.

By the way, x86_64-w64-mingw32 means you are compiling 64-bit Windows executables. If you have both toolchains installed, and you want to target 32-bit Windows users as well, you must swap this out with i686-w64-mingw32.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #15 on: November 30, 2016, 09:37:07 PM »
Thank you for your reply. I am looking into the pthread issue, and I have noticed another include file error that may be causing that, which I am investigating.

In the meantime, I still cannot fathom what specific file that I need in the directory to which I point with the -L flag in config.mingw. I have pointed it to a directory containing zlibstat.lib and zdll.lib, and still get the same error. Those files (and all the others in that directory) come from the win32 subdirectory of the OpenTTD downloaded files.

As to 64 vs. 32 bit executables, I have modified the settings thus in config.mingw:

Code: [Select]

CC=i686-w64-mingw32-gcc
CXX=i686-w64-mingw32-g++

so as to get a 32-bit output.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 8685
  • Total likes: 294
  • Helpful: 228
  • Languages: De,EN,JP
Re: Cross-compiling: Linux to Windows
« Reply #16 on: November 30, 2016, 09:54:18 PM »
I think you may need also 64 bit libraries for the linking. So you need the same lib files as for your MSVC compiling. Look into the folder with the compiler. Close to it there should be also a lib and include folder. Specify these with -L and -I under LDFLAGS and CCFLAGS should point to the correct include and library folders.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #17 on: November 30, 2016, 10:57:09 PM »
If things are done correctly, no -L or -I should be required, because the correct files will be installed in the i686-w64-mingw32/x86_64-w64-mingw32 (or just mingw32 for the original mingw32) directories under /usr. This was very easy to do on Gentoo, probably because it installs things by building them from source, so installing cross-compile libraries is just a matter of building them with the cross-compiler. However, it took me a while to figure out the magic command(s) to run. While Googling cross-compilation gives lots of results, they are mostly just repeats of each other with a mix of sub-optimal solutions. I wouldn't be surprised if there is a good solution for Ubuntu, at least for such common libraries as zlib.

Offline TurfIt

Re: Cross-compiling: Linux to Windows
« Reply #18 on: November 30, 2016, 11:10:06 PM »
Latest devel-new-2 compile fails for me with the same pthread error.
I have
Code: [Select]
#define pthread_cleanup_pop(E)\
    (*pthread_getclean() = _pthread_cup.next, (E?_pthread_cup.func((pthread_once_t *)_pthread_cup.arg):0));}
Changing this to match Ters and then it compiles.

In the meantime, I still cannot fathom what specific file that I need in the directory to which I point with the -L flag in config.mingw.
-L flag. Why? Easier to just install the libs after you build them into the same prefix as you built the cross compiler with...
Just look at the output from gcc -v  to see where it's looking as configured.
Code: [Select]
$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\msys64\mingw32\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/5.3.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../gcc-5.3.0/configure --prefix=/mingw32 --with-local-prefix=/mingw32/local --build=i686-w64-mingw32 --host=i686-w64-mingw32 --target=i686-w64-mingw32 --with-native-system-header-dir=/mingw32/i686-w64-mingw32/include --libexecdir=/mingw32/lib --with-gxx-include-dir=/mingw32/include/c++/5.3.0
...


I have pointed it to a directory containing zlibstat.lib and zdll.lib, and still get the same error. Those files (and all the others in that directory) come from the win32 subdirectory of the OpenTTD downloaded files.
eh?  .lib?  WTF sort of screwed up Unix system you running? Please don't say you're using GNU ld to link a Microsoft library...
OpenTTD? This is Simutrans forum.


Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #19 on: November 30, 2016, 11:23:25 PM »
Prissi

Since I am building for Win32, I do not think that I need 64-bit libraries, do I? I have already copied the files that I have in my Windows include and library directories to folders pointed to with -I and -L flags in the FLAGS= setting in config.mingw.

However, I am coming upon a problem of some complexity. If I do not add /usr/include manually by an -I/usr/include flag, I get the error that it cannot find iconv.h. The only copy of iconv.h is in /usr/include. However, when I include /usr/include, the version of pthread.h in there conflicts with the version that seems to be included by default with mingw in its own mingw include folder (which is included automatically without a flag), and the compiler then generates great numbers of error messages about redefinitions.

I did try copying just iconv.h from /usr/include to the Open TTD include directory, but had no success there, as I then had multiple compiler errors for things that were in turn referenced from iconv.h.

I am not sure what to do about this. Any help would be appreciated.

TurfIt

May I ask what compiler that you are using in which you are getting the pthread error? The thing that you are recommending to be changed is in a file supplied as part of the pthread module itself: it is not a Simutrans file. Is there an issue of incompatible pthreads versions, I wonder?

As to the libraries, may I ask what you mean when you refer to installing something into a prefix? gcc -v will surely give information about the Linux GCC/G++ compiler, rather than mingw? It has its own library and include directories, albeit ones that omit zlib (but have pthreads).

For reference, I get:

Code: [Select]

root@438242:/usr/share/games/nightly/simutrans-experimental/makeobj# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)

As to the libraries, it seems that I need to understand better how libraries work given your comments. Do I infer from what you wrote that, even when cross-compiling for Windows, files with a .lib extension are not suitable for use with GCC? I presume from this that there is another sort of library file that is suitable, but I am not sure what sort of library file that it might be or where to get it.

In dealing with libraries in the past, I have, for Windows, downloaded the library files (usually with a .lib extension), put them in a folder, and told Visual Studio to find libraries in that folder. For Linux, I have just installed the relevant libxxx packages with apt (e.g. "apt-get install libpng-dev"), and the system itself has taken care of the files themselves and where they go, so I have never had to deal with the details of the files before.

For cross-compiling, I am not clear on what I need. Do I need Windows libraries (given that I am building for Windows), Linux libraries (given that I am building on Linux), or some sort of special cross-compile libraries (in which case, where can I find those)?

Please forgive me if this is a silly question: I am afraid that I have never tried any sort of cross-compiling before, so this is all new to me and the available documentation seems very scant.

In relation to Open TTD, the instructions for compiling Simutrans do specify using a lot of the libraries for Open TTD (especially zlib and libpng or their Windows equivalents), at least for Windows, and downloading the set of OpenTTD libraries is an explicit instruction on the "how to compile Simutrans" stickied post. Prissi said to use the same libraries on Linux for cross-compiling as I was using in Windows, which is why I copied the contents of the Open TTD libraries/include files folder.

Thank you all very much for your help so far.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline TurfIt

Re: Cross-compiling: Linux to Windows
« Reply #20 on: December 01, 2016, 12:58:59 AM »
I'm using whatever version of MinGW-w64 comes with MSYS2 that I installed ~12 months ago. (nice if these things were versioned better....)
The pthread.h that came with appears faulty - same as the one you have. Ters has one that's better - no idea if his is newer and fixed, or older and ours got broke. If I change the macro to match Ters version, your code compiles.

With 'gcc -v', I thought obviously you would invoke your cross compiler, not native Ubuntu one. if 'i686-w64-mingw32-gcc' is it, then run that.

MSVC libraries are not compatible with GCC.  'Windows' != MSVC.

For cross-compiling, yes, you need cross-compile libraries. You need them built with the cross-compile tool chain. Most likely that means building them from source, using the cross compile, and ensuring the install into the cross tool chain directories - not the native machine ones. That appears to be possibly /usr/i686-w64-mingw32/{include/lib/etc...}, but the config printout from GCC should show you. I presume your cross came from some package manager, then maybe they have some cross libraries packaged too, but you'll most likely be building from scratch.

At no point do you want your Ubuntu include or lib dirs being used by the cross compiler. re: your iconv.h problem. If you have a dependency on libiconv, then you need it built with the cross toolchain and installed for those tools, same as all the other libraries.

I would suggest you take anything OTTD and delete it. And delete anything you've copied over from a Windows machine - like .libs. And delete anything you may have copied from Ubuntu into the MinGW paths. i.e. Probably start over.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #21 on: December 01, 2016, 06:37:37 AM »
If I do not add /usr/include manually by an -I/usr/include flag, I get the error that it cannot find iconv.h.

Get the system include directory the @#%& off your include path! Whatever your problem is, that is NOT the solution when cross-compiling!

MSVC libraries are not compatible with GCC.  'Windows' != MSVC.

For plain C, I seem to remember that .lib files can be used by GCC. They may have to specified explicitly, though. I don't think a normal -l will not find them. One can however link directly against the DLL (again, only plain C). I don't remember if -l will work in that case. (C++ uses different name mangling, which is why C++ libraries can't be shared by MSC++ and GCC.)

Offline Dwachs

  • DevTeam, Coder/patcher
  • Administrator
  • *
  • Posts: 4150
  • Total likes: 140
  • Helpful: 147
  • Languages: EN, DE, AT
Re: Cross-compiling: Linux to Windows
« Reply #22 on: December 01, 2016, 07:38:34 AM »
I use this http://mxe.cc/ for cross-compiling. It is very easy to install and configure.
Parsley, sage, rosemary, and maggikraut.

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 8685
  • Total likes: 294
  • Helpful: 228
  • Languages: De,EN,JP
Re: Cross-compiling: Linux to Windows
« Reply #23 on: December 01, 2016, 09:59:58 PM »
The also mention that Debian (and derived Ubuntu) needs

apt-get install g++-multilib libc6-dev-i386 libtool-bin

Without multilib you cannot link a 32 bit library with a 64 bit executable.

Ang mingw does fine with lib files. At least on windows, because even a DLL requires a .lib (or .a) file to link for the interface.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #24 on: December 02, 2016, 07:10:45 AM »
Without multilib you cannot link a 32 bit library with a 64 bit executable.

I thought that

  • multilib was for running 32-bit programs on 64-bit Linux, and has nothing to do with cross-compilation for Windows
  • It didn't link 32-bit libraries with 64-bit executables (nor vice versa), but provided 32-bit libraries for 32-bit applications on a 64-bit system and/or allowed 32-bit libraries to work with a 64-bit kernel

Ang mingw does fine with lib files. At least on windows, because even a DLL requires a .lib (or .a) file to link for the interface.

I seem to remember learning that it is possible to link using the DLL only in some limited cases, probably functions exported by name. The DLL should contain all information needed for that, as it's the same GetProcAddress needs. Exporting by ordinal was a thing of the previous century, and global variables are "bad" anyway.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #25 on: December 11, 2016, 10:40:11 PM »
Thank you very much for all your help, and apologies for not having replied sooner: I have been spending a great deal of time making multi-threading for passenger generation work in network mode.

Returning to where we left off, I see that there is some inconsistency in the responses as to whether I need to compile special cross-compile versions of the libraries, or whether I can use Windows .lib files.

However, before I can get to the stage of linking the code, I need to be able to compile it. The iconv.h issue is a compiling rather than a linking issue: i.e., a missing header file. Would I need to find a special cross-compile version of this header file? That would not make a great deal of sense, as this is source code. However, the iconv.h problem remains: there is no iconv.h file in the MinGW include directory, and I cannot use the iconv.h file in the Linux system include directory for the reasons given above.

Does anyone have any idea of what version of iconv.h that I might need, where I might find this version, whether it has further dependencies, and where I might find those?

Edit: I think that I have managed to find a suitable iconv.h here.

Edit 2: However, I now get a rather odd error when I try to run make:

Code: [Select]
===> LD  build/mingw/simutrans-experimental
build/mingw/simres.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
common.mk:21: recipe for target 'build/mingw/simutrans-experimental' failed
make: *** [build/mingw/simutrans-experimental] Error 1
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline TurfIt

Re: Cross-compiling: Linux to Windows
« Reply #26 on: December 11, 2016, 11:46:15 PM »
Edit: I think that I have managed to find a suitable iconv.h here.
How on earth did you end up there. Search for iconv or libiconv and first result: https://www.gnu.org/software/libiconv/
As with any other libraries you're missing, get them directly from the authors, and build/install them with the cross tools.


Edit 2: However, I now get a rather odd error when I try to run make:
Perhaps using Ubunutu ld rather than MinGW ld?  check paths...
I presume Ubunutu doesn't have a windres, but if it does, again make sure you invoke the MinGW version.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #27 on: December 12, 2016, 06:35:37 AM »
Perhaps using Ubunutu ld rather than MinGW ld?  check paths...
I presume Ubunutu doesn't have a windres, but if it does, again make sure you invoke the MinGW version.

Simutrans doesn't call ld directly, so it must be using the wrong compiler altogether in that case, or that compiler is internally inconsistent.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #28 on: December 12, 2016, 10:23:01 AM »
LD is the linker, is it not? This is called by make, surely, whenever anything is compiled? I assume that this must be the MinGW version of the linker. It would make no sense if the native Linux linker were called on a cross-compile build. How would one even go about changing which linker is used?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 8685
  • Total likes: 294
  • Helpful: 228
  • Languages: De,EN,JP
Re: Cross-compiling: Linux to Windows
« Reply #29 on: December 12, 2016, 04:14:03 PM »
Same as using CC/CXX for compiler only using LD.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #30 on: December 12, 2016, 04:14:09 PM »
LD is the linker, is it not? This is called by make, surely, whenever anything is compiled?

Yes, ld is the linker, but it is not, usually, called by make. Instead, make calls the main GCC program (gcc for C or g++ for C++), which in turn calls the preprocessor, compiler, assembler and/or linker depending on what input files it is given. Calling ld directly requires a bunch of parameters that the front-end adds for us.

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #31 on: December 13, 2016, 12:49:01 AM »
Yes, ld is the linker, but it is not, usually, called by make. Instead, make calls the main GCC program (gcc for C or g++ for C++), which in turn calls the preprocessor, compiler, assembler and/or linker depending on what input files it is given. Calling ld directly requires a bunch of parameters that the front-end adds for us.

That makes sense - but would not that mean in turn that it is very unlikely indeed that the problem is the wrong linker being called?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #32 on: December 13, 2016, 06:27:54 AM »
If you run objdump -f build/mingw/simres.o, what does it say? And what does objdump -f build/mingw/simmain.o say?

Offline jamespetts

  • Simitrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 15144
  • Total likes: 354
  • Helpful: 155
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Cross-compiling: Linux to Windows
« Reply #33 on: December 18, 2016, 09:32:54 AM »
Sorry for the delay. Output from objdump -f build/mingw/simres.o

Code: [Select]
file format pe-x86-64
architecture: i386:x86-64, flags 0x00000039:
HAS_RELOC, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x0000000000000000

Output from  objdump -f build/mingw/simmain.o

Code: [Select]

build/mingw/simmain.o:     file format pe-i386
architecture: i386, flags 0x00000039:
HAS_RELOC, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000

Does this help? Thank you very much for your assistance so far.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4547
  • Total likes: 165
  • Helpful: 106
  • Languages: EN, NO
Re: Cross-compiling: Linux to Windows
« Reply #34 on: December 18, 2016, 09:45:34 AM »
simres.o has been built for 64-bit Windows and simmain.o has been built for 32-bit Windows. So both are cross-compiled, but you have still been mixing toolchains. I guess WINDRES must be set in config.<whatever> just like CC and CXX. It should be set to <prefix>-windres where prefix will be the same as used in <prefix>-g++. I'm a bit surprised it even found a windres without this being set.