PR #22 enables cross-compiling on Linux. @spk121 has provided a patch that builds with GCC on Mingw64 though there are still a few loose ends to tie up to make it ready.
Guile main fails to build on Mingw64. #56
test-hashing.exe in test-suite/standalone fails on both 64-bit, not on MINGW32.
Error in test. Test chooses between 32-bit and 64-bit hash value via SIZEOF_UNSIGNED_LONG, instead of the sizeof our new hash type.
Not really. While changing just the test does make the test pass, the compiler warns that the constant passed to expect overflows. It needs
@@ -39,17 +39,17 @@ test_hashing ()
// Value determined by calling wide_string_hash on {0x3A0, 0x3B5,
// 0x3C1, 0x3AF} via a temporary test program.
#if SCM_SIZEOF_INTPTR_T == 8
- const unsigned long expect = 4029223418961680680;
+ const scm_t_hash expect = 4029223418961680680;
#elif SCM_SIZEOF_INTPTR_T == 4
- const unsigned long expect = 938126682;
+ const scm_t_hash expect = 938126682;
#else
-#error "unsigned long not 4 or 8 bytes (need additonal test data)"
+#error "scm_t_hash not 4 or 8 bytes (need additonal test data)"
#endif
- const unsigned long actual = scm_to_ulong (scm_symbol_hash (sym));
+ const scm_t_hash actual = scm_to_uintptr_t (scm_symbol_hash (sym));
if (actual != expect)
{
- fprintf (stderr, "fail: unexpected utf-8 symbol hash (%lu != %lu)\n",
+ fprintf (stderr, "fail: unexpected utf-8 symbol hash (%tx != %tx)\n",
actual, expect);
exit (EXIT_FAILURE);
}
and libguile/symbols.c needs
@@ -375,7 +375,7 @@ SCM_DEFINE (scm_symbol_hash, "symbol-hash", 1, 0, 0,
#define FUNC_NAME s_scm_symbol_hash
{
SCM_VALIDATE_SYMBOL (1, symbol);
- return scm_from_ulong (scm_i_symbol_hash (symbol));
+ return scm_from_uintptr_t (scm_i_symbol_hash (symbol));
}
#undef FUNC_NAME
For it to pass and be correct.
FAIL: bytevectors.test: 2.4 Operations on Integers of Arbitrary Size: uint-list->bytevector [out-of-range] (eval)
FAIL: bytevectors.test: 2.4 Operations on Integers of Arbitrary Size: uint-list->bytevector [out-of-range] (compile -O0)
FAIL: bytevectors.test: 2.4 Operations on Integers of Arbitrary Size: uint-list->bytevector [out-of-range] (compile -O2)
FAIL: bytevectors.test: Datum Syntax: negative integers
Probably needs this
static inline void
twos_complement (mpz_t value, size_t size)
{
uintptr_t bit_count;
/* We expect BIT_COUNT to fit in a uintptr_t thanks to the range
checking on SIZE performed earlier. */
bit_count = (uintptr_t) size << 3ULL;
if (SCM_LIKELY (bit_count < sizeof (uintptr_t)))
mpz_ui_sub (value, 1ULL << bit_count, value);
else
{
mpz_t max;
mpz_init (max);
mpz_ui_pow_ui (max, 2, bit_count);
mpz_sub (value, max, value);
mpz_clear (max);
}
}
Unfortunately that doesn't fix it. Edit But this does:
diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c
index 3b984c6cd..8141e4001 100644
--- a/libguile/bytevectors.c
+++ b/libguile/bytevectors.c
@@ -75,11 +75,11 @@
#define INT32_T_signed int32_t
#define INT32_T_unsigned uint32_t
#define is_signed_int8(_x) (((_x) >= -128L) && ((_x) <= 127L))
-#define is_unsigned_int8(_x) ((_x) <= 255UL)
+#define is_unsigned_int8(_x) ((_x) >= 0 && (_x) <= 255UL)
#define is_signed_int16(_x) (((_x) >= -32768L) && ((_x) <= 32767L))
-#define is_unsigned_int16(_x) ((_x) <= 65535UL)
+#define is_unsigned_int16(_x) ((_x) >= 0 && (_x) <= 65535UL)
#define is_signed_int32(_x) (((_x) >= -2147483648L) && ((_x) <= 2147483647L))
-#define is_unsigned_int32(_x) ((_x) <= 4294967295UL)
+#define is_unsigned_int32(_x) ((_x) >= 0 && (_x) <= 4294967295UL)
#define SIGNEDNESS_signed 1
#define SIGNEDNESS_unsigned 0
I think since compiling linux stuff on window is such a pain in the behind, and everyone has slightly different setups with mingw, i propose we all stick to one setup to test this stuff.
I was chatting with the Chicken Scheme devs, and they highly recommended this docker image for building chicken on windows: https://github.com/skeeto/w64devkit
Also, idk if this repo has a CI/CD thing setup already, but it would be really nice once this feature finally gets merged to have that set up with this docker image
This issue is about building on the Windows operating system with MSYS2 and MINGW64 installed on it. As I wrote in the issue description PR #22 takes care of building in a cross-compiler environment. I don't know if the Lillypond folks are using a docker image or not, but GnuCash builds for Windows on Windows/MSYS2 and since the MSYS2 folks are winding down the 32-bit support we need to get a 64-bit build working soon. I'd prefer that it's a ucrt build because that's more modern and standards compliant, but in the short term I'll settle for msvcrt if necessary.
@jralls wrote in #56 (comment):
I'd prefer that it's a ucrt build because that's more modern and standards compliant, but in the short term I'll settle for msvcrt if necessary.
UCRT has much better UTF-8 support. I don't see much value in supporting MSVCRT, since it is already legacy. There is already so little interest and manpower in maintenance of Guile on MinGW that converging on only the 64-bit UCRT build and msys and letting the others rot would be fine by me.
The arrays.test exception comes from
#4 0x00007ffc7320d5ab in scm_out_of_range (subr=0x0, bad_value=0x400000002)
at /mingw64/src/debug/guile3/guile/libguile/error.c:202
#5 0x00007ffc732a9cb2 in scm_c_vector_ref (v=0x3ddcf98, k=4294967296)
at /mingw64/src/debug/guile3/guile/libguile/vectors.c:185
#6 0x00007ffc73232b09 in scm_array_handle_ref (h=0x5fdc90, p=4294967294)
at /mingw64/src/debug/guile3/guile/libguile/array-handle.h:108
#7 0x00007ffc731f50b3 in array_compare (hx=0x5fdc90, hy=0x5fdd00, dim=2, posx=4294967294, posy=2)
at /mingw64/src/debug/guile3/guile/libguile/array-map.c:582
#8 0x00007ffc731f5246 in array_compare (hx=0x5fdc90, hy=0x5fdd00, dim=1, posx=4294967294, posy=2)
at /mingw64/src/debug/guile3/guile/libguile/array-map.c:601
#9 0x00007ffc731f5246 in array_compare (hx=0x5fdc90, hy=0x5fdd00, dim=0, posx=0, posy=0)
at /mingw64/src/debug/guile3/guile/libguile/array-map.c:601
#10 0x00007ffc731f533e in scm_array_equal_p (x=0x58fdfa0, y=0x3ddd098)
at /mingw64/src/debug/guile3/guile/libguile/array-map.c:632
and the fix is
--- a/libguile/array-map.c
+++ b/libguile/array-map.c
@@ -576,7 +576,7 @@ SCM_DEFINE (scm_array_index_map_x, "array-index-map!", 2, 0, 0,
static int
array_compare (scm_t_array_handle *hx, scm_t_array_handle *hy,
- size_t dim, unsigned long posx, unsigned long posy)
+ size_t dim, size_t posx, size_t posy)
{
if (dim == scm_array_handle_rank (hx))
return scm_is_true (scm_equal_p (scm_array_handle_ref (hx, posx),
There might be clues in the old MinGW tree for some of these bugs, but, that is a few months old and hasn't been rebased on PR #22.
@spk121 isn't that already here?
@jralls wrote in #56 (comment):
@spk121 isn't that already here?
So it is. I didn't know they carried over all that history to codeberg.
@spk121 I rebased hahnjo-mingw64 on yesterday's main, then rebased your wip-mingw-2025 on that. It still needed my scm-symbol_hash patch for standalone/hashes.test but arrays.test, bytevectors.test, and srfi-60.test pass. I've pushed the result to mingw2025 on my fork.
BTW, 8203869515 sets -std=gnu17 so we no longer need to set that in CFLAGS.
Can we merge #22 into main now? 3.0.11 is released, so we’ll have time to detect and fix problems.
@ArneBab I sure don't have any objections.
#22 is merged now, since @rlb could verify that it does not cause ABI breakage.
Would you create a PR with the additional improvements you built here to get cross-compilation to work?
@ArneBab I can, but most of the changes are @spk121's so maybe better for him to make the PR.
Perhaps it should wait for @hahnjo's followup PR as well?
Sounds like a good way forward, yes.
Oh, hey, I was mentioned. I'll update my patch set.
OK pull request #81 will get this to build natively on MinGW UCRT. I've made sure that it does not modify or override anything that happened in #22.
It is intentionally minimal. It only gets us up to compilation and execution. Many tests will fail or will get hung or not run.
I could make a larger patch that handles more issues, but, it is already a big PR. People will have to let me know what the preferred strategy is.
For those trying to follow along:
#86 will "fix" the limb type when using mini-gmp. We've been patching this in LilyPond since switching to mini-gmp and it matches what "regular" GMP is doing. I'm also submitting upstream.
#106 is another downstream patch from LilyPond that now became critical for booting Guile after #89 was merged that requires shifting and generally working with large numbers at run-time (as opposed to compile-time).
Together, this is enough to build and run basic LilyPond which means that a good base of Guile is functional.
What's next for this issue? Please put me up to date :)
@old wrote in #56 (comment):
What's next for this issue? Please put me up to date :)
I haven't really tried to build the latest main on MinGW UCRT 64-bit, but by inspection it looks promising.
Next, a high priority would be to fix some lingering JIT issues on 64-bit Windows
https://codeberg.org/guile/lightening/pulls/1
https://codeberg.org/guile/lightening/pulls/2
Then there is the issue around #68. In issue 68, MSYS informs us that %host-type triplet is not a reliable way to disambiguate how to do the DLL search with (system foreign-library) and that (uname) is a better indicator.
From there, we could say that basic function is complete. Following, it would be tackling smaller issues. Various commits from the old wip-mingw-2025 branch could be extracted as bug fixes.
OK. I just tried the native MinGW UCRT build, and it doesn't compile in main. I may have to reopen and rebase the changes from #81 after all and see what's left before we can move on to the issues in the previous message.
@spk121 wrote in #56 (comment):
OK. I just tried the native MinGW UCRT build, and it doesn't compile in main.
Thank you for checking! Please ping me when you found what’s missing so it works both for Lilypond and for native builds.
(I’ll gladly review as well as I can)
@spk121 if you can share some more details about what doesn't compile, I may be able to help / make educated guesses of what's missing.
I dunno folks. I started pulling together a draft as #140, but the change to libguile/integers.c is huge to deal with all the cases. I feel like I'm going down a wrong path. Suggestions?
Yes, I'm not convinced that all of this is necessary. Can we first take a step back and assess what is the current situation: Does Guile build or not? I'm only talking about make, not yet about the tests. If not, what is the error message, the (understood) cause and the proposed fix? As I commented on the PR, it's a mix of "obviously correct" fixes and intricate changes in integers.c that I'm not sure are needed. It is impossible to understand what is required to just get Guile building, which is the scope of this issue.
OK. We can work this one by one, if this is a preferred strategy. I can talk about it here, or I can move individual issues to a different place if this is too noisy.
If we start with C compilation errors, the first issue I run into is that stime.c doesn't compile. MinGW UCRT has its own gettimeofday which configure detects, and HAVE_GETTIMEOFDAY is defined in config.h.
But we include gnulib's "sys/time.h" which shadows struct timeval with an incompatible rpl_timeval with different sized fields.
One hacky solution is to just not use gettimeofday on MinGW since clock_gettime() exists and time() exists.
You can disable gettimeofday by various means. This hack below works. But the real fix seems to be in Gnulib or our use of it.
--- a/libguile/stime.c
+++ b/libguile/stime.c
@@ -44,6 +44,10 @@
# include <config.h>
#endif
+#ifdef __MINGW32__
+#undef HAVE_GETTIMEOFDAY
+#endif
+
#include <errno.h>
#include <stdio.h>
That fix alone will allow the guile executable to compile, but it will then segfault.
@spk121 wrote in #56 (comment):
OK. We can work this one by one, if this is a preferred strategy. I can talk about it here, or I can move individual issues to a different place if this is too noisy.
I don't know, it depends on what others think. I'm personally a big advocate of incremental development, it makes reviewing and reasoning much easier IMO. A PR doesn't have to solve all aspects of a problem, small consistent steps might be faster overall.
If we start with C compilation errors, the first issue I run into is that stime.c doesn't compile. MinGW UCRT has its own
gettimeofdaywhichconfiguredetects, andHAVE_GETTIMEOFDAYis defined inconfig.h.But we include gnulib's "sys/time.h" which shadows
struct timevalwith an incompatiblerpl_timevalwith different sized fields.One hacky solution is to just not use
gettimeofdayon MinGW sinceclock_gettime()exists andtime()exists.You can disable gettimeofday by various means. This hack below works. But the real fix seems to be in Gnulib or our use of it.
--- a/libguile/stime.c +++ b/libguile/stime.c @@ -44,6 +44,10 @@ # include <config.h> #endif +#ifdef __MINGW32__ +#undef HAVE_GETTIMEOFDAY +#endif + #include <errno.h> #include <stdio.h>
Ok interesting, how do other packages solve this? Is that a "known issue" with gnulib's "sys/time.h"?
That fix alone will allow the guile executable to compile, but it will then segfault.
Do you know if there's a "single" issue that, after solved, will make some more progress? A big difference to how we cross-compile Guile for LilyPond is of course that we're not exercising bytecode compilation with the cross-compiled guile executable. You could try if simply copying bytecode from Linux "solves" the issue...
Ok interesting, how do other packages solve this? Is that a "known issue" with gnulib's "sys/time.h"?
I've reached out to bug-gnulib for support.
That fix alone will allow the guile executable to compile, but it will then segfault.
Do you know if there's a "single" issue that, after solved, will make some more progress? A big difference to how we cross-compile Guile for LilyPond is of course that we're not exercising bytecode compilation with the cross-compiled
guileexecutable. You could try if simply copying bytecode from Linux "solves" the issue...
I have bytecode I generated from the #140 patch. Using that on a MinGW Guile built from main the only the stime hack and the segfault-on-boot fix hack, it will run well enough to execute ./check-guile. It will even compile simple code.
PR #141 fixes the compile error in stime.c for MinGW.
@spk121 wrote in #56 (comment):
PR #141 fixes the compile error in stime.c for MinGW.
In the discussion closing PR #141, it was suggested that instead of working around the stime.c compile bug on MinGW, I instead investigate what it would take to update our gnulib files. So #141 has been repurposed to update gnulib to the current stable branch. If we decide that we want to upgrade gnulib like #141, it will fix the stime.c compile bug as a side effect.
Just want y'all to know that getting a native MinGW 64-bit build using the UCRT C library instead of the deprecated MSVCRT C library is still top of mind for me. If we're taking it one step at a time, the compilation error in stime.c is first. In PR #141 there is one way forward on that. We just need to either accept the strategy in 141 or I can go back to the small hack around the stime.c compilation error originally proposed at the top of 141.
Once we get past that, guile will build and will be capable of running somewhat using *.go files built by another host, but, it won't be able to compile stage0 eval.scm on its own until we fix a couple of numerical overflows. It will fail with
In ../module/ice-9/eval.scm:
619:8 19 (_ #(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#<directory (language tree-il compile-bytecode) 288428e4c80> #<<asm> buf: #u32(1 0 26214669 6189 62 6268 265983 131 127 6228 0 268196 5691 0 50599332 267428 50593956 276 2097218 335544392 16842824 276 2097218 352321608 16842824 276 2097218 369098824 16842824 276 2097218 385876040 16842824 5908 24123428 45 62 340 0 16777268 111 16782663 39 1027 256 4194568 6656 45 62 340 0 16777268 4�> �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �))
I am still confused about what needs to be done/merge for making Windows work. I see couple of issues and open PRs, but I don't know which one are to prioritize and in what order.
If a list of PRs, sorted by order of priority can be made here, that would greatly me.
- To get to compile in C in a MinGW native environment: #141
- Then to correct problems that cause it to fail to build stage0: a cleaned-up, minimal subset of #140
I can break that one up into individual PRs to make it easier to review when the time comes.
And we've already worked five of the commits currently in #140 in separate issues, directly or indirectly - Then to correct problems that may cause JIT instability
guile/lightening#1
guile/lightening#2
That should be it for this specific issue.
Here's the latest.
-
libguile.so- stime.c compilation error: #141. This is the PR that discusses whether we want to update our Gnulib. All comments received so far have been addressed.
- x86-cpu.c compilation error for 32-bit MinGW when using
-Wimplicit-function-declarationis addressed in guile/lightening#1
-
stage0 compilation
-
lightening
- guile/lightening#1 fixes missing declaration for
ffsin Win32 build - guile/lightening#2 fixes bug in Win64 JIT register dependency resolution in JIT calls
- guile/lightening#1 fixes missing declaration for
No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?