guile/guile
22
141
Fork
You've already forked guile
45

Guile main fails to build on Mingw64. #56

Open
opened 2025年11月18日 22:02:07 +01:00 by jralls · 34 comments

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.

[PR #22](https://codeberg.org/guile/guile/pulls/22) enables cross-compiling on Linux. @spk121 [has provided](https://codeberg.org/guile/guile/pulls/22#issuecomment-8309930) [a patch](https://codeberg.org/attachments/1d62117c-b0b1-48f3-99e6-ce72410a8564) that builds with GCC on Mingw64 though there are still a few [loose ends](https://codeberg.org/guile/guile/pulls/22#issuecomment-8338239) to tie up to make it ready.
Author
Copy link

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.

>>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.
Author
Copy link

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
>>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

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
Author
Copy link

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.

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](https://codeberg.org/guile/guile/pulls/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.
Contributor
Copy link

@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.

@jralls wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-8342733: > 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.
Author
Copy link

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),
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), ```
Contributor
Copy link

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.

savannah guile wip-mingw-2025 tree

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. [savannah guile wip-mingw-2025 tree](https://cgit.git.savannah.gnu.org/cgit/guile.git/log/?h=wip-mingw-2025)
Author
Copy link

@spk121 isn't that already here?

@spk121 isn't that [already here](https://codeberg.org/guile/guile/src/branch/wip-mingw-2025)?
Contributor
Copy link

@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.

@jralls wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-8399178: > @spk121 isn't that [already here](https://codeberg.org/guile/guile/src/branch/wip-mingw-2025)? So it is. I didn't know they carried over all that history to codeberg.
Author
Copy link

@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.

@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](https://codeberg.org/jralls/guile/commits/branch/mingw2025). BTW, https://codeberg.org/guile/guile/commit/82038695153628efa29f958f188260820e10e1b4 sets `-std=gnu17` so we no longer need to set that in CFLAGS.
Collaborator
Copy link

Can we merge #22 into main now? 3.0.11 is released, so we’ll have time to detect and fix problems.

Can we merge https://codeberg.org/guile/guile/pulls/22 into main now? 3.0.11 is released, so we’ll have time to detect and fix problems.
Author
Copy link

@ArneBab I sure don't have any objections.

@ArneBab I sure don't have any objections.
Collaborator
Copy link

#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?

https://codeberg.org/guile/guile/pulls/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?
Author
Copy link

@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?

@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?
Collaborator
Copy link

Sounds like a good way forward, yes.

Sounds like a good way forward, yes.
Contributor
Copy link

Oh, hey, I was mentioned. I'll update my patch set.

Oh, hey, I was mentioned. I'll update my patch set.
Contributor
Copy link

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.

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.
Contributor
Copy link

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.

For those trying to follow along: https://codeberg.org/guile/guile/pulls/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. https://codeberg.org/guile/guile/pulls/106 is another downstream patch from LilyPond that now became critical for booting Guile after https://codeberg.org/guile/guile/pulls/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.
Collaborator
Copy link

What's next for this issue? Please put me up to date :)

What's next for this issue? Please put me up to date :)
Contributor
Copy link

@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.

@old wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-11835981: > 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/1) [https://codeberg.org/guile/lightening/pulls/2](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](https://codeberg.org/guile/guile/commits/branch/wip-mingw-2025) could be extracted as bug fixes.
Contributor
Copy link

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.

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.
Collaborator
Copy link

@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 wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-11869479: > 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)
Contributor
Copy link

@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.

@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.
Contributor
Copy link

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?

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?
Contributor
Copy link

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.

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.
Contributor
Copy link

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.

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.
Contributor
Copy link

@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 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>

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...

@spk121 wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-11932548: > 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 `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. > > ```text > --- 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...
Contributor
Copy link

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 guile executable. 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.

> 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 `guile` executable. 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.
Contributor
Copy link

PR #141 fixes the compile error in stime.c for MinGW.

PR #141 fixes the compile error in stime.c for MinGW.
Contributor
Copy link

@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.

@spk121 wrote in https://codeberg.org/guile/guile/issues/56#issuecomment-11954472: > 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.
Contributor
Copy link

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�> �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �))
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�> �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �) �)) ```
Collaborator
Copy link

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.

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.
Contributor
Copy link
  • 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.

