-
Notifications
You must be signed in to change notification settings - Fork 64
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
Windows build with embedded GLib #72
Comments
Good question. The state is unknown, since I haven't tested it, but I've planned for Windows support to be easily achievable.
Line 90 in 6fc7358
That particular code looks good, though, so there's likely something else going on. My Windows porting-fu is a little out of date, but a typical cause of grief is mixing DLLs from different build envs, resulting in incompatible bitfield handing, linking with the wrong runtime, etc. So I'd be wary of that. What does your build env look like - MSVC, MinGW? In particular, how is GLib built and linked? If you want to test if the issue is related to GOnce, and you're not calling into Chafa from different threads, then you should be able to replace void
chafa_init (void)
{
static int once = 0;
if (!once) { init_once (NULL); once = 1; }
} It wouldn't be a permanent solution, though. Useful links: Documentation for GOnce and advice on Windows porting from the GLib authors. |
I'm using gcc 9.3 installed via scoop. I'm building glib statically, mostly the same as the setup in this repo like we discussed a few months ago. I tried the |
Big fan of valgrind, it's great when you can use it. Not sure if it's relevant, but building with Let me know if you get stuck, I'll think about some alternatives in the meantime. |
I compared the glibconfig.h and GLib's generated config.h from the working MinGW build to the ones in your repo. They are pretty much identical, so the root cause probably lies elsewhere. Did you try with I guess one stumbling block is that we still don't have a good stack trace. Can Scoop be set up with debug symbols etc? |
Well, I installed Scoop on Win 10 and was able to build the stack dynamically there. Works ok. Building on Windows is kind of an ordeal, though. Cross compilation is much easier :-) A couple of notes so I don't forget:
This is all pretty ad-hoc and shouldn't be taken as some kind of definitive set of instructions :-) I wonder why Chafa was so particularly hard to build. Maybe my packaging autotools are too old. Anyway, another good argument for moving to meson. Static build ( The next step would be to try building your repo with the embedded glib. I think I'm getting debug symbols with line offsets etc, so it should be interesting. |
Oh hello there, it's great that you find my comment helpful, although that was more of a (failed) experiment than a proper build guide, so you really shouldn't follow that. For building autotools based project, you can either cross compile from WSL2, or use MSYS2. Either of them will provide a Unix-style development environment (or you can just port the build system to CMake, which is highly recommended ☺). I'd suggest going with MSYS2, since they have prebuilt packages for zlib, glib and freetype, which saves some time building it from scratch. Either way, the build process should be pretty much the same as with Linux. If you go the cross-compile route however, Wine is required, since meson needs to run tests on the host arch. |
For sure, MSYS2 is the easier route, but @oakes was using Scoop and getting segvs with the resulting binaries, and I don't see why it should not build with Scoop, so we're trying to get to the bottom of it. And also it's interesting to see how Autotools (don't) deal with modern marginal environments :-) The diffs you posted were very helpful in that regard, thanks a ton. |
That diff was an experiment to replace MSYS2 with BusyBox and native Windows port of various Unix tools. However it became too difficult to maintain, and the lack of other Unix tools (such as a Unix-style Perl, used by OpenSSL) ultimately scrapped it. You can still use it to build simple autotools projects, but using MSYS2 or WSL2 is the best way to go (or just port it to CMake, you'll make me happy :) Also, the SIGSEGV crash might be due to different CRT being mixed together, as you've said. Make sure to not mix toolchains! |
Some more info: |
@longnguyen2004 Didn't know about nuwen's distro. Awesome, that's a lot of options :-) @oakes Found your problem. It's crashing in thread code because on Win32, GLib needs to initialize the thread subsystem on startup. This is done from its Suggested changes based on your fork: diff --git a/build_windows.sh b/build_windows.sh
new file mode 100644
index 0000000..a6d8171
--- /dev/null
+++ b/build_windows.sh
@@ -0,0 +1,139 @@
+#!/bin/bash
+
+CC="${CC:-cc}"
+
+${CC} \
+ -Ichafa \
+ -Ichafa/internal \
+ -Ichafagen \
+ -Wno-deprecated-declarations \
+ -Wno-macro-redefined \
+ tests/example.c \
+ chafa/chafa-canvas-config.c \
+ chafa/chafa-canvas.c \
+ chafa/chafa-features.c \
+ chafa/chafa-symbol-map.c \
+ chafa/chafa-term-db.c \
+ chafa/chafa-term-info.c \
+ chafa/chafa-util.c \
+ chafa/internal/chafa-base64.c \
+ chafa/internal/chafa-batch.c \
+ chafa/internal/chafa-canvas-printer.c \
+ chafa/internal/chafa-color-hash.c \
+ chafa/internal/chafa-color-table.c \
+ chafa/internal/chafa-color.c \
+ chafa/internal/chafa-dither.c \
+ chafa/internal/chafa-indexed-image.c \
+ chafa/internal/chafa-iterm2-canvas.c \
+ chafa/internal/chafa-kitty-canvas.c \
+ chafa/internal/chafa-palette.c \
+ chafa/internal/chafa-pca.c \
+ chafa/internal/chafa-pixops.c \
+ chafa/internal/chafa-sixel-canvas.c \
+ chafa/internal/chafa-string-util.c \
+ chafa/internal/chafa-symbols.c \
+ chafa/internal/chafa-work-cell.c \
+ chafa/internal/smolscale/smolscale.c \
+ -Iglib \
+ -Iglib/glib \
+ -Iglib/glib/gnulib \
+ -Iglib/glib-windows \
+ -lm \
+ -mthreads \
+ -DGLIB_COMPILATION -DLIBDIR \
+ glib/glib/gmessages.c \
+ glib/glib/garcbox.c \
+ glib/glib/garray.c \
+ glib/glib/gasyncqueue.c \
+ glib/glib/gbacktrace.c \
+ glib/glib/gbitlock.c \
+ glib/glib/gbytes.c \
+ glib/glib/gcharset.c \
+ glib/glib/gconvert.c \
+ glib/glib/gdir.c \
+ glib/glib/genviron.c \
+ glib/glib/gerror.c \
+ glib/glib/gfileutils.c \
+ glib/glib/ggettext.c \
+ glib/glib/ghash.c \
+ glib/glib/ghostutils.c \
+ glib/glib/giochannel.c \
+ glib/glib/giowin32.c \
+ glib/glib/glib-init.c \
+ glib/glib/gwin32.c \
+ glib/glib/glist.c \
+ glib/glib/gmain.c \
+ glib/glib/gmem.c \
+ glib/glib/goption.c \
+ glib/glib/gpattern.c \
+ glib/glib/gpoll.c \
+ glib/glib/gprintf.c \
+ glib/glib/gqsort.c \
+ glib/glib/gquark.c \
+ glib/glib/gqueue.c \
+ glib/glib/grand.c \
+ glib/glib/grcbox.c \
+ glib/glib/grefcount.c \
+ glib/glib/gshell.c \
+ glib/glib/gslice.c \
+ glib/glib/gslist.c \
+ glib/glib/gspawn-win32.c \
+ glib/glib/gstdio.c \
+ glib/glib/gstrfuncs.c \
+ glib/glib/gstring.c \
+ glib/glib/gtestutils.c \
+ glib/glib/gthread-win32.c \
+ glib/glib/gthread.c \
+ glib/glib/gthreadpool.c \
+ glib/glib/gtimer.c \
+ glib/glib/gtranslit.c \
+ glib/glib/gtrashstack.c \
+ glib/glib/gunidecomp.c \
+ glib/glib/guniprop.c \
+ glib/glib/guri.c \
+ glib/glib/gutf8.c \
+ glib/glib/gutils.c \
+ glib/glib/gvariant-core.c \
+ glib/glib/gvariant-parser.c \
+ glib/glib/gvariant-serialiser.c \
+ glib/glib/gvariant.c \
+ glib/glib/gvarianttype.c \
+ glib/glib/gvarianttypeinfo.c \
+ glib/glib/gwakeup.c \
+ glib/glib/libcharset/localcharset.c \
+ glib/glib/gnulib/asnprintf.c \
+ glib/glib/gnulib/frexp.c \
+ glib/glib/gnulib/frexpl.c \
+ glib/glib/gnulib/isnand.c \
+ glib/glib/gnulib/isnanf.c \
+ glib/glib/gnulib/isnanl.c \
+ glib/glib/gnulib/printf-args.c \
+ glib/glib/gnulib/printf-frexp.c \
+ glib/glib/gnulib/printf-frexpl.c \
+ glib/glib/gnulib/printf-parse.c \
+ glib/glib/gnulib/printf.c \
+ glib/glib/gnulib/signbitd.c \
+ glib/glib/gnulib/signbitf.c \
+ glib/glib/gnulib/signbitl.c \
+ glib/glib/gnulib/vasnprintf.c \
+ glib/glib/gnulib/xsize.c \
+ -D_FILE_OFFSET_BITS=64 \
+ -D_GNU_SOURCE \
+ -mms-bitfields \
+ -Wl,--allow-shlib-undefined \
+ -Wl,--subsystem,console \
+ -lole32 \
+ -loleaut32 \
+ -luuid \
+ -lws2_32 \
+ -lkernel32 \
+ -luser32 \
+ -lgdi32 \
+ -lwinspool \
+ -lshell32 \
+ -lcomdlg32 \
+ -ladvapi32 \
+ -ggdb \
+ -fno-omit-frame-pointer \
+ -o chafawin && echo "Built chafawin"
+
diff --git a/glib/glib-windows/generated_config.h b/glib/glib-windows/generated_config.h
index 83f7bf5..7b0eb6a 100644
--- a/glib/glib-windows/generated_config.h
+++ b/glib/glib-windows/generated_config.h
@@ -19,7 +19,7 @@
#define DLL_EXPORT
-#define ENABLE_NLS 1
+#undef ENABLE_NLS
#define EXEEXT ".exe"
diff --git a/glib/glib-windows/glibconfig.h b/glib/glib-windows/glibconfig.h
index 9d2e3b0..4c32c4c 100644
--- a/glib/glib-windows/glibconfig.h
+++ b/glib/glib-windows/glibconfig.h
@@ -18,8 +18,8 @@
*/
#undef GLIB_USING_SYSTEM_PRINTF
-/* #undef GLIB_STATIC_COMPILATION */
-/* #undef GOBJECT_STATIC_COMPILATION */
+#define GLIB_STATIC_COMPILATION
+#define GOBJECT_STATIC_COMPILATION
G_BEGIN_DECLS
diff --git a/glib/glib/ggettext.c b/glib/glib/ggettext.c
index 3360e64..1500a29 100644
--- a/glib/glib/ggettext.c
+++ b/glib/glib/ggettext.c
@@ -40,7 +40,10 @@
#include <string.h>
#include <locale.h>
-#include <libintl.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+#endif
#ifdef G_OS_WIN32
diff --git a/glib/glib/glib-init.c b/glib/glib/glib-init.c
index 982906e..d491327 100644
--- a/glib/glib/glib-init.c
+++ b/glib/glib/glib-init.c
@@ -342,12 +342,34 @@ glib_init (void)
#if defined (G_OS_WIN32)
+HMODULE glib_dll;
+
+# ifdef G_HAS_CONSTRUCTORS
+
+# ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+# pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor)
+# endif
+G_DEFINE_CONSTRUCTOR(glib_init_ctor)
+
+static void
+glib_init_ctor (void)
+{
+ g_crash_handler_win32_init ();
+ g_clock_win32_init ();
+#ifdef THREADS_WIN32
+ g_thread_win32_init ();
+#endif
+ glib_init ();
+ /* must go after glib_init */
+ g_console_win32_init ();
+}
+
+# else
+
BOOL WINAPI DllMain (HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved);
-HMODULE glib_dll;
-
BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
DWORD fdwReason,
@@ -389,6 +411,8 @@ DllMain (HINSTANCE hinstDLL,
return TRUE;
}
+# endif
+
#elif defined (G_HAS_CONSTRUCTORS)
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA The important bit is in |
There's a patch for glib 2.56.x that adds constructor support on Windows https://github.com/bincrafters/conan-glib/blob/fad3e50d0eaf69221c0ef65077823aee341cee25/patches/0002-win32-Prefer-the-use-of-constructors-over-DllMain.patch, not sure if it'll apply cleanly on later versions. |
Oh great, that's basically the same thing, but done properly. Do you know if it's been proposed upstream? |
After digging around glib's GitLab, I found this PR which has been merged a while ago, so theoretically it should work, if you use a new enough glib. Also, have you tried building glib separately, but produce static instead of shared libraries? Meson can be a bit painful with cross-compilation and such, but that should be the best option, instead of specifying the source files directly. I'll have a try at it myself. |
I started doing cross-builds using MXE about a week ago and submitted this PR there. That wasn't too hard (biggest time investment was some Windows-specific code to query the console size and enable ANSI processing and Unicode). Btw, this issue is sort of a continuation of #41 and is specifically about building with an embedded GLib. Sorry if that was unclear. Avoiding the external dep is something that gets brought up now and again, and if it can be done without too much of a maintenance burden, it would be nice to have as an option. That's a considerable "if", though. |
Just checked, and MXE patches the GLib init as above. Makes you wonder how much time we'd have saved collectively if it'd been upstreamed back in 2013 :-) |
At least it has been upstreamed, so we can finally have some sleep :) |
Sweet thanks for this. I updated glib to 2.72.3 and it now works on windows (i had to remove a few functions and add an #include to get it to compile). |
Did you try to build a static version of glib? Mine builds successfully with no errors |
No I haven't tried that, I wanted to build everything with nim's build tool. |
Long time no chat :-) Is there anything left to do here? I think our status on Windows is good now - I make static win32 native releases regularly. The outstanding issues are:
|
What is the state of the project on windows? I tried building something based on example.c but i'm getting a SIGSEGV when calling
chafa_symbol_map_new
. In gdb all it tells me is:The text was updated successfully, but these errors were encountered: