My msys build of fossil does nothing at all
(1.1) By Stephan Beal (stephan) on 2025-02-08 22:40:19 edited from 1.0 [link] [source]
i was recently pulled out of the wide-open landscape of my Unix comfort zone and into a fenced-in plot of Windows real-estate...
To that end, i just attempted to build Fossil on msys2 and cannot explain the results...
From the msys shell it configures and builds just fine, but i noticed a Windows-specific compiler warning partway through, cancelled the build, and patched it...
Using fossil.exe from the fossil home page:
$ f diff Index: src/winfile.c ================================================================== --- src/winfile.c +++ src/winfile.c @@ -505,14 +505,14 @@ fi2.FileId[1], fi2.FileId[0]); } } if( zFileId==0 ){ if( GetFileInformationByHandle(hFile,&fi) ){ - ULARGE_INTEGER FileId = { + ULARGE_INTEGER FileId = {{ /*.LowPart = */ fi.nFileIndexLow, /*.HighPart = */ fi.nFileIndexHigh - }; + }}; zFileId = mprintf( "%08x/%016llx", fi.dwVolumeSerialNumber,(u64)FileId.QuadPart); } }
After a clean rebuild, there's a fresh new fossil.exe in that directory, but...
stephan@hplite UCRT64 /c/f/f $ ./fossil.exe diff <no output> $ echo $? 127 $ ./fossil.exe status <no output> $ echo $? 127 $ ./fossil.exe version This is fossil version 2.26 [822a050d52] 2025-02-08 21:27:25 UTC
However, using fossil.exe from fossil-scm.org works just fine (as we see in the diff shown above).
That is: fossil.exe built with msys silently fails to do much of anything at all.
My first suspicion was that it cannot find the .fslckout
because on this machine it's called _FOSSIL_
, so i renamed _FOSSIL_
to .fslckout
, but the result is the same.
Reverting my patch did not fix this, either.
Is there a trick to getting a working build via msys?
Why msys? Because that's what our docs suggest:
There is limited support for building under MinGW's native Windows port of GNU Make instead by defining the USE_WINDOWS=1 variable, but it's better to build under MSYS, Cygwin, or WSL on Windows since this mode doesn't take care of cases such as the "openssl" target, which depends on sed.
Sidebar: the official binaries are built using MSVC, and that build runs fine here but then the binary won't work until i get around to installing libssl system-wide (which hasn't happened yet - baby steps!). (Edit: the msvc build works fine.)
(2) By Florian Balmer (florian.balmer) on 2025-02-09 06:11:25 in reply to 1.1 [link] [source]
I don't know MSYS2 at all. I imagine that environments like MSYS2, Cygwin, WSL and similar add a whole lot of complexity atop Windows, and that tackling problems in such layered subsystems is really tricky. So if you're really new to Windows, you definitely chose to start in the Champions League! ;-)
Are you working one some MSYS-specific issues? If no, my recommendation is to stick to MSVC on Windows. Installing Visual Studio just to get the tools, headers and libraries is a pain, I'd use a throw-away VM for a short/one-time project. (There used to be an official MSVC package providing just compiler/linker, headers and libs, something like "MSVC essentials", but I can't find the download, right now.)
Anyway, some random thoughts:
- Exit code
127
doesn't look like it's from Fossil, but from the shell (if loading the binary fails completely) or the C runtime (for example, if dynamically loading a DLL fails). - Is your generated
fossil.exe
a valid PE binary, and are all the DLLs linked at compile-time available? Trypelook
(also the-i
option) to find out. (If MSYS2 doesn't generate PE files, then you have to resort to its tools to inspect and validate the binary.) - If
fossil.exe
is actually loaded, does it search for a (missing) DLL? You can use the Sysinternals Process Monitor to log file operations, for example.- Usually, if a binary file is corrupt or a compile-time linked DLL is
missing, the Windows loader shows an error message. But MSYS may use its own
custom loader (or, "preloader"?) that just returns
127
. - The same goes for missing DLLs loaded at runtime, usually the C runtime
shows an error message -- but the MSYS2 C runtime may just halt the program
with exit code
127
, for example.
- Usually, if a binary file is corrupt or a compile-time linked DLL is
missing, the Windows loader shows an error message. But MSYS may use its own
custom loader (or, "preloader"?) that just returns
- If you inject
fossil_printf("Hello!");
as the first statement inmain()
, does that work? - If yes, you can use the debugger to step through the program.
Good luck!
(3) By Warren Young (wyoung) on 2025-02-09 08:39:03 in reply to 1.1 [link] [source]
I have dusty years-old recollections of tty incompatibilities between native EXEs and anything built on cygwin1.dll
, which includes MSYS2 if you squint. Empty output was a common symptom.
The general solution is to avoid mixing tool chains and terminal types. If you must use cmd.exe
1 or PowerShell in a native Windows Console, build with MSVC. If you prefer MSYS2/Cygwin, use their preferred terminal. Last I used Cygwin, they were shipping a fork of PuTTY with the SSH code ripped out, leaving just the GUI terminal emulator.2
Atop that, avoid mixing EXE types in any area where you need I/O interop, as in a pipeline.
The new Windows Terminal may help with some of this, but that’s speculation. It post dates my exit from the Cygwin community.
(4) By Stephan Beal (stephan) on 2025-02-09 14:24:26 in reply to 2 [link] [source]
(With my apologies in advance for confusingly mixing quotes from Florian and Warren in this same post...)
Before responding: after running the msvc-based build, including the local build of libssl, all's working well.
So if you're really new to Windows, you definitely chose to start in the Champions League!
Effectively new - haven't actively used it in 25 years. i recognize that this particular undertaking is a bit too advanced for a beginner, though, and i need to step back and learn a few things first.
Are you working one some MSYS-specific issues?
"Jein" - i am attempting to help some sqlite forum users with build-related issues on msys/cygwin/mingw (and i'm still not 100% clear where the line is drawn between those three). The project no longer officially supports non-native-Windows builds (such as those three environments), for reasons like the one that Warren mentions in his response:
I have dusty years-old recollections of tty incompatibilities between native EXEs and anything built on cygwin1.dll,
and a similar issues which people report (some of whom like to cross-compile between msys and cygwin for reasons i don't understand).
Because we only officially target MSVC builds i'm not going to put in huge amounts of effort to resolve any build issues on those environments, but would like to resolve any which don't require genuine expertise in the specifics of those environments.
Is your generated fossil.exe a valid PE binary, and are all the DLLs linked at compile-time available? ... If fossil.exe is actually loaded, does it search for a (missing) DLL?
No idea! Thank you for those hints.
The general solution is to avoid mixing tool chains and terminal types.
If i only knew what that meant in this context - they currently all blend in together in my eyes :/.
If you must use cmd.exe1 or PowerShell in a native Windows Console, build with MSVC.
As of a couple of weeks ago, that's the only officially-supported option1, and that mode works well for both sqlite and fossil but uses toolchains i'm 100% unfamiliar with, so my instinct (for better or worse) is to reach for msys because it feels more familiar on my fingers' muscle-memory. That familiarity is only skin-deep, though.
If you prefer MSYS2/Cygwin, use their preferred terminal.
"Prefer" might be too strongly-worded, but i'm attempting to become at least "minimally proficient" with msys, as it seems to be the most actively-developed of the alternative environments.
Atop that, avoid mixing EXE types in any area where you need I/O interop, as in a pipeline.
Thank you both for the helpful tips!
- ^ https://sqlite.org/forum/forumpost/b398a58ecc372f79
(5) By Warren Young (wyoung) on 2025-02-09 18:34:27 in reply to 4 [link] [source]
If i only knew what that meant in this context
My memory of the circumstances wasn't clear enough to allow me to reconstruct a repro case for you, but I did manage to get a working build.
First, be sure you have the necessary deps:
$ pacman -sS gcc make openssl openssl-devel zlib-devel
Next, apply this patch:
Index: auto.def
==================================================================
--- auto.def
+++ auto.def
@@ -244,11 +244,16 @@
test_system_sqlite
}
proc is_mingw {} {
- return [string match *mingw* [get-define host]]
+ if {[string match *mingw* [get-define host]] && \
+ ![file exists "/dev/null"]} {
+ return 1
+ } else {
+ return 0
+ }
}
if {[is_mingw]} {
define-append EXTRA_CFLAGS -DBROKEN_MINGW_CMDLINE
define-append LIBS -lkernel32 -lws2_32
(I expect someone whose Tcl-fu does not suck to be able to simplify that.)
Reconfigure and rebuild. When I do that, I get:
$ ./fossil.exe version
This is fossil version 2.26 [25672b1def] 2025-02-09 05:04:40 UTC
I also tested a clone of Fossil's self-hosting repo, then went no further.
On your say-so, I'll apply that patch and a suitable fix to the docs.
(6) By Stephan Beal (stephan) on 2025-02-09 18:42:53 in reply to 5 [link] [source]
(I expect someone whose Tcl-fu does not suck to be able to simplify that.)
As a tcl neophyte, that all looks good to me.
file exists "/dev/null"
That's an interesting detail. Indeed, my msys /dev dir has only 2 entries: mqueue and shm.
On your say-so, I'll apply that patch and a suitable fix to the docs.
By all means. You need no permission from me!
(7) By Florian Balmer (florian.balmer) on 2025-02-09 18:47:36 in reply to 3 [link] [source]
Empty output was a common symptom.
Ah, yes, something similar has already been reported.
Still wondering where the exit code 127 comes from ... it's not from the Fossil source code, so I assumed the binary was not loaded properly due to corruption or some other loader problem. But maybe it's just some CRT fatal exit.
(8) By Warren Young (wyoung) on 2025-02-09 18:59:03 in reply to 6 [link] [source]
As a tcl neophyte, that all looks good to me.
I'm irritated that I can't just say "return THING1 && THING2
" here for some reason, even though there are other C-like uses of && in auto.def
. One line blew up to 6 because I can speak only pidgin Tcl.
my msys /dev dir has only 2 entries: mqueue and shm.
Are we talking about MSYS2 here, with its mintty-based terminal, or the old original MSYS?
You need no permission from me!
I'm making it a condition of the commit that my change solves the actual problem.
(9) By Trevor (MelvaigT) on 2025-02-09 19:14:17 in reply to 7 [source]
That chimes with my dusty recollection of long-ago MSDOS adventures, and a quick google to confirm I'm not entirely making it up.
127 generally means some flavour of 'not found'. It isn't talking about fossil.exe itself though, because the shell should give you a clear message for that. Rather it is something missing during the loading process of fossile.exe. That could be a DLL, or possibly a required entry within a DLL that fossil.exe wants to bind to - i.e. there is a difference between what fossil was compiled against and what is present at run time.
As we say in Microsoft world, welcome to DLL hell :-)
Trevor
(10) By Stephan Beal (stephan) on 2025-02-09 19:27:13 in reply to 8 [link] [source]
I'm irritated that I can't just say ...
TCL has never been my strong suit, but after having spent many hours porting the sqlite build to autosetup i've come to rather like it for that type of task. i'm still getting used to when to use $foo
vs foo
, though.
Are we talking about MSYS2 here, with its mintty-based terminal, or the old original MSYS?
Msys2. msys was way before my time.
I'm making it a condition of the commit that my change solves the actual problem.
Fair enough. i have not tested that patch specifically but will do so by tomorrow afternoon at the latest and confirm whether it does or does not.
(11) By Stephan Beal (stephan) on 2025-02-09 19:29:19 in reply to 9 [link] [source]
127 generally means some flavour of 'not found'.
My suspicion, but i did not investigate it after getting the native build working, was that it was a DLL linkage problem, but the "version" command worked fine, which shouldn't have worked if the binary can't link to libwhatever. Shrug.
(12.1) By Warren Young (wyoung) on 2025-02-09 19:38:15 edited from 12.0 in reply to 10 [link] [source]
Msys2
Oh, I see the problem, then: you're using native Windows tools like dir
or Windows Explorer to list c:\msys64\dev
. This test operates within the MSYS2 environment, though, where virtual files like /dev/null
appear. They aren't file system dev nodes as on a proper POSIX system, but to everything linked to cygwin1.dll
or its MSYS2 equivalent msys-2.0.dll
, they're present.
One key thing to realize about these environments is that they're providing a Linux-like view of the world entirely in user space, but only to programs linked to that special DLL. The other is that unlike WSL, those same programs also get to see the native Windows APIs, and if you aren't careful, you can cause six kinds of havoc in six microseconds.
The point is, my patch works because:
$ ldd jimsh0.exe
…
msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
(13) By Stephan Beal (stephan) on 2025-02-10 00:30:52 in reply to 10 [link] [source]
i have not tested that patch specifically but will do so by tomorrow afternoon at the latest and confirm whether it does or does not.
Patch applied and, interestingly...
With msys2's "ucrt64" environment (the one the msys2 site recommends), it builds fine but suffers the same "silently fail with rc 127" behavior. jimsh0.exe won't build in that environment due to a missing
<sys/wait.h>
(or some such - it's scrolled out of my buffer).Using msys2's default environment - whatever their terminal app defaults to - builds and runs just fine. jimsh0.exe also builds in that setup. i won't check in your patch from there because "./fossil status" shows lots of semi-bogus EXEC/UNEXEC mods which should not get applied (even doing "./fossil revert ." does not eliminate them). It otherwise looks just fine.
Shrug.
I'm irritated that I can't just say "return THING1 && THING2" here for some reason
You can but you have to tell tcl that THING1 && THING2
is an expression:
return [expr \ [string match *mingw* [get-define host]] && \ ![file exists "/dev/null"]]
should do the trick (but is arguably less legible (in tcl)).
One key thing to realize about these environments is that ...
Thank you. That explanation certainly gives me a better understanding of the voodoo sitting being the terminal and the OS.
(14) By Florian Balmer (florian.balmer) on 2025-02-10 06:45:38 in reply to 1.1 [link] [source]
Fix for a struct initialization warning on Windows, but cannot currently test this ...
Works fine with MSVC. The test command is:
fossil test-file-environment FILE
(See the file_inode_sql_func
line in the output.)
BTW: There's two easy GCC distributions for Windows, without the Cygwin or MSYS layers:
Unfortunately, building Fossil currently fails due to autosetup not recognizing build the environment.
I maintain similar packages for MSVC, which I can generate entirely by scripting
on a VM, to keep my main system lean and mean: two zip archives (MSVC: 46 MB,
SDK: 35 MB) containing all the stuff required for Win32 development, with a
script to set up the PATH
, INCLUDE
and LIB
environment variables.
I'm always tempted to share these packages, but I don't think it's legal to repackage and redistribute MSVC and the Windows SDK, unfortunately.
(15) By Doug (doug9forester) on 2025-02-10 17:29:16 in reply to 13 [link] [source]
Stephen, The EXEC/UNEXEC problem was caused by fossil under windows. I can't figure out exactly how by looking at the code but the fix is:
fossil sql
update vfile set chnged=0 where chnged=6;
(16.1) By js on 2025-03-01 10:36:42 edited from 16.0 in reply to 1.1 [link] [source]
I've noticed the same happening for their fossil package, however, it only fails in some of their environments, but works in others. Notably, all the 32 bit environments (which they now removed I think?) worked. Can you try the other environments they still have to see if it makes a difference?