- 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 https://codeberg.org/guile/lightening/pulls/1 https://codeberg.org/guile/lightening/pulls/2 That should be it for this specific issue.
Contributor
Copy link

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-declaration is addressed in guile/lightening#1
  • stage0 compilation

    • #140 We've been breaking this PR into small PRs. So this is obsolete but still there for reference.
    • #174 fixes a macro and is ready to go
    • #178 is improvement to scm to int32 conversion. I think this is also ready to go.
    • more PR extracted from #140 to follow
  • lightening

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-declaration` is addressed in guile/lightening#1 - stage0 compilation - #140 We've been breaking this PR into small PRs. So this is obsolete but still there for reference. - #174 fixes a macro and is ready to go - #178 is improvement to scm to int32 conversion. I think this is also ready to go. - more PR extracted from #140 to follow - lightening - guile/lightening#1 fixes missing declaration for `ffs` in Win32 build - guile/lightening#2 fixes bug in Win64 JIT register dependency resolution in JIT calls
Sign in to join this conversation.
No Branch/Tag specified
main
wip-whippet
wip-mingw-2025
wip-elisp-rebased
wip-exception-truncate
wip-3.2
wip-tailify
wip-load-lang
wip-lightening-riscv
wip-cuirass-ci
wip-mingw
wip-modernize-autotools
wip-tree-il-sourcev
compile-to-js-merge
wip-inlinable-exports
branch_release-1-8
mingw-guile-3.0
use-minigmp
excise-ltdl
stable-2.2-wip-exception-truncate
wip-vector-cleanup
wip-replace-ltdl-with-gmodule
stable-2.2
wip-new-tagging-bis-broken
wip-new-tagging
lightening
lightning
wip-mingw-guile-2.2
stable-2.0
wip-lloda
wip-cygwin-guile-2.2
wip-itimer-checks
lloda-squash1
lloda-squash0
lloda-array-support
wip-ethreads
wip-elisp
wip-stime
wip-streams
r7rs-wip
lloda-array-cleanup
cky-hygienic-macros
lua
wip-retagging
ttn-back-in-the-saddle
wip-raeburn-misc
wip-threaded-http-server
wip-finalizers
wip-threads-and-fork
wip-compiler
nan-boxing
wip-bpt-elisp
historical/wip-1-8-mingw-build
wip-sassy
wip-nj-locks-nc
wip-nj-thread-safety
branch_release-1-6
branch_release-1-4
v3.0.11
v3.0.10
v3.0.9
v3.0.9rc1
v3.0.8
v3.0.7
v3.0.6
v3.0.5
v3.0.4
v3.0.3
v3.0.2
v3.0.1
v2.2.7
v3.0.0
v2.9.9
v2.9.8
v2.9.7
v2.9.6
v2.9.5
v2.9.4
v2.9.3
v2.2.6
v2.2.5
v2.9.2
v2.9.1
v2.9.0
v2.3.0
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.8
v2.1.7
v2.0.14
v2.1.6
v2.1.5
v2.0.13
v2.1.4
v2.0.12
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.11
v2.0.10
v2.0.9
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
release_1-9-15
release_1-9-14
release_1-8-8
release_1-9-13
release_1-9-12
release_1-9-11
release_1-9-10
branch-notes/wip-1-8-mingw-build
release_1-9-9
release_1-9-8
release_1-9-7
release_1-9-6
release_1-9-5
release_1-9-4
release_1-9-3
release_1-9-2
release_1-9-1
release_1-8-7
release_1-9-0
release_1-8-6
release_1-8-5
release_1-8-4
release_1-8-3
release_1-8-2
branch_release-1-8_last-merged-to-head
release_1-8-1
release_1-6-8
release_1-6-8-rc1
release_1-8-0
branch-root_release-1-8
release_1-6-8-rc0
release_1-7-2
branch-root_mvo-thread-cleanup
release_1-6-7
release_1-6-6
mvo-post-libguile_ltdl_removal
mvo-pre-libguile_ltdl_removal
release_1-6-5
release_1-7-1
before-merge_mvo-substrings
branch-root_mvo-substrings
release_1-6-4
rlb-post-gmp
rlb-pre-gmp
release_1-6-3
release_1-6-2
release_1-6-1
rlb-post-libguile-ltdl
rlb-pre-libguile-ltdl
release_1-6-0
release_1-5-8
release_1-5-7
after-hanwen-gc-change
before-hanwen-gc-change
release_1-4-1
release_1-5-6
release_1-5-5
ossau-elisp-root
release_1-5-4
release_1-5-3
release_1-5-2
branch-root_release-1-6
mvo-root-of-vcell-cleanup-1
cmm-post-tags
cmm-post-cards
cmm-pre-cards
mdj_post_struct_free_fix
mdj_pre_struct_free_fix
release_1_4
mdj_post_doublecell
mdj_pre_doublecell
gjb_post_voidp_patch
gjb_pre_voidp_patch
mdj-post-ansi-string
mdj-pre-ansi-string
release_1_3_4
jimb_mb_branchpoint_1
mdj_post_subr_table
mdj_pre_subr_table
release_1_3_2
merged_from_trunk_to_elisp
merged_from_goops_to_trunk
trunk
merged_from_trunk_to_goops
release_1_3
mvo_pre_local_defines_fix
release_1_2_90
jimb_post_port_passthrough
jimb_pre_port_passthrough
jimb_pre_maciej_warning_patch
tromey_post_mb_removal
tromey_pre_mb_removal
release_1_2
post_marcus_gnu_win32
pre_marcus_gnu_win32
release_1_1
pre_core
jimb_post_threads_merge
jimb_post_gh_merge
jimb_pre_gh_merge
jimb_automake1_1n_works
jimb_pre_merge_threads
rep_to_cyclic
release_1_0
pre_jimb_debug
tromey_post_automake
tromey_pre_automake
post_vollmer_snarf
pre_vollmer_snarf
post_vollmer_scm_p
pre_vollmer_scm_p
mdj_pre_scm_cleanup
mdj_pre_circref
jimb_pre_header
snap_960725
Labels
Clear labels
Compat/Breaking
Breaking change that won't be backward compatible
Contribution Welcomed
A PR is most welcome to help
Discussion
More of a discussion than an issue
Good First Issue
An issue that is good for new contributors
Help Wanted
Help is needed from someone
Kind/Bug
Something is not working
Kind/Documentation
Documentation changes
Kind/Enhancement
Improve existing functionality
Kind/Feature
New functionality
Kind/Security
This is security issue
Kind/Testing
Issue or pull request related to testing
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
Reviewed
Confirmed
Issue has been confirmed
Reviewed
Duplicate
This issue or pull request already exists
Reviewed
Invalid
Invalid issue
Reviewed
Won't Fix
This issue won't be fixed
Status
Abandoned
Somebody has started to work on this but abandoned work
Status
Blocked
Something is blocking this issue or pull request
Status
Need More Info
Feedback is required to reproduce issue or to continue work
Windows
🪟 related.
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
6 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
guile/guile#56
Reference in a new issue
guile/guile
No description provided.
Delete branch "%!s()"

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?