Problem.
I've needed to build glib (actually finally I want to get libxml++, and glib is one of dependencies). Will do it static library with static runtime (/MT and /MTd) x64. Firstly I wanted to build only part of glib, but finally I built whole library successfully.
Tools and versions (my case):
- Visual Studio 2013
- Python (I have python 2.7)
- Perl (I have ActivePerl x64)
- git client
- x32 cygwin
- far manager
- notepad++
- Compiled intl (version 20090911) in Visual Studio 2013 - [link]
- Compiled pcre (version 8.37) in Visual Studio 2013 - [link]
- Compiled libffi (version 3.2.1) in Visual Studio 2013 - [link]
- Compiled zlib (version 1.2.8) in Visual Studio 2013 - [link]
Date: (02.07.2015 14:06:17)
Commit hash: e337fe31637fe868ab94b488caf9b4898a2a1040
just last commit from git for the moment of compilation.
Action
1. git clone git://git.gnome.org/glib
2. open x32 cygwin - Cygwin.bat
3. go to dir with glib sources
4. replace all '\r' to '' in files (I did it in notepad++):
- autogen.sh
- configure.ac
- ./autogen.sh
- cd ./gio
- make
Now we don't need cygwin - can close it.
6.exec python script (I did it with python 2.7), located in 'glib/build/win32':
python setup.py --perl=C:\Perl64\bin\perl.exe
it's like ./configure. For example, it copies config.h.win32 to config.h with replacing some substrings to real value (for example - @MAJOR_VERSION@ to concrete number) - without it visual studio can't find config.h. Also here are exists './glib/win32-fixup.pl', but you don't need touch this file - I think it's deprecated.
But it's not fully-functional configure, bcs it doesn't create file 'gdbus-daemon-generated.c', and we still need to exec autogen & make before it.
7. open ./glib/build/win32/vs10/glib.sln
8. choose mode x64 (I will consider modes Debug_ExtPCRE and Release_ExtPCRE)
9. in project properties, general -> change 'dynamic library' to 'static library' for projects:
- gio
- glib
- gmodule
- gobject
- gthread
10. open 'property sheets' and delete all 'user macros' in sheet named 'glibgensrcsprops'
11. Create two property sheets - one for release x64, another for debug x64. I assume all 4 dependency libraries located in 'D:\projects\libraries\libxmlplusplus' and built by my instructions.
Release_ExtPCRE x64:
- additional include directories
- D:\projects\libraries\libxmlplusplus\intl\_build_x64_static_release_mt\include
- D:\projects\libraries\libxmlplusplus\pcre-8.37\_build_x64_static_release_mt\include
- D:\projects\libraries\libxmlplusplus\libffi-3.2.1\_build_x64_static_release_mt\include
- D:\projects\libraries\libxmlplusplus\zlib-1.2.8\_build_x64_static_release_mt\include
- additional library directories
- D:\projects\libraries\libxmlplusplus\intl\_build_x64_static_release_mt\lib
- D:\projects\libraries\libxmlplusplus\pcre-8.37\_build_x64_static_release_mt\Release
- D:\projects\libraries\libxmlplusplus\libffi-3.2.1\_build_x64_static_release_mt\.libs
- D:\projects\libraries\libxmlplusplus\zlib-1.2.8\_build_x64_static_release_mt\lib
- input
- ws2_32.lib
- winmm.lib
- libffi_convenience.lib
- Iphlpapi.lib
- Dnsapi.lib
- zlib.lib
- pcre.lib
- additional include directories
- D:\projects\libraries\libxmlplusplus\intl\_build_x64_static_debug_mtd\include
- D:\projects\libraries\libxmlplusplus\pcre-8.37\_build_x64_static_debug_mtd\include
- D:\projects\libraries\libxmlplusplus\libffi-3.2.1\_build_x64_static_debug_mtd\include
- D:\projects\libraries\libxmlplusplus\zlib-1.2.8\_build_x64_static_debug_mtd\include
- additional library directories
- D:\projects\libraries\libxmlplusplus\intl\_build_x64_static_debug_mtd\lib
- D:\projects\libraries\libxmlplusplus\pcre-8.37\_build_x64_static_debug_mtd\Debug
- D:\projects\libraries\libxmlplusplus\libffi-3.2.1\_build_x64_static_debug_mtd\.libs
- D:\projects\libraries\libxmlplusplus\zlib-1.2.8\_build_x64_static_debug_mtd\lib
- input
- ws2_32.lib
- winmm.lib
- libffi_convenience.lib
- Iphlpapi.lib
- Dnsapi.lib
- zlib.lib
- pcred.lib
12. Set static runtime (/MT and /MTd accordingly) for all projects except:
- glib-install
- gspawn-win32-helper
- gspawn-win32-helper-console
13. The goal of this step - get rid from dll export (if you don't do it - executables, which use libxml++ will have export O_o. So, you need make several replaces.
in 'glib\glib\gtypes.h':
- '# define GLIB_VAR __declspec(dllexport)' -> '# define GLIB_VAR extern'
- '# define GLIB_VAR extern __declspec(dllimport)' -> '# define GLIB_VAR extern'
- '#define _GLIB_EXTERN __declspec (dllexport) extern' -> '#define _GLIB_EXTERN extern'
- '# define GOBJECT_VAR __declspec(dllexport)' -> '# define GOBJECT_VAR extern'
- # define GOBJECT_VAR extern __declspec(dllimport)' -> '# define GOBJECT_VAR extern'
DllExportDefines Dll_EXPORT
15. And finally one dirty hack) The point is - looks like glib usually used on Windows only as dynamic library. In dynamic libraries on Windows exists function DllMain, which in glib implemented to fill some internal structure with pointers to internal functions. When you build this library as static, there are no called DllMain, this structure is not initialized (filled by zeros), and glibmm has some global object, and everything crashes into constructor of this object, because it calles some glib function, and executed 'call' by address zero.
So, the point of my dirty hack is - initialize this internal structure in the first glib function, which called from glibmm.
so, in file glib -> glib_init.c
BOOL WINAPI DllMain (HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved);
HMODULE glib_dll;
BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
glib_dll = hinstDLL;
g_clock_win32_init ();
#ifdef THREADS_WIN32
g_thread_win32_init ();
#endif
glib_init ();
break;
case DLL_THREAD_DETACH:
#ifdef THREADS_WIN32
g_thread_win32_thread_detach ();
#endif
break;
default:
/* do nothing */
;
}
return TRUE;
}
replace by
HMODULE glib_dll;
int is_glib_initialized = 0;
void
glib_init_ctor (void)
{
if (is_glib_initialized == 0)
{
glib_dll = 0;
g_clock_win32_init ();
g_thread_win32_init ();
glib_init ();
is_glib_initialized = 1;
}
}
and in glib -> gthread-win32.c
void
g_mutex_init (GMutex *mutex)
{
g_thread_impl_vtable.InitializeSRWLock (mutex);
}
replace by
extern void glib_init_ctor(void);
void
g_mutex_init (GMutex *mutex)
{
glib_init_ctor();
g_thread_impl_vtable.InitializeSRWLock (mutex);
}
16. build all
unsuccessful can be only: gspawn-win32-helper and gspawn-win32-helper-console. It's okay.
Possible errors for googling people
problem - you didn't called 'setup.py'
-----------------------------------------------
1> Copying config.h from config.h.win32...
1> The system cannot find the file specified
-----------------------------------------------
what to do - step 2 in this post
Thank you so much for posting this, you just helped me Tremendously!
ReplyDeletenice post
ReplyDeletePenyebab Penyakit Miom
Did you face errors with libiconv during autogen.sh ?
ReplyDeleteDoes anyone have the setup.py for GLib 2.45.3 ? The archive for that version no longer includes the setup.py - and thats all I am missing.
ReplyDelete