-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Basic MinGW-w64 cross-compilation support #15070
Merged
straight-shoota
merged 11 commits into
crystal-lang:master
from
HertzDevil:feature/mingw-w64
Oct 11, 2024
Merged
Basic MinGW-w64 cross-compilation support #15070
straight-shoota
merged 11 commits into
crystal-lang:master
from
HertzDevil:feature/mingw-w64
Oct 11, 2024
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HertzDevil
added
kind:feature
platform:windows
Windows support based on the MSVC toolchain
platform:x86
labels
Oct 9, 2024
This pull request has been mentioned on Crystal Forum. There might be relevant details there: |
straight-shoota
approved these changes
Oct 9, 2024
straight-shoota
pushed a commit
that referenced
this pull request
Oct 19, 2024
This is a continuation of #15070 that allows a compiler built with MinGW-w64 to itself build programs correctly. Resolves part of #6170. * Because linker flags for GCC may now be executed on a Windows environment, we use the correct form of argument quoting. We also drop `-rdynamic` since that only makes sense for ELF executables. * Targetting `x86_64-windows-gnu`, including normal compilations from such a Crystal compiler, will not copy dependent DLLs to the output directory. Crystal itself and programs built under MSYS2 will just work as long as the proper environment is used. You are on your own here, although `ldd` exists on MSYS2 so that you don't need the MSVC build tools for this. * The correct GCC compiler flag to select `wmain` over `main` as the C entry point is `-municode`. (The system entry point is presumably `_start` now.) * `legacy_stdio_definitions.obj` doesn't exist on MinGW-w64, so we disable it outside MSVC. * For build command lines that are too long on Windows, we use GCC's response file support. To build a MinGW-w64 compiler: ```cmd @Rem on the MSVC developer prompt make -fMakefile.win crystal bin\crystal build --cross-compile --target=x86_64-windows-gnu src\compiler\crystal.cr -Dwithout_interpreter ``` ```sh # on MSYS2's UCRT64 environment pacman -Sy \ mingw-w64-ucrt-x86_64-gc mingw-w64-ucrt-x86_64-pcre2 mingw-w64-ucrt-x86_64-libiconv \ mingw-w64-ucrt-x86_64-zlib mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-llvm cc crystal.obj -o crystal \ $(pkg-config bdw-gc libpcre2-8 iconv zlib openssl --libs) \ $(llvm-config --libs --system-libs --ldflags) \ -lDbgHelp -lole32 -lWS2_32 export CRYSTAL_PATH='lib;$ORIGIN\src' export CRYSTAL_LIBRARY_PATH='' ``` Now you can run or build a considerable number of files from here, such as `./crystal.exe samples/2048.cr` and `./crystal.exe spec spec/std/regex_spec.cr`. Notable omissions are OpenSSL and LLVM, as fixing their version detection macros is a bit complicated. The interpreter is not supported. Most likely, `Crystal::Loader` would have a GCC-style `.parse`, but the rest of the functionality would be identical to the MSVC `LoadLibraryExW`-based loader. ~~Also, some invocations like `./crystal.exe spec spec/std/json` will fail since the whole command line string is too long. Similar to MSVC, [GCC also handles response files starting with `@`](https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html), so this can be implemented later; a workaround is to use `--single-module`.~~ For reference, here are all the useful MSYS2 packages and their corresponding pkg-config names: | MSYS2 package name | pkg-config name | |-|-| | mingw-w64-ucrt-x86_64-gc | bdw-gc | | mingw-w64-ucrt-x86_64-pcre2 | libpcre2-8 | | mingw-w64-ucrt-x86_64-libiconv | iconv | | mingw-w64-ucrt-x86_64-gmp | gmp | | mingw-w64-ucrt-x86_64-zlib | zlib | | mingw-w64-ucrt-x86_64-libxml2 | libxml-2.0 | | mingw-w64-ucrt-x86_64-libyaml | yaml-0.1 | | mingw-w64-ucrt-x86_64-openssl | openssl | | mingw-w64-ucrt-x86_64-libffi | libffi | | mingw-w64-ucrt-x86_64-llvm | _(use llvm-config instead)_ |
HertzDevil
added
platform:windows-gnu
Windows support based on the MinGW-w64 toolchain + MSYS2
and removed
platform:windows
Windows support based on the MSVC toolchain
labels
Oct 20, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
kind:feature
platform:windows-gnu
Windows support based on the MinGW-w64 toolchain + MSYS2
platform:x86
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolves part of #6170. These series of patches allow
--cross-compile --target=x86_64-windows-gnu
to mostly work:@[ThreadLocal]
annotation and its corresponding LLVM attribute seem to break when targettingx86_64-windows-gnu
, so Win32 TLS is used instead. This is only needed forThread.current
.libgcc
, and Crystal relies on the underlying C++ ABI to raise exceptions, we use the Itanium ABI's_Unwind_*
functions, along with a thin personality function wrapper. (GCC itself does the same. See also Language-specific handler from the Windows x64 ABI docs.)--cross-compile
now prints ld-style linker flags, rather than MSVC ones. This is still incomplete and includes remnants of the MSVC toolchain like the/ENTRY
flag; they will be fixed later once we get to native compiler builds.src/lib_c/x86_64-windows-gnu
is now a symlink tosrc/lib_c/x86_64-windows-msvc
, since both toolchains are targetting the same Win32 APIs. (This is not Cygwin nor MSYS2's MSYS environment.)After building a local compiler,
bin\crystal build --cross-compile --target=x86_64-windows-gnu
will generate an object file suitable for linking under MinGW-w64. At a minimum, this object file depends on Boehm GC and libiconv, although they can be skipped using-Dgc_none
and-Dwithout_iconv
respectively. Then we could use MSYS2's UCRT64 environment to link the final executable:Stack traces do not work correctly yet. Also note that MSYS2's DLL names are different from the ones distributed with MSVC Crystal, and that cross-compilation never copies the DLL dependencies to the output directory. To make the executable run outside MSYS2, use
dumpbin /dependents
from the MSVC developer prompt to obtain the dependencies, then copy them manually from the MSYS2/ucrt64/bin
folder.