-
Notifications
You must be signed in to change notification settings - Fork 605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix Windows cross-compilation on Linux using mingw-w64 #688
Conversation
A quick look at your changes looks good. I'm a little worried about your changes in 1a9b48184ece to files in the We should delete the folder at some point :) |
I'm not sure; I started the branch a while ago, but I didn't push it, partly because linking failed with the bundled SDL (I think it might only work for MSVC, I'm using a separate SDL binary now) and partly because the diff was a lot larger back then. It's possible that it broke the build when I started, but doesn't any more.
One of my ulterior motives in trying to set up a working autobuild environment for mingw is that I can try out changes like "delete |
I've benefited from some cleanup done by other people within OpenJK, and also some fixes in the mingw-w64 headers (for which I previously had a somewhat nasty workaround). |
You are right that not all of 1a9b481 is necessary now; the only parts that actually break compilation are the various inclusions of |
I've updated the branch to stop patching There are a few fixes in code paths which are only taken with |
Updated the branch again to be able to use the bundled SDL2 library rather than an external one. It turned out to be a library-order issue. The change to fix that should be harmless on MSVC (but please test!), because the MSVC linker prefers to resolve symbols in the same way gcc would, but unlike gcc it tries to cope with incorrect library order by falling back to libraries earlier in the command line: The MSVC linker is less sensitive to this issue because it will search all libraries for an unreferenced symbol. Library order still can affect which symbol gets resolved if more than one library have the symbol. |
Sure. I didn't want to change what happens on MSVC until someone could test there; but if you have now, that's fine.
If the check isn't done (on Windows), then CMAKE_SIZEOF_VOID_P is unset and so doesn't match 8, Architecture is set to x86, and we produce a jagamex86.dll that is actually 64-bit code; and the cmake variable WIN64 isn't set, although that doesn't currently seem to have any practical effect on non-MSVC other than not installing DLLs to I don't think the check can fail (as in produce no result), assuming you have a working C compiler. It compiles a simple executable that encodes the size into a string, then looks for the string in the binary (to avoid having to run it, which would fail when cross-compiling). |
MSVC doesn't object to this, but mingw gcc does. OpenAL-Soft already had this fix applied in its initial commit (kcat/openal-soft@ae5f4e9).
On gcc, the floating-point overloads of abs() are only available after including <cmath>. On MSVC it seems to be unnecessary but harmless.
On Windows, header files' case and forward- vs. backslashes don't matter, but when cross-compiling for Windows on a case-sensitive platform like Linux it does matter. This case combination works on mingw-w64.
These aren't currently compiled.
This gets set with native gcc on Linux, and presumably also with MSVC judging by its use in OpenJK, but doesn't seem to be set when cross-compiling with the mingw-w64 toolchain.
Order is significant when using traditional Unix linkers like GNU ld: libraries later in the link line can provide symbols required by libraries earlier in the link line, but the opposite is not true. When using an external SDL2, FindSDL2.cmake puts SDL2main before SDL2, because SDL2main uses symbols from SDL2. Do the same for the bundled SDL2 library. This fixes the following link errors: .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_main]+0x5): undefined reference to `SDL_SetMainReady' .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_WinMain@16]+0x14): undefined reference to `SDL_wcslen' .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_WinMain@16]+0x2f): undefined reference to `SDL_iconv_string' .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_WinMain@16]+0x63): undefined reference to `SDL_malloc' .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_ParseCommandLine]+0x36): undefined reference to `SDL_isspace' .../lib/SDL2/lib/x86/SDL2main.lib(./Release/SDL_windows_main.obj):(.text[_ParseCommandLine]+0xf5): undefined reference to `SDL_isspace' collect2: error: ld returned 1 exit status
These assume that the compiler is in $PATH, and is named like the ones in Debian/Ubuntu.
gcc/g++ link with support libraries: libgcc is a support library for executables generated by gcc/g++, and libstdc++ is the GNU implementation of Standard C++. Linking them statically means we don't need to distribute separate libgcc_s_sjlj-1.dll and libstdc++-6.dll binaries alongside OpenJK.
Looks good. Thanks smcv. |
fix Windows cross-compilation on Linux using mingw-w64
mingw-w64 is a way to compile native 32- or 64-bit Windows executables using gcc/g++, compiling on either Linux (with a cross-compiler that targets mingw-w64) or Windows. The resulting binaries do not depend on a special platform layer like Cygwin: they use the normal Win32 API, with Microsoft's
msvcrt.dll
as their C runtime.Previous versions of OpenJK needed significant changes for mingw, which is presumably why it isn't currently supported, but current git master can cross-compile under mingw on Linux with only minor modifications: the general theme is that it becomes necessary to distinguish between MSVC-only code, and Windows-only code (which were previously the same thing). These changes hopefully don't break MSVC builds, but I'd appreciate it if someone could test that.
So far, I've only tried compiling 32-bit debug and release builds on Linux. My planned next steps are: test those builds on native Windows; test on Wine; try Win64 builds.
Travis-CI has a mingw-w64 cross-compiler available, which ioquake3 uses for snapshot builds. I'm going to look into setting this up for my own OpenJK branches, and I hope to be able to provide a pull request soon if the OpenJK developers would be interested in doing the same. Unlike the buildbot, Travis-CI can be run automatically for every commit and every pull request, making it easy to detect pull requests from a Linux user that would break the Windows build, or vice versa. You could continue to use OpenJK's current buildbot infrastructure to produce the official snapshots if you prefer that (and it does have the advantage of covering OS X, which needs special setup for Travis-CI).