[glib/wip/meson: 16/53] meson: Improve MSVC and MinGW support and fix dependencies everywhere



commit ec3aefc1c362ca7f33fac98a1aea09b680aa8bb5
Author: Nirbheek Chauhan <nirbheek centricular com>
Date:   Wed Dec 21 04:07:24 2016 +0530

    meson: Improve MSVC and MinGW support and fix dependencies everywhere
    
    Disable gio tests on Windows, fix .gitignore to not ignore
    config.h.meson, and add more things to it.
    
    Rename the library file naming and versioning to match what Autotools
    outputs, e.g., libglib-2.0.so.0.5000.2 on Linux, libglib-2.0-0.dll  and
    glib-2.0-0.dll on Windows with MSVC.
    
    Several more tiny fixes, more executables built and installed, install
    pkg-config and m4 files, fix building of gobject tests.
    
    Changes to gdbus-codegen to support out-of-tree builds without
    environment variables set (which you can't in Meson). We now add the
    build directory to the Python module search path.

 .gitignore                             |   15 +-
 config.h.meson                         |   15 +-
 gio/build_mkenum.py                    |   16 +-
 gio/data-to-c.py                       |   16 +
 gio/gdbus-2.0/codegen/codegen.py       |    2 +-
 gio/gdbus-2.0/codegen/config.py.in     |    3 -
 gio/gdbus-2.0/codegen/gdbus-codegen.in |   12 +-
 gio/gdbus-2.0/codegen/meson.build      |   35 ++
 gio/inotify/meson.build                |    3 +-
 gio/kqueue/meson.build                 |    4 +-
 gio/meson.build                        |  365 +++++++--------
 gio/tests/meson.build                  |   40 +--
 gio/tests/modules/meson.build          |    6 +-
 gio/win32/meson.build                  |    4 +-
 gio/xdgmime/meson.build                |    2 +-
 glib/libcharset/meson.build            |    2 +-
 glib/meson.build                       |   95 +++-
 glib/pcre/meson.build                  |   50 ++
 glib/tests/meson.build                 |   50 +--
 gmodule/meson.build                    |   40 +-
 gobject/gmarshal-list-to-strings.py    |   21 +
 gobject/meson.build                    |   53 ++-
 gobject/tests/gobject_test_marshal.py  |   10 +-
 gobject/tests/meson.build              |   20 +-
 gthread/meson.build                    |    9 +-
 meson.build                            |  799 ++++++++++++++++++--------------
 26 files changed, 981 insertions(+), 706 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 9edb72c..886da4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,16 @@ tags
 
 # autofoo stuff here
 compile
-config.*
+config.cache
+config.guess
+config.h
+config.h.in
+config.h-new
+config.log
+config.lt
+config.rpath
+config.status*
+config.sub
 configure
 depcomp
 aclocal.m4
@@ -47,3 +56,7 @@ README
 ChangeLog
 /glib-lcov.info
 /glib-lcov/
+
+# Meson
+/meson-build/
+/subprojects/
diff --git a/config.h.meson b/config.h.meson
index eeb2dea..b8b419e 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -15,6 +15,9 @@
 /* poll doesn't work on devices */
 #mesondefine BROKEN_POLL
 
+/* Whether we're building a DLL and hence need symbols exported for a DLL */
+#mesondefine DLL_EXPORT
+
 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
    systems. This function is required for `alloca.c' support on those systems.
    */
@@ -316,9 +319,18 @@
 /* Have function pthread_attr_setstacksize */
 #mesondefine HAVE_PTHREAD_ATTR_SETSTACKSIZE
 
+/* Have function pthread_cond_timedwait_relative_np */
+#mesondefine HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
+
 /* Have function pthread_condattr_setclock */
 #mesondefine HAVE_PTHREAD_CONDATTR_SETCLOCK
 
+/* Have function pthread_setname_np without TID as argument */
+#mesondefine HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID
+
+/* Have function pthread_setname_np with TID as argument */
+#mesondefine HAVE_PTHREAD_SETNAME_NP_WITH_TID
+
 /* Define to 1 if the system has the type `ptrdiff_t'. */
 #mesondefine HAVE_PTRDIFF_T
 
@@ -511,9 +523,6 @@
 /* Define to 1 if you have the <sys/poll.h> header file. */
 #mesondefine HAVE_SYS_POLL_H
 
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-#mesondefine HAVE_SYS_PRCTL_H
-
 /* Define to 1 if you have the <sys/resource.h> header file. */
 #mesondefine HAVE_SYS_RESOURCE_H
 
diff --git a/gio/build_mkenum.py b/gio/build_mkenum.py
index c93ee32..5d40e9f 100755
--- a/gio/build_mkenum.py
+++ b/gio/build_mkenum.py
@@ -7,15 +7,17 @@
 
 import sys, os, shutil, subprocess
 
-ofilename = sys.argv[1]
-template_file_dir = sys.argv[2]
-template_file_path = template_file_dir + '/' + ofilename + '.template'
-headers = sys.argv[3:]
+perl = sys.argv[1]
+glib_mkenums = sys.argv[2]
+ofilename = sys.argv[3]
+ofile_rel = os.path.basename(ofilename)
+template_file_dir = sys.argv[4]
+template_file_path = template_file_dir + '/' + ofile_rel + '.template'
+headers = sys.argv[5:]
 
-arg_array = ['--template', template_file_path ]
+arg_array = ['--template', template_file_path]
 
-# FIXME: should use $top_builddir/gobject/glib-mkenums
-cmd = [shutil.which('perl'), shutil.which('glib-mkenums')]
+cmd = [perl, glib_mkenums]
 pc = subprocess.Popen(cmd + arg_array + headers, stdout=subprocess.PIPE)
 (stdo, _) = pc.communicate()
 if pc.returncode != 0:
diff --git a/gio/data-to-c.py b/gio/data-to-c.py
new file mode 100644
index 0000000..7a8d8a8
--- /dev/null
+++ b/gio/data-to-c.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) < 4:
+    print('Usage: {0} <filename> <variable> <output>')
+
+with open(sys.argv[1], 'rb') as f:
+    in_data = f.read().decode('utf-8', 'backslashreplace')
+b = [r'\x{:02x}'.format(ord(c)) for c in in_data]
+
+out_data = "const char {0}[] = \"".format(sys.argv[2])
+out_data += "".join(b) + "\";"
+
+with open(sys.argv[3], 'w') as f:
+    f.write(out_data)
diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py
index f9f404c..f2f4fe7 100644
--- a/gio/gdbus-2.0/codegen/codegen.py
+++ b/gio/gdbus-2.0/codegen/codegen.py
@@ -50,7 +50,7 @@ class CodeGenerator:
             self.ns_upper = ''
             self.ns_lower = ''
         self.interface_prefix = interface_prefix
-        self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', '_')
+        self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', 
'_').replace(':', '_')
 
     # ----------------------------------------------------------------------------------------------------
 
diff --git a/gio/gdbus-2.0/codegen/config.py.in b/gio/gdbus-2.0/codegen/config.py.in
index 38e0865..3d26d2d 100644
--- a/gio/gdbus-2.0/codegen/config.py.in
+++ b/gio/gdbus-2.0/codegen/config.py.in
@@ -19,7 +19,4 @@
 #
 # Author: David Zeuthen <davidz redhat com>
 
-DATADIR = "@datarootdir@"
-DATADIR = DATADIR.replace(
-    "${prefix}", "@prefix@")
 VERSION = "@VERSION@"
diff --git a/gio/gdbus-2.0/codegen/gdbus-codegen.in b/gio/gdbus-2.0/codegen/gdbus-codegen.in
index fd31a55..1814fa3 100644
--- a/gio/gdbus-2.0/codegen/gdbus-codegen.in
+++ b/gio/gdbus-2.0/codegen/gdbus-codegen.in
@@ -24,14 +24,18 @@ import os
 import sys
 
 srcdir = os.getenv('UNINSTALLED_GLIB_SRCDIR', None)
+filedir = os.path.dirname(__file__)
 
 if srcdir is not None:
     path = os.path.join(srcdir, 'gio', 'gdbus-2.0')
-elif os.name == 'nt':
-    # Makes gdbus-codegen 'relocatable' at runtime on Windows.
-    path = os.path.join(os.path.dirname(__file__), '..', 'share', 'glib-2.0')
+elif os.path.basename(filedir) == 'bin':
+    # Make the prefix containing gdbus-codegen 'relocatable' at runtime by
+    # adding /some/prefix/bin/../share/glib-2.0 to the python path
+    path = os.path.join(filedir, '..', 'share', 'glib-2.0')
 else:
-    path = os.path.join('@datadir@', 'glib-2.0')
+    # Assume that the modules we need are in the current directory and add the
+    # parent directory to the python path.
+    path = os.path.join(filedir, '..')
 
 sys.path.insert(0, os.path.abspath(path))
 from codegen import codegen_main
diff --git a/gio/gdbus-2.0/codegen/meson.build b/gio/gdbus-2.0/codegen/meson.build
new file mode 100644
index 0000000..b062cfb
--- /dev/null
+++ b/gio/gdbus-2.0/codegen/meson.build
@@ -0,0 +1,35 @@
+gdbus_codegen_files = [
+  '__init__.py',
+  'codegen.py',
+  'codegen_main.py',
+  'codegen_docbook.py',
+  'dbustypes.py',
+  'parser.py',
+  'utils.py',
+]
+
+gdbus_codegen_conf = configuration_data()
+gdbus_codegen_conf.set('VERSION', glib_version)
+gdbus_codegen_conf.set('PYTHON', python.path())
+
+# Install gdbus-codegen executable
+# FIXME: Set permissions
+gdbus_codegen = configure_file(input : 'gdbus-codegen.in',
+  output : 'gdbus-codegen',
+  install : true,
+  install_dir : 'bin', configuration : gdbus_codegen_conf)
+
+configure_file(input : 'config.py.in',
+  output : 'config.py',
+  install : true,
+  install_dir : 'share/glib-2.0/codegen', configuration : gdbus_codegen_conf)
+
+blank_conf = configuration_data()
+foreach f : gdbus_codegen_files
+  # Copy these into the builddir so that gdbus-codegen can be used uninstalled
+  # and then install it too so that it can be used after installation
+  configure_file(input : f, output : f,
+    install : true,
+    install_dir : 'share/glib-2.0/codegen',
+    configuration : blank_conf)
+endforeach
diff --git a/gio/inotify/meson.build b/gio/inotify/meson.build
index cc31656..3f00d94 100644
--- a/gio/inotify/meson.build
+++ b/gio/inotify/meson.build
@@ -9,5 +9,6 @@ inotify_sources = [
 
 inotify_lib = static_library('inotify',
   sources : inotify_sources,
-  include_directories : inc_dirs,
+  include_directories : [configinc, glibinc, gmoduleinc],
+  dependencies : [gioenumtypes_dep],
   c_args : [ '-DHAVE_CONFIG_H', '-fPIC', '-DG_DISABLE_DEPRECATED' ] + gio_c_args)
diff --git a/gio/kqueue/meson.build b/gio/kqueue/meson.build
index 7405d68..326915c 100644
--- a/gio/kqueue/meson.build
+++ b/gio/kqueue/meson.build
@@ -7,9 +7,11 @@ kqueue_sources = [
   'kqueue-utils.c',
   'kqueue-exclusions.c',
   'dep-list.c',
+  # gkqueuefilemonitor.h includes gio.h which includes this
+  gioenumtypes_h,
 ]
 
 kqueue_lib = static_library('kqueue',
   sources : kqueue_sources,
-  include_directories : inc_dirs,
+  include_directories : [configinc, glibinc, gmoduleinc],
   c_args : [ '-DHAVE_CONFIG_H', '-fPIC', '-DG_DISABLE_DEPRECATED' ] + gio_c_args)
diff --git a/gio/meson.build b/gio/meson.build
index 4b0aeea..1249cbb 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -1,24 +1,22 @@
 gio_c_args = [
   '-DG_LOG_DOMAIN="GLib-GIO"',
   '-DGIO_COMPILATION',
-  '-DGIO_MODULE_DIR="@0@/gio/modules"'.format(get_option('libdir')),
+  '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir),
 ]
 
-# FIXME: subdir('gdbus-2.0/codegen')
-
 gnetworking_h_conf = configuration_data()
 
 gnetworking_h_wspiapi_include = ''
 gnetworking_h_nameser_compat_include = ''
 
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   # <wspiapi.h> in the Windows SDK and in mingw-w64 has wrappers for
   # inline workarounds for getaddrinfo, getnameinfo and freeaddrinfo if
   # they aren't present at run-time (on Windows 2000).
   gnetworking_h_wspiapi_include = '#include <wspiapi.h>'
 endif
 
-if host_machine.system().contains('android')
+if host_system.contains('android')
   # Android does not have C_IN in public headers, we define it wherever necessary
   if not cc.compiles('''#include <sys/types.h>
                         #include <arpa/nameser.h>
@@ -38,7 +36,7 @@ endif
 
 network_libs = [ ]
 network_args = [ ]
-if host_machine.system() != 'windows'
+if host_system != 'windows'
   # res_query()
   res_query_test = '''#include <resolv.h>
                       int main (int argc, char ** argv) {
@@ -50,10 +48,10 @@ if host_machine.system() != 'windows'
                         ''' + res_query_test
   if not cc.links(res_query_test_full, name : 'res_query()')
     if cc.links(res_query_test_full, args : '-lresolv', name : 'res_query() in -lresolv')
-      network_libs += [ find_library('resolv') ]
+      network_libs += [ cc.find_library('resolv') ]
       network_args += [ '-lresolv' ]
     elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind')
-      network_libs += [ find_library('bind') ]
+      network_libs += [ cc.find_library('bind') ]
       network_args += [ '-lbind' ]
     else
       error('Could not find res_query()')
@@ -68,7 +66,7 @@ if host_machine.system() != 'windows'
                    }'''
   if not cc.links(socket_test, name : 'socket()')
     if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket')
-      network_libs += [ find_library('socket') ]
+      network_libs += [ cc.find_library('socket') ]
       network_args += [ '-lsocket' ]
     else
       error('Could not find socket()')
@@ -93,12 +91,18 @@ if host_machine.system() != 'windows'
   endif
 endif
 
+network_args_string = ''
+foreach arg : network_args
+  network_args_string += arg + ' '
+endforeach
+glib_conf.set('NETWORK_LIBS', network_args_string)
+
 gnetworking_h_conf.set('WSPIAPI_INCLUDE', gnetworking_h_wspiapi_include)
 gnetworking_h_conf.set('NAMESER_COMPAT_INCLUDE', gnetworking_h_nameser_compat_include)
 
 gnetworking_h = configure_file(input : 'gnetworking.h.in',
                                output : 'gnetworking.h',
-                               install_dir : 'include/glib-2.0/gio/',
+                               install_dir : 'include/glib-2.0/gio',
                                configuration : gnetworking_h_conf)
 
 gdbus_headers = [
@@ -156,16 +160,17 @@ gdbus_sources = [
   'gtestdbus.c',
 ]
 
-# FIXME: These are not built into the library yet
-#EXTRA_DIST += gdbusdaemon.c gdbusdaemon.h dbus-daemon.xml
-#gdbus-daemon-generated.h gdbus-daemon-generated.c: $(srcdir)/dbus-daemon.xml 
$(srcdir)/gdbus-2.0/codegen/gdbus-codegen.in
-#  $(AM_V_GEN) UNINSTALLED_GLIB_SRCDIR=$(top_srcdir) ',
-#    UNINSTALLED_GLIB_BUILDDIR=$(top_builddir) ',
-#    $(PYTHON) $(srcdir)/gdbus-2.0/codegen/gdbus-codegen.in ',
-#    --interface-prefix org. ',
-#    --generate-c-code gdbus-daemon-generated ',
-#    --c-namespace _G ',
-#    $(srcdir)/dbus-daemon.xml
+# Generate gdbus-codegen
+subdir('gdbus-2.0/codegen')
+
+# Generate gdbus-generated.{c,h}
+gdbus_daemon_generated = custom_target('gdbus-daemon-generated',
+    input : ['dbus-daemon.xml'],
+    output : ['gdbus-daemon-generated.h', 'gdbus-daemon-generated.c'],
+    command : [python, gdbus_codegen,
+               '--interface-prefix', 'org.',
+               '--generate-c-code', '@OUTDIR@/gdbus-daemon-generated',
+               '--c-namespace', '_G', '@INPUT@'])
 
 settings_headers = [
   'gsettingsbackend.h',
@@ -185,7 +190,7 @@ settings_sources = [
   'gsettings.c',
 ]
 
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   settings_sources += [ 'gregistrysettingsbackend.c' ]
 endif
 
@@ -267,37 +272,15 @@ local_sources = [
   'thumbnail-verify.c',
 ]
 
-platform_deps = [ ]
-internal_deps = [ ]
-appinfo_sources = [ ]
-
-# inotify
-if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
-  subdir('inotify')
-  internal_deps += [ inotify_lib ]
-endif
-
-# kevent
-if have_func_kqueue and have_func_kevent
-  subdir('kqueue')
-  internal_deps += [ kqueue_lib ]
-endif
+platform_deps = []
+internal_deps = []
+appinfo_sources = []
 
-if host_machine.system() == 'windows'
-  subdir('win32')
-  internal_deps += [ giowin32_lib ]
-endif
-
-# FIXME: FAM support
-#if HAVE_FAM
-#  subdir('fam')
-#endif
-
-unix_sources = [ ]
-if host_machine.system() != 'windows'
-  appinfo_sources += [ 'gdesktopappinfo.c' ]
+unix_sources = []
+if host_system != 'windows'
+  appinfo_sources += ['gdesktopappinfo.c']
   subdir('xdgmime')
-  internal_deps += [ xdgmime_lib ]
+  internal_deps += [xdgmime_lib]
   unix_sources = [
     'gfiledescriptorbased.c',
     'gunixconnection.c',
@@ -349,25 +332,24 @@ endif
 
 gdbus_daemon_sources = [
   'gdbusdaemon.c',
-  'gdbus-daemon-generated.c',
-]
-
-win32_actual_sources = gdbus_daemon_sources + [
-  'gwin32registrykey.c',
-  'gcontenttype-win32.c',
-  'gwin32mount.c',
-  'gwin32volumemonitor.c',
-  'gwin32inputstream.c',
-  'gwin32outputstream.c',
+  gdbus_daemon_generated,
 ]
 
-if host_machine.system() == 'windows'
-  appinfo_sources += [ 'gwin32appinfo.c' ]
-  platform_deps += [ find_library('shlwapi'),
-                     find_library('ws2_32'),
-                     find_library('dnsapi'),
-                     find_library('iphlpapi') ]
-  # win32_sources = $(win32_actual_sources)
+win32_sources = gdbus_daemon_sources
+if host_system == 'windows'
+  appinfo_sources += ['gwin32appinfo.c']
+  platform_deps += [cc.find_library('shlwapi'),
+                    cc.find_library('dnsapi'),
+                    cc.find_library('iphlpapi'),
+                    winsock2]
+  win32_sources += [
+    'gwin32registrykey.c',
+    'gcontenttype-win32.c',
+    'gwin32mount.c',
+    'gwin32volumemonitor.c',
+    'gwin32inputstream.c',
+    'gwin32outputstream.c',
+  ]
 
   gio_win32_include_headers = [
     'gwin32inputstream.h',
@@ -491,144 +473,37 @@ gio_sources = [
   'gvolumemonitor.c',
   'gzlibcompressor.c',
   'gzlibdecompressor.c',
-# FIXME  'gioenumtypes.c',
   'glistmodel.c',
   'gliststore.c',
 ]
 
-# FIXME
 gio_sources += appinfo_sources
 gio_sources += unix_sources
-#gio_sources += win32_sources
+gio_sources += win32_sources
 gio_sources += application_sources
 gio_sources += settings_sources
 gio_sources += gdbus_sources
 gio_sources += local_sources
 
-foo = '''
+MISSING_STUFF = '''
 if OS_WIN32_AND_DLL_COMPILATION
 gio_win32_res = gio-win32-res.o
 gio_win32_res_ldflag = -Wl,$(gio_win32_res)
 endif
 
-
-if OS_COCOA
-# This is dumb.  The ObjC source file should be properly named .m
-libgio_2_0_la_CFLAGS += -xobjective-c
-libgio_2_0_la_LDFLAGS += -Wl,-framework,Foundation -Wl,-framework,AppKit
-endif
-
-libgio_2_0_la_DEPENDENCIES = $(gio_win32_res) $(gio_def) $(platform_deps)
-
 gio-win32-res.o: gio.rc
   '$(WINDRES) gio.rc $@
 
-gioincludedir=$(includedir)/glib-2.0/gio/
-gioinclude_HEADERS =',
-  '$(gio_headers)',
-  'gioenumtypes.h
-
-# these sources (also mentioned above) are generated.
-BUILT_SOURCES +=',
-  'gconstructor_as_data.h',
-  'gioenumtypes.h',
-  'gioenumtypes.c',
-  'gdbus-daemon-generated.c',
-  'gdbus-daemon-generated.h',
-  'gnetworking.h',
-  '$(NULL)
-
-BUILT_EXTRA_DIST +=',
-  'gio.rc
-
 # This is read by gobject-introspection/misc/ and gtk-doc
 gio-public-headers.txt: Makefile
   '$(AM_V_GEN) echo $(gioinclude_HEADERS) $(giowin32include_HEADERS) $(giounixinclude_HEADERS) > $@.tmp && 
mv $@.tmp $@
 
-all-local: gio-public-headers.txt
-
-gioenumtypes.h: $(gio_headers) gioenumtypes.h.template
-  '$(AM_V_GEN) $(top_builddir)/gobject/glib-mkenums --template $(filter %.template,$^) $(filter-out 
%.template,$^) >',
-  '    gioenumtypes.h.tmp && mv gioenumtypes.h.tmp gioenumtypes.h
-
-gioenumtypes.c: $(gio_headers) gioenumtypes.c.template
-  '$(AM_V_GEN) $(top_builddir)/gobject/glib-mkenums --template $(filter %.template,$^) $(filter-out 
%.template,$^) >',
-  '    gioenumtypes.c.tmp && mv gioenumtypes.c.tmp gioenumtypes.c
-
 gio.def: libgio-2.0.la
   '$(AM_V_GEN) dumpbin.exe -exports .libs/libgio-2.0-0.dll | awk 'BEGIN { print "EXPORTS" } / +[[:digit:]]+ 
+[[:xdigit:]]+ +[[:xdigit:]]+/{ print $$4 }' > gio.def.tmp && mv gio.def.tmp gio.def
 
 gio-2.0.lib: libgio-2.0.la gio.def
   '$(AM_V_GEN) lib.exe -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgio-2.0-$(LT_CURRENT_MINUS_AGE).dll 
-def:$(builddir)/gio.def -out:$@
 
-bin_PROGRAMS = gio-querymodules glib-compile-schemas glib-compile-resources gsettings
-
-glib_compile_resources_LDADD = libgio-2.0.la',
-  '$(top_builddir)/gobject/libgobject-2.0.la',
-  '$(top_builddir)/gmodule/libgmodule-2.0.la',
-  '$(top_builddir)/glib/libglib-2.0.la',
-  '$(NULL)
-
-glib_compile_resources_SOURCES =',
-  'gvdb/gvdb-format.h',
-  'gvdb/gvdb-builder.h',
-  'gvdb/gvdb-builder.c',
-  'glib-compile-resources.c
-
-gio_querymodules_SOURCES = gio-querymodules.c
-gio_querymodules_LDADD  = libgio-2.0.la',
-  '$(top_builddir)/gobject/libgobject-2.0.la',
-  '$(top_builddir)/gmodule/libgmodule-2.0.la',
-  '$(top_builddir)/glib/libglib-2.0.la',
-  '$(NULL)
-
-gconstructor_as_data.h: $(top_srcdir)/glib/gconstructor.h data-to-c.pl
-  '$(AM_V_GEN) $(srcdir)/data-to-c.pl $(top_srcdir)/glib/gconstructor.h gconstructor_code > $@.tmp && mv 
$@.tmp $@
-
-glib_compile_schemas_LDADD = $(top_builddir)/glib/libglib-2.0.la
-glib_compile_schemas_SOURCES =',
-  'gconstructor_as_data.h',
-  'gvdb/gvdb-format.h',
-  'gvdb/gvdb-builder.h',
-  'gvdb/gvdb-builder.c',
-  'glib-compile-schemas.c
-
-gsettings_LDADD = libgio-2.0.la',
-  '$(top_builddir)/gobject/libgobject-2.0.la',
-  '$(top_builddir)/gmodule/libgmodule-2.0.la',
-  '$(top_builddir)/glib/libglib-2.0.la',
-  '$(NULL)
-gsettings_SOURCES = gsettings-tool.c
-
-schemadir = $(datadir)/glib-2.0/schemas
-dist_schema_DATA = gschema.dtd
-
-itsdir = $(datadir)/gettext/its
-dist_its_DATA = gschema.loc gschema.its
-
-# ------------------------------------------------------------------------
-# gdbus(1) tool
-
-bin_PROGRAMS += gdbus
-gdbus_SOURCES = gdbus-tool.c
-gdbus_LDADD = libgio-2.0.la',
-  '$(top_builddir)/gobject/libgobject-2.0.la',
-  '$(top_builddir)/gmodule/libgmodule-2.0.la',
-  '$(top_builddir)/glib/libglib-2.0.la',
-  '$(NULL)
-
-if OS_UNIX
-# ------------------------------------------------------------------------
-# gapplication(1) tool
-bin_PROGRAMS += gapplication
-gapplication_SOURCES = gapplication-tool.c
-gapplication_LDADD = libgio-2.0.la',
-  '$(top_builddir)/gobject/libgobject-2.0.la',
-  '$(top_builddir)/gmodule/libgmodule-2.0.la',
-  '$(top_builddir)/glib/libglib-2.0.la',
-  '$(NULL)
-endif
-
 completiondir = $(datadir)/bash-completion/completions
 completion_DATA =',
   'completion/gapplication',
@@ -745,58 +620,146 @@ gio_headers = [
   'glistmodel.h',
   'gliststore.h',
 ]
-# FIXME: 'gnetworking.h', - generated? was in nodist_gioinclude_HEADERS
+
 gio_headers += application_headers
 gio_headers += settings_headers
 gio_headers += gdbus_headers
 install_headers(gio_headers, subdir : 'glib-2.0/gio/')
 
-gio_mkenums = find_program('build_mkenum.py')
+gio_build_mkenum = find_program('build_mkenum.py')
 
 gioenumtypes_h = custom_target('gioenumtypes_h',
   output : 'gioenumtypes.h',
   input : gio_headers,
   install : true,
   install_dir : 'include/glib-2.0/gio/',
-  depends : [ ],
-  command : [ gio_mkenums, '@OUTPUT@', meson.source_root(), '@INPUT@', gnetworking_h ])
+  depends : [],
+  command : [gio_build_mkenum, perl, glib_mkenums,
+             '@OUTPUT@', meson.current_source_dir(),
+             '@INPUT@', gnetworking_h])
 
 gioenumtypes_c = custom_target('gioenumtypes_c',
   output : 'gioenumtypes.c',
   input : gio_headers,
-  depends : [ gioenumtypes_h ],
-  command : [ gio_mkenums, '@OUTPUT@', meson.source_root(), '@INPUT@', gnetworking_h, ])
+  depends : [gioenumtypes_h],
+  command : [gio_build_mkenum, perl, glib_mkenums,
+             '@OUTPUT@', meson.current_source_dir(),
+             '@INPUT@', gnetworking_h])
+
+gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h])
+
+# inotify
+if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
+  subdir('inotify')
+  internal_deps += [ inotify_lib ]
+endif
+
+# kevent
+if have_func_kqueue and have_func_kevent
+  subdir('kqueue')
+  internal_deps += [ kqueue_lib ]
+endif
+
+if host_system == 'windows'
+  subdir('win32')
+  internal_deps += [ giowin32_lib ]
+endif
 
-libgio = shared_library('gio',
+# FIXME: FAM support
+#if HAVE_FAM
+#  subdir('fam')
+#endif
+
+libgio = shared_library('gio-2.0',
   gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources,
-  version : glib_version,
-  soversion : interface_version,
+  version : library_version,
+  soversion : soversion,
   install : true,
-  include_directories : inc_dirs,
-  link_with : [ libglib, libgobject, libgmodule ] + internal_deps,
+  include_directories : [configinc, gioinc],
+  link_with : internal_deps,
   #libgio_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS)',
   #  '$(gio_win32_res_ldflag)',
-  #  '-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)',
-  #  '-export-dynamic $(no_undefined)
-  #$(ZLIB_LIBS)
   #$(SELINUX_LIBS)
-  #$(GLIB_LIBS)
   #$(XATTR_LIBS)
-  #$(NETWORK_LIBS)
-  dependencies : [ libz_dep, libdl_dep ] + platform_deps + network_libs,
-  c_args : gio_c_args
+  dependencies : [libintl, libz_dep, libdl_dep, libglib_dep, libgobject_dep,
+                  libgmodule_dep] + platform_deps + network_libs,
+  c_args : gio_c_args,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
 )
 
-# gresource tool
+libgio_dep = declare_dependency(link_with : libgio,
+  dependencies : [gioenumtypes_dep],
+  # We sadly need to export configinc here because everyone includes <gio/*.h>
+  include_directories : [configinc, gioinc])
+
+# Dependencies used by executables below
 libelf = dependency('libelf', version : '>= 0.8.12', required : false)
 if libelf.found()
   glib_conf.set('HAVE_LIBELF', 1)
 endif
+
+gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
+    input : ['data-to-c.py', meson.source_root() + '/glib/gconstructor.h'],
+    output : ['gconstructor_as_data.h'],
+    command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@'])
+
+# Several installed executables
 executable('gresource', 'gresource-tool.c',
-  include_directories : inc_dirs,
-  c_args : [ '-DHAVE_CONFIG_H=1' ],
-  link_with : [ libgio, libgobject, libgmodule, libglib ],
-  dependencies : libelf,
-)
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'],
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libelf, libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+
+executable('gio-querymodules', 'gio-querymodules.c',
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
 
-subdir('tests')
+executable('glib-compile-schemas',
+  [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-schemas.c'],
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'],
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+
+executable('glib-compile-resources',
+  [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'],
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+
+executable('gsettings', 'gsettings-tool.c',
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+install_data(['gschema.dtd', 'gschema.loc', 'gschema.its'],
+  install_dir : 'share/glib-2.0/schemas')
+
+executable('gdbus', 'gdbus-tool.c',
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+
+if host_system != 'windows'
+  executable('gapplication', 'gapplication-tool.c',
+    install : true,
+    c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
+    # intl.lib is not compatible with SAFESEH
+    link_args : noseh_link_args,
+    dependencies : [libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+endif
+
+if host_system != 'windows'
+  subdir('tests')
+endif
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index 3715005..1a3cbd9 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -88,11 +88,9 @@ foreach test_name : gio_tests
     test_name = 'autoptr-gio'
   endif
   exe = executable(test_name, src_file,
-      include_directories : inc_dirs,
       install : false,
       c_args : test_c_args,
-      link_with : [ libgio, libgmodule, libglib ],
-      dependencies : deps,
+      dependencies : [libglib_dep, libgmodule_dep, libgio_dep],
   )
   if test_name == 'testfilemonitor'
     test(test_name, exe, env : test_env, timeout : 45)
@@ -129,11 +127,9 @@ uninstalled_test_extra_programs = [
 
 foreach extra_program : uninstalled_test_extra_programs
   exe = executable(extra_program, '@0@.c'.format(extra_program),
-      include_directories : inc_dirs,
       install : false,
       c_args : test_c_args,
-      link_with : [ libgio, libgmodule, libglib ],
-      dependencies : deps,
+      dependencies : [libglib_dep, libgmodule_dep, libgio_dep],
   )
 endforeach
 
@@ -143,26 +139,20 @@ test_extra_programs = [
 ]
 
 exe = executable('tls-certificate', 'tls-certificate.c', 'gtesttlsbackend.c',
-  include_directories : inc_dirs,
   c_args : test_c_args,
-  link_with : [ libgio, libgmodule, libglib ],
-  dependencies : deps,
+  dependencies : [libglib_dep, libgmodule_dep, libgio_dep],
 )
 test('tls-certificate', exe, env : test_env)
 
 exe = executable('socket-client', 'socket-client.c', 'gtlsconsoleinteraction.c',
-  include_directories : inc_dirs,
   c_args : test_c_args,
-  link_with : [ libgio, libgmodule, libglib ],
-  dependencies : deps,
+  dependencies : [libglib_dep, libgmodule_dep, libgio_dep],
 )
 
 #exe = executable('gdbus-daemon', 'gdbus-daemon.c', '../gdbusdaemon.c',
 #  #meson.build_root() + '/gio/gdbus-daemon-generated.c', # FIXME
-#  include_directories : inc_dirs,
 #  c_args : test_c_args,
-#  link_with : [ libgio, libgmodule, libglib ],
-#  dependencies : deps,
+#  dependencies : [libglib_dep, libgmodule_dep, libgio_dep],
 #)
 #test('gdbus-daemon', exe, env : test_env)
 
@@ -174,45 +164,35 @@ endif
 
 # FIXME: consolidate all of these into the array
 exe = executable('overflow-fallback', 'overflow.c',
-  include_directories : inc_dirs,
   c_args : [ '-DHAVE_CONFIG_H=1', '-D_GLIB_TEST_OVERFLOW_FALLBACK' ],
-  link_with : libglib,
-  dependencies : deps,
+  dependencies : [libglib_dep],
 )
 test('overflow-fallback', exe, env : test_env)
 
 exe = executable('642026-ec', '642026.c',
-  include_directories : inc_dirs,
   c_args : [ '-DHAVE_CONFIG_H=1', '-DG_ERRORCHECK_MUTEXES' ],
-  link_with : libglib,
-  dependencies : deps,
+  dependencies : [libglib_dep],
 )
 test('642026-ec', exe, env : test_env)
 
 exe = executable('1bit-emufutex', '1bit-mutex.c',
-  include_directories : inc_dirs,
   c_args : [ '-DHAVE_CONFIG_H=1', '-DTEST_EMULATED_FUTEX' ],
-  link_with : libglib,
-  dependencies : deps,
+  dependencies : [libglib_dep],
 )
 test('1bit-emufutex', exe, env : test_env)
 
 if glib_conf.has('HAVE_EVENTFD')
   exe = executable('gwakeup-fallback', 'gwakeuptest.c', '../gwakeup.c',
-    include_directories : inc_dirs,
     c_args : [ '-DHAVE_CONFIG_H=1', '-DTEST_EVENTFD_FALLBACK' ],
-    link_with : libglib,
-    dependencies : deps,
+    dependencies : [libglib_dep],
   )
   test('gwakeup-fallback', exe, env : test_env)
 endif
 
 # test-spawn-echo helper binary required by the spawn tests
 executable('test-spawn-echo', 'test-spawn-echo.c',
-           include_directories : inc_dirs,
            c_args : [ '-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib"' ],
-           link_with : libglib,
-           dependencies : deps,
+           dependencies : [libglib_dep],
 )
 '''
 
diff --git a/gio/tests/modules/meson.build b/gio/tests/modules/meson.build
index 3d4af50..c219015 100644
--- a/gio/tests/modules/meson.build
+++ b/gio/tests/modules/meson.build
@@ -1,13 +1,11 @@
 libtestmodulea = shared_library('testmodulea', 'test-module-a.c',
   install : false,
-  include_directories : inc_dirs,
-  link_with : [ libglib, libgobject, libgmodule, libgio ],
+  dependencies : [libglib_dep, libgobject_dep, libgmodule_dep, libgio_dep],
   c_args : [ ]
 )
 
 libtestmoduleb = shared_library('testmoduleb', 'test-module-b.c',
   install : false,
-  include_directories : inc_dirs,
-  link_with : [ libglib, libgobject, libgmodule, libgio ],
+  dependencies : [libglib_dep, libgobject_dep, libgmodule_dep, libgio_dep],
   c_args : [ ]
 )
diff --git a/gio/win32/meson.build b/gio/win32/meson.build
index 52d720e..72b521c 100644
--- a/gio/win32/meson.build
+++ b/gio/win32/meson.build
@@ -8,6 +8,6 @@ giowin32_sources = [
 ]
 
 giowin32_lib = static_library('giowin32',
-  sources : giowin32_sources,
-  include_directories : inc_dirs,
+  sources : [giowin32_sources, gioenumtypes_h],
+  include_directories : [configinc, glibinc, gioinc, gmoduleinc],
   c_args : [ '-DHAVE_CONFIG_H', '-fPIC', '-DG_DISABLE_DEPRECATED' ] + gio_c_args)
diff --git a/gio/xdgmime/meson.build b/gio/xdgmime/meson.build
index 4b04221..5e1fb4a 100644
--- a/gio/xdgmime/meson.build
+++ b/gio/xdgmime/meson.build
@@ -11,5 +11,5 @@ xdgmime_sources = [
 
 xdgmime_lib = static_library('xdgmime',
   sources : xdgmime_sources,
-  include_directories : inc_dirs,
+  include_directories : [configinc],
   c_args : [ '-DHAVE_CONFIG_H', '-DXDG_PREFIX=_gio_xdg', '-fPIC' ])
diff --git a/glib/libcharset/meson.build b/glib/libcharset/meson.build
index 1ee08cc..9f267ef 100644
--- a/glib/libcharset/meson.build
+++ b/glib/libcharset/meson.build
@@ -1,3 +1,3 @@
 charset_lib = static_library('charset', 'localcharset.c',
-  include_directories : inc_dirs,
+  include_directories : configinc,
   c_args : [ '-DLIBDIR="lib"', '-fPIC' ])
diff --git a/glib/meson.build b/glib/meson.build
index 0c99dfc..ac32637 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -1,6 +1,12 @@
-configure_file(input : 'glibconfig.h.in', output : 'glibconfig.h', configuration : glibconfig_conf)
+configure_file(input : 'glibconfig.h.in', output : 'glibconfig.h',
+  install : true,
+  install_dir : 'lib/glib-2.0/include',
+  configuration : glibconfig_conf)
 
 subdir('libcharset')
+if not pcre.found()
+  subdir('pcre')
+endif
 
 glib_headers = [
   'glib.h',
@@ -17,7 +23,7 @@ glib_deprecated_headers = [
   'deprecated/grel.h',
   'deprecated/gthread.h',
 ]
-install_headers(glib_deprecated_headers, subdir : 'glib-2.0/deprecated/')
+install_headers(glib_deprecated_headers, subdir : 'glib-2.0/glib/deprecated/')
 
 glib_sub_headers = [
   'glib-autocleanups.h',
@@ -96,14 +102,6 @@ glib_sub_headers = [
 ]
 install_headers(glib_sub_headers, subdir : 'glib-2.0/glib/')
 
-if host_machine.system() == 'windows'
-  thread_src = ['gthread-win32.c']
-  plat_src = []
-else
-  thread_src = ['gthread-posix.c']
-  plat_src = ['glib-unix.c']
-endif
-
 deprecated_sources = [
 'deprecated/gallocator.c',
 'deprecated/gcache.c',
@@ -164,7 +162,6 @@ glib_sources = [
 'gstrfuncs.c',
 'gstring.c',
 'gstringchunk.c',
-'gtester.c',
 'gtestutils.c',
 'gthread.c',
 'gthreadpool.c',
@@ -190,19 +187,69 @@ glib_sources = [
 'gwakeup.c',
 'gprintf.c',]
 
-extra_src = ['gspawn.c', 'giounix.c']
+if host_system == 'windows'
+  thread_src = ['gthread-win32.c']
+  plat_src = ['gwin32.c', 'gspawn-win32.c', 'giowin32.c']
+  platform_deps = [winsock2, cc.find_library('winmm')]
+else
+  thread_src = ['gthread-posix.c']
+  plat_src = ['glib-unix.c', 'gspawn.c', 'giounix.c']
+  platform_deps = []
+endif
+
+libglib = shared_library('glib-2.0',
+  sources : [deprecated_sources, glib_sources, thread_src, plat_src],
+  version : library_version,
+  soversion : soversion,
+  install : true,
+  # intl.lib is not compatible with SAFESEH
+  link_args : noseh_link_args,
+  include_directories : configinc,
+  link_with : charset_lib,
+  dependencies : [pcre, thread_dep, libintl, librt] + libiconv + platform_deps,
+  c_args : ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION', '-DPCRE_STATIC']
+)
 
-#'gspawn-win32.c', # FIXME
-#'gspawn-win32-helper.c', # FIXME
+libglib_dep = declare_dependency(link_with : libglib,
+  # We sadly need to export configinc here because everyone includes <glib/*.h>
+  include_directories : [configinc, glibinc])
 
-libglib = shared_library('glib',
-sources : [deprecated_sources, glib_sources, thread_src, plat_src, extra_src],
-version : glib_version,
-soversion : interface_version,
-install : true,
-include_directories : inc_dirs,
-link_with : charset_lib,
-dependencies : [ pcre, thread_dep, libiconv, librt ],
-c_args : ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION', '-DPCRE_STATIC'])
+# On Windows, glib needs a spawn helper for g_spawn* API
+if host_system == 'windows'
+  if host_machine.cpu_family() == 'x86'
+    executable('gspawn-win32-helper', 'gspawn-win32-helper.c',
+      install : true,
+      gui_app : true,
+      c_args : ['-DHAVE_CONFIG_H=1'],
+      include_directories : configinc,
+      dependencies : [libglib_dep])
+    executable('gspawn-win32-helper-console', 'gspawn-win32-helper.c',
+      install : true,
+      c_args : ['-DHAVE_CONFIG_H=1', '-DHELPER_CONSOLE'],
+      include_directories : configinc,
+      dependencies : [libglib_dep])
+  else
+    executable('gspawn-win64-helper', 'gspawn-win32-helper.c',
+      install : true,
+      gui_app : true,
+      c_args : ['-DHAVE_CONFIG_H=1'],
+      include_directories : configinc,
+      dependencies : [libglib_dep])
+    executable('gspawn-win64-helper-console', 'gspawn-win32-helper.c',
+      install : true,
+      c_args : ['-DHAVE_CONFIG_H=1', '-DHELPER_CONSOLE'],
+      include_directories : configinc,
+      dependencies : [libglib_dep])
+  endif
+else
+  executable('gtester', 'gtester.c',
+    install : true,
+    c_args : ['-DHAVE_CONFIG_H=1'],
+    include_directories : configinc,
+    dependencies : [libglib_dep])
+endif
 
-subdir('tests')
+# gtester doesn't work on native windows
+if cc.get_id() != 'msvc'
+  subdir('tests')
+endif
diff --git a/glib/pcre/meson.build b/glib/pcre/meson.build
new file mode 100644
index 0000000..3c6c8f0
--- /dev/null
+++ b/glib/pcre/meson.build
@@ -0,0 +1,50 @@
+pcre_sources = [
+  'pcre_byte_order.c',
+  'pcre_chartables.c',
+  'pcre_compile.c',
+  'pcre_config.c',
+  'pcre_dfa_exec.c',
+  'pcre_exec.c',
+  'pcre_fullinfo.c',
+  'pcre_get.c',
+  'pcre_globals.c',
+  'pcre_jit_compile.c',
+  'pcre_newline.c',
+  'pcre_ord2utf8.c',
+  'pcre_string_utils.c',
+  'pcre_study.c',
+  'pcre_tables.c',
+  'pcre_valid_utf8.c',
+  'pcre_version.c',
+  'pcre_xclass.c',
+  'pcre.h',
+  'pcre_internal.h',
+  'ucp.h',
+]
+
+libpcre = static_library('pcre',
+  sources : [pcre_sources],
+  install : false,
+  include_directories : [configinc, glibinc],
+  dependencies : [],
+  c_args : ['-DG_LOG_DOMAIN="GLib-GRegex"',
+            '-DHAVE_MEMMOVE',
+            '-DSUPPORT_UCP',
+            '-DSUPPORT_UTF',
+            '-DSUPPORT_UTF8',
+            '-DNEWLINE=-1',
+            '-DMATCH_LIMIT=10000000',
+            '-DMATCH_LIMIT_RECURSION=8192',
+            '-DMAX_NAME_SIZE=32',
+            '-DMAX_NAME_COUNT=10000',
+            '-DMAX_DUPLENGTH=30000',
+            '-DLINK_SIZE=2',
+            '-DPOSIX_MALLOC_THRESHOLD=10',
+            '-DPCRE_STATIC',
+            '-UBSR_ANYCRLF',
+            '-UEBCDIC',
+            '-DGLIB_COMPILATION',
+           '-fPIC',]
+)
+
+pcre = declare_dependency(link_with : libpcre)
diff --git a/glib/tests/meson.build b/glib/tests/meson.build
index 9ef1b3d..983485b 100644
--- a/glib/tests/meson.build
+++ b/glib/tests/meson.build
@@ -88,57 +88,51 @@ test_env = [
   'G_TEST_BUILDDIR=' + meson.current_build_dir(),
 ]
 
+test_cargs = ['-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib"']
+
 foreach test_name : glib_tests
-  deps = [ libm, thread_dep ]
+  deps = [libm, thread_dep, libglib_dep]
   if test_name == 'regex'
-    deps += [ pcre ]
+    deps += [pcre]
   endif
   exe = executable(test_name, '@0@.c'.format(test_name),
-      include_directories : inc_dirs,
-      c_args : [ '-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib"' ],
-      link_with : libglib,
-      dependencies : deps,
-      install : false,
+    c_args : ['-DPCRE_STATIC'] + test_cargs,
+    dependencies : deps,
+    install : false,
   )
   test(test_name, exe, env : test_env)
 endforeach
 
-c_args_atomic = [ ]
+c_args_atomic = []
 if cc.get_id() == 'gcc'
-  c_args_atomic += [ '-Wstrict-aliasing=2' ]
+  c_args_atomic += ['-Wstrict-aliasing=2']
 endif
 
+deps = [libm, thread_dep, libglib_dep]
+
 exe = executable('atomic', 'atomic.c',
-  include_directories : inc_dirs,
-  c_args : [ '-DHAVE_CONFIG_H=1' ] + c_args_atomic,
-  link_with : libglib,
+  c_args : test_cargs + c_args_atomic,
   dependencies : deps,
 )
 test('atomic', exe, env : test_env)
 
 # FIXME: consolidate all of these into the array
 exe = executable('overflow-fallback', 'overflow.c',
-  include_directories : inc_dirs,
-  c_args : [ '-DHAVE_CONFIG_H=1', '-D_GLIB_TEST_OVERFLOW_FALLBACK' ],
-  link_with : libglib,
+  c_args : test_cargs + ['-D_GLIB_TEST_OVERFLOW_FALLBACK'],
   dependencies : deps,
   install : false,
 )
 test('overflow-fallback', exe, env : test_env)
 
 exe = executable('642026-ec', '642026.c',
-  include_directories : inc_dirs,
-  c_args : [ '-DHAVE_CONFIG_H=1', '-DG_ERRORCHECK_MUTEXES' ],
-  link_with : libglib,
+  c_args : test_cargs + ['-DG_ERRORCHECK_MUTEXES'],
   dependencies : deps,
   install : false,
 )
 test('642026-ec', exe, env : test_env)
 
 exe = executable('1bit-emufutex', '1bit-mutex.c',
-  include_directories : inc_dirs,
-  c_args : [ '-DHAVE_CONFIG_H=1', '-DTEST_EMULATED_FUTEX' ],
-  link_with : libglib,
+  c_args : test_cargs + ['-DTEST_EMULATED_FUTEX'],
   dependencies : deps,
   install : false,
 )
@@ -146,20 +140,16 @@ test('1bit-emufutex', exe, env : test_env)
 
 if glib_conf.has('HAVE_EVENTFD')
   exe = executable('gwakeup-fallback', 'gwakeuptest.c', '../gwakeup.c',
-    include_directories : inc_dirs,
-    c_args : [ '-DHAVE_CONFIG_H=1', '-DTEST_EVENTFD_FALLBACK' ],
-    link_with : libglib,
+    c_args : test_cargs + ['-DTEST_EVENTFD_FALLBACK'],
     dependencies : deps,
     install : false,
   )
   test('gwakeup-fallback', exe, env : test_env)
 endif
 
-# test-spawn-echo helper binary required by the spawn tests
+# test-spawn-echo helper binary required by the spawn tests above
 executable('test-spawn-echo', 'test-spawn-echo.c',
-           include_directories : inc_dirs,
-           c_args : [ '-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib"' ],
-           link_with : libglib,
-           dependencies : deps,
-           install : false,
+  c_args : test_cargs,
+  dependencies : deps,
+  install : false,
 )
diff --git a/gmodule/meson.build b/gmodule/meson.build
index 465c4e4..3319740 100644
--- a/gmodule/meson.build
+++ b/gmodule/meson.build
@@ -22,21 +22,21 @@ int main (int argc, char ** argv) {
 }'''
 
 # On Windows force native WIN32 shared lib loader
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   g_module_impl = 'G_MODULE_IMPL_WIN32'
 # Force native AIX library loader
 # dlopen() filepath must be of the form /path/libname.a(libname.so)
-elif host_machine.system() == 'aix'
+elif host_system == 'aix'
   g_module_impl = 'G_MODULE_IMPL_AR'
 elif cc.links(dlopen_dlsym_test_code, name : 'dlopen() and dlsym() in system libraries')
   g_module_impl = 'G_MODULE_IMPL_DL'
 # NSLinkModule (dyld) in system libraries (Darwin)
-elif cc.has_function('NSLinkModule', prefix : '#include <mach-o/dyld.h>', name : 'NSLinkModule')
+elif cc.has_function('NSLinkModule')
   g_module_impl = 'G_MODULE_IMPL_DYLD'
   g_module_need_uscore = 1
 elif cc.links(dlopen_dlsym_test_code, args : '-ldl', name : 'dlopen() and dlsym() in libdl')
   g_module_impl = 'G_MODULE_IMPL_DL'
-  libdl_dep = find_library('dl')
+  libdl_dep = cc.find_library('dl')
   g_module_lib_args = '-ldl'
 endif
 
@@ -45,17 +45,23 @@ if g_module_impl == 'G_MODULE_IMPL_DL'
   # FIXME: check for OSF1/5.0 RTLD_GLOBAL brokenness (is this still relevant?)
 
   # Check whether we need preceding underscores
-  if not meson.is_cross_build()
+  if cc.get_id() == 'msvc'
+    message('Building for MSVC: assuming that symbols are prefixed with underscore')
+    g_module_need_uscore = 1
+  elif meson.has_exe_wrapper()
     # FIXME: communicate result via stdout instead of return value, so non-0 return is not printed in bold 
red
     rres = cc.run(dlopen_dlsym_test_code,
                   args : g_module_lib_args,
                   name : 'dlsym() preceding underscores')
-    if rres.compiled() and rres.returncode() == 0
+    if host_system == 'windows' or rres.returncode() == 0
       g_module_need_uscore = 1
     endif
+  else
+    message('Cross-compiling: assuming that symbols aren\'t prefixed with underscore')
+    g_module_need_uscore = 0
   endif
 
-  if cc.has_function('dlerror', prefix : '#include <dlfcn.h>', args : g_module_lib_args, name : 'dlerror')
+  if cc.has_function('dlerror', args : g_module_lib_args)
     g_module_have_dlerror = 1
   endif
 endif
@@ -76,15 +82,17 @@ gmoduleconf_h = configure_file(input : 'gmoduleconf.h.in',
                                output : 'gmoduleconf.h',
                                configuration : gmoduleconf_conf)
 
-install_headers([ 'gmodule.h' ], subdir : 'glib-2.0/')
+install_headers(['gmodule.h'], subdir : 'glib-2.0/')
 
-libgmodule = shared_library('gmodule',
-  sources : [ 'gmodule.c' ],
-  version : glib_version,
-  soversion : interface_version,
+libgmodule = shared_library('gmodule-2.0',
+  sources : ['gmodule.c'],
+  version : library_version,
+  soversion : soversion,
   install : true,
-  include_directories : inc_dirs,
-  link_with : libglib,
-  dependencies : libdl_dep,
-  c_args : ['-DG_LOG_DOMAIN="GModule"', '-DG_DISABLE_DEPRECATED' ],
+  include_directories : [configinc, gmoduleinc],
+  dependencies : [libdl_dep, libglib_dep],
+  c_args : ['-DG_LOG_DOMAIN="GModule"', '-DG_DISABLE_DEPRECATED'],
 )
+
+libgmodule_dep = declare_dependency(link_with : libgmodule,
+  include_directories : gmoduleinc)
diff --git a/gobject/gmarshal-list-to-strings.py b/gobject/gmarshal-list-to-strings.py
new file mode 100644
index 0000000..ee60953
--- /dev/null
+++ b/gobject/gmarshal-list-to-strings.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+# Does the same thing as `marshal-genstrings.pl` and the 'gmarshal.strings'
+# target in Makefile.am
+
+import re
+import sys
+
+prefix = '"g_cclosure_marshal_'
+suffix = '",\n'
+
+if len(sys.argv) != 3:
+    print('Usage: {0} <input> <output>'.format(sys.argv[0]))
+
+fin = open(sys.argv[1], 'r')
+fout = open(sys.argv[2], 'w')
+
+for line in fin:
+    if not line[0].isalpha():
+        continue
+    symbol = line[:-1].replace(':', '__').replace(',', '_')
+    fout.write(prefix + symbol + suffix)
diff --git a/gobject/meson.build b/gobject/meson.build
index cdb6443..22a3f51 100644
--- a/gobject/meson.build
+++ b/gobject/meson.build
@@ -1,10 +1,3 @@
-#FIXME
-#if host_machine.system() == 'windows'
-#  plat_src = []
-#else
-#  plat_src = []
-#endif
-
 gobject_install_headers = [
   'gobject-autocleanups.h',
   'glib-types.h',
@@ -52,14 +45,42 @@ gobject_c_sources = [
   'gvaluetypes.c',
 ]
 
-libgobject = shared_library('gobject',
-sources : [ gobject_c_sources ],
-version : glib_version,
-soversion : interface_version,
-install : true,
-include_directories : inc_dirs,
-link_with : libglib,
-dependencies : libffi_dep,
-c_args : ['-DG_LOG_DOMAIN="GLib-GObject"', '-DGOBJECT_COMPILATION' ])
+libgobject = shared_library('gobject-2.0',
+  sources : [gobject_c_sources],
+  version : library_version,
+  soversion : soversion,
+  install : true,
+  include_directories : [configinc],
+  dependencies : [libffi_dep, libglib_dep],
+  c_args : ['-DG_LOG_DOMAIN="GLib-GObject"', '-DGOBJECT_COMPILATION'])
+
+libgobject_dep = declare_dependency(link_with : libgobject,
+  include_directories : gobjectinc)
+
+glib_mkenums_conf = configuration_data()
+glib_mkenums_conf.set('GLIB_VERSION', glib_version)
+glib_mkenums_conf.set('PERL_PATH', perl.path())
+
+# FIXME: Set permissions
+glib_mkenums = configure_file(input : 'glib-mkenums.in',
+  output : 'glib-mkenums',
+  install : true,
+  install_dir : 'bin', configuration : glib_mkenums_conf)
+
+executable('gobject-query', 'gobject-query.c',
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'],
+  dependencies : [libglib_dep, libgobject_dep])
+
+gmarshal_strings = custom_target('gmarshal.strings',
+    input : ['gmarshal-list-to-strings.py', 'gmarshal.list'],
+    output : ['gmarshal.strings'],
+    command : [python, '@INPUT0@', '@INPUT1@', '@OUTPUT@'])
+
+glib_genmarshal = executable('glib-genmarshal',
+  gmarshal_strings, 'glib-genmarshal.c',
+  install : true,
+  c_args : ['-DHAVE_CONFIG_H=1'],
+  dependencies : [libglib_dep, libgobject_dep])
 
 subdir('tests')
diff --git a/gobject/tests/gobject_test_marshal.py b/gobject/tests/gobject_test_marshal.py
index a0f6852..66a7aec 100755
--- a/gobject/tests/gobject_test_marshal.py
+++ b/gobject/tests/gobject_test_marshal.py
@@ -4,14 +4,18 @@
 
 import sys, subprocess
 
-assert(len(sys.argv) == 3)
+if len(sys.argv) != 3:
+    print('Usage: {0} <listname> <outputfile>')
+    sys.exit(0)
 
-_, listname, outname = sys.argv
+glib_genmarshal = sys.argv[1]
+listname = sys.argv[2]
+outname = sys.argv[3]
 
 if outname.endswith('.h'):
     arg = '--header'
 else:
     arg = '--body'
 
-output = subprocess.check_output(['glib-genmarshal', '--prefix=test', '--valist-marshallers', arg, listname])
+output = subprocess.check_output([glib_genmarshal, '--prefix=test', '--valist-marshallers', arg, listname])
 open(outname, 'wb').write(output)
diff --git a/gobject/tests/meson.build b/gobject/tests/meson.build
index 21aefd9..03be192 100644
--- a/gobject/tests/meson.build
+++ b/gobject/tests/meson.build
@@ -23,16 +23,14 @@ test_env = [
 ]
 
 foreach test_name : gobject_tests
-  deps = [ libm, thread_dep ]
+  deps = [libm, thread_dep, libglib_dep, libgobject_dep]
   test_src = '@0@.c'.format(test_name)
   # private is an existing or reserved target it seems
   if test_name == 'private'
     test_name = 'gobject-private'
   endif
   exe = executable(test_name, test_src,
-      include_directories : inc_dirs,
-      c_args : [ '-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib-GObject"' ],
-      link_with : [ libglib, libgobject ],
+      c_args : ['-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib-GObject"'],
       dependencies : deps,
   )
   test(test_name, exe, env : test_env)
@@ -40,29 +38,23 @@ endforeach
 
 # The marshalers test requires running a binary, so we cannot build it when
 # cross-compiling
-if not meson.is_cross_build()
-  # FIXME: need to pass this as argument to the genmarshal script
-  # and somehow we need to specify it as build dep of the custom targets
-  # lib_genmarshal = meson.build_root() + '/gobject/glib-genmarshal'
-
+if not meson.has_exe_wrapper()
   genmarshal = find_program('gobject_test_marshal.py')
 
   marshalers_h = custom_target('marshalers_h',
     output : 'marshalers.h',
     input : 'marshalers.list',
-    command : [ genmarshal, '@INPUT@', '@OUTPUT@' ],
+    command : [genmarshal, glib_genmarshal, '@INPUT@', '@OUTPUT@'],
   )
   marshalers_c = custom_target('marshalers_c',
     output : 'marshalers.c',
     input : 'marshalers.list',
-    command : [ genmarshal, '@INPUT@', '@OUTPUT@' ],
+    command : [genmarshal, glib_genmarshal, '@INPUT@', '@OUTPUT@'],
   )
 
   exe = executable('signals',
       'signals.c', marshalers_h, marshalers_c,
-      include_directories : inc_dirs,
-      c_args : [ '-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib-GObject"' ],
-      link_with : [ libglib, libgobject ],
+      c_args : ['-DHAVE_CONFIG_H=1', '-DG_LOG_DOMAIN="GLib-GObject"'],
       dependencies : deps,
   )
   test('signals', exe, env : test_env)
diff --git a/gthread/meson.build b/gthread/meson.build
index a12c420..1efe1e3 100644
--- a/gthread/meson.build
+++ b/gthread/meson.build
@@ -1,11 +1,10 @@
 # Just a skeleton lib for backwards compatibility since all the functionaliy
 # has been moved into glib now
-libgthread = shared_library('gthread',
+libgthread = shared_library('gthread-2.0',
   sources : [ 'gthread-impl.c' ],
-  version : glib_version,
-  soversion : interface_version,
+  version : library_version,
+  soversion : soversion,
   install : true,
-  include_directories : inc_dirs,
-  link_with : libglib,
+  dependencies : [libglib_dep],
   c_args : ['-DG_LOG_DOMAIN="GThread"' ],
 )
diff --git a/meson.build b/meson.build
index 19092a4..3658e73 100644
--- a/meson.build
+++ b/meson.build
@@ -1,23 +1,60 @@
 project('glib', 'c', 'cpp',
-  version : '2.47.6',
-  meson_version : '>= 0.30.0',
+  version : '2.51.0',
+  meson_version : '>= 0.32.0',
   default_options : [ 'warning_level=1',
-                      'c_std=gnu99',
+                      'c_std=gnu89',
                       'buildtype=debugoptimized' ])
 
 cc = meson.get_compiler('c')
 cxx = meson.get_compiler('cpp')
 
-add_global_arguments('-Werror', language : 'c') # FIXME
+if cc.get_id() == 'msvc'
+  # Ignore several spurious warnings for things glib does very commonly
+  # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
+  # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
+  # NOTE: Only add warnings here if you are sure they're spurious
+  add_global_arguments('/wd4244', '/wd4305', '/wd4035', '/wd4715', '/wd4116',
+    '/wd4046', '/wd4068', '/wo4090', language : 'c')
+  # Disable SAFESEH with MSVC for plugins and libs that use external deps that
+  # are built with MinGW
+  noseh_link_args = ['/SAFESEH:NO']
+else
+  noseh_link_args = []
+  # -mms-bitfields vs -fnative-struct ?
+endif
 
-major_version = 2
-minor_version = 47
-micro_version = 6
-interface_version = 2 # FIXME
+host_system = host_machine.system()
 
-glib_version = meson.project_version()
-inc_dirs = include_directories('.', 'glib', 'gmodule', 'gio')
+#add_global_arguments('-Werror', language : 'c') # FIXME
 
+glib_version = meson.project_version()
+version_arr = glib_version.split('.')
+major_version = version_arr[0]
+minor_version = version_arr[1]
+micro_version = version_arr[2]
+
+soversion = 0
+# Maintain compatibility with previous libtool versioning
+# current = minor * 100 + micro
+library_version = '@0@.@1@.0'.format(soversion, minor_version.to_int() * 100 + micro_version.to_int())
+
+configinc = include_directories('.')
+glibinc = include_directories('glib')
+gobjectinc = include_directories('gobject')
+gmoduleinc = include_directories('gmodule')
+gioinc = include_directories('gio')
+
+glib_prefix = get_option('prefix')
+glib_libdir = glib_prefix + '/' + get_option('libdir')
+glib_datadir = glib_prefix + '/share'
+glib_includedir = glib_prefix + '/include'
+glib_giomodulesdir = glib_libdir + '/gio/modules'
+
+glib_pkgconfigreldir = get_option('libdir') + '/pkgconfig'
+
+########################
+# Configuration begins #
+########################
 glib_conf = configuration_data()
 glibconfig_conf = configuration_data()
 
@@ -25,11 +62,12 @@ glibconfig_conf = configuration_data()
 # use them later in test programs (autoconf does this automatically)
 glib_conf_prefix = ''
 
+glib_conf.set('GLIB_VERSION', glib_version)
 glib_conf.set('GLIB_MAJOR_VERSION', major_version)
 glib_conf.set('GLIB_MINOR_VERSION', minor_version)
 glib_conf.set('GLIB_MICRO_VERSION', micro_version)
 glib_conf.set('GLIB_INTERFACE_AGE', micro_version)
-glib_conf.set('GLIB_BINARY_AGE', major_version * 100 + minor_version * 10 + micro_version)
+glib_conf.set('GLIB_BINARY_AGE', 100 * minor_version.to_int() + micro_version.to_int())
 glib_conf.set('GETTEXT_PACKAGE', '"glib20"')
 glib_conf.set('PACKAGE_BUGREPORT', '"http://bugzilla.gnome.org/enter_bug.cgi?product=glib";')
 glib_conf.set('PACKAGE_NAME', '"glib"')
@@ -40,8 +78,40 @@ glib_conf.set('PACKAGE_VERSION', '"@0@"'.format(meson.project_version()))
 glib_conf.set('ENABLE_NLS', 1)
 glib_conf.set('HAVE_GOOD_PRINTF', 1) # FIXME
 
+# Variables used in glib-gettextize and pkg-config files
+# These should not contain " quotes around the values
+glib_conf.set('PACKAGE', 'glib')
+glib_conf.set('VERSION', meson.project_version())
+glib_conf.set('prefix', glib_prefix)
+glib_conf.set('exec_prefix', glib_prefix)
+glib_conf.set('libdir', glib_libdir)
+glib_conf.set('includedir', glib_includedir)
+glib_conf.set('datadir', glib_datadir)
+glib_conf.set('datarootdir', glib_datadir)
+
 glib_conf.set('_GNU_SOURCE', 1)
 
+if host_system == 'windows'
+  # Poll doesn't work on devices on Windows
+  glib_conf.set('BROKEN_POLL', true)
+endif
+
+# Detect and set symbol visibility
+if get_option('default_library') != 'static'
+  if host_system == 'windows'
+    glib_conf.set('DLL_EXPORT', true)
+    if cc.get_id() == 'msvc'
+      glib_conf.set('_GLIB_EXTERN', '__declspec(dllexport) extern')
+    else
+      glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) __declspec(dllexport) extern')
+      add_global_arguments('-fvisibility=hidden', language : 'c')
+    endif
+  else
+    glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) extern')
+    add_global_arguments('-fvisibility=hidden', language : 'c')
+  endif
+endif
+
 if run_command('xgettext', '--help').returncode() != 0
   error('GNU Gettext required currently.')
 endif
@@ -49,9 +119,9 @@ glib_conf.set('HAVE_GETTEXT', 1)
 glib_conf.set('GLIB_LOCALE_DIR', '"@0@/share/locale"'.format(get_option('prefix')))
 
 # FIXME: what about Cygwin (G_WITH_CYGWIN)
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   glib_os = '''#define G_OS_WIN32
-               #define G_PLATFORM_WIN32'''
+#define G_PLATFORM_WIN32'''
 else
   glib_os = '#define G_OS_UNIX'
 endif
@@ -59,75 +129,66 @@ glibconfig_conf.set('glib_os', glib_os)
 
 # check for header files
 
-include_sys_param_h_if_available = '''
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif'''
-
 headers = [
-  [ 'stdlib.h', 'HAVE_STDLIB_H' ],
-  [ 'string.h', 'HAVE_STRING_H' ],
-  [ 'strings.h', 'HAVE_STRINGS_H' ],
-  [ 'memory.h', 'HAVE_MEMORY_H' ],
-  [ 'alloca.h', 'HAVE_ALLOCA_H' ],
-  [ 'locale.h', 'HAVE_LOCALE_H' ],
-  [ 'xlocale.h', 'HAVE_XLOCALE_H' ],
-  [ 'float.h', 'HAVE_FLOAT_H' ],
-  [ 'limits.h', 'HAVE_LIMITS_H' ],
-  [ 'pwd.h', 'HAVE_PWD_H' ],
-  [ 'grp.h', 'HAVE_GRP_H' ],
-  [ 'poll.h', 'HAVE_POLL_H' ],
-  [ 'sys/param.h', 'HAVE_SYS_PARAM_H' ],
-  [ 'sys/resource.h', 'HAVE_SYS_RESOURCE_H' ],
-  [ 'mach/mach_time.h', 'HAVE_MACH_MACH_TIME_H' ],
-  [ 'sys/select.h', 'HAVE_SYS_SELECT_H' ],
-  [ 'stdint.h', 'HAVE_STDINT_H' ],
-  [ 'inttypes.h', 'HAVE_INTTYPES_H' ],
-  [ 'sched.h', 'HAVE_SCHED_H' ],
-  [ 'malloc.h', 'HAVE_MALLOC_H' ],
-  [ 'sys/vfs.h', 'HAVE_SYS_VFS_H' ],
-  [ 'sys/vmount.h', 'HAVE_SYS_VMOUNT_H' ],
-  [ 'sys/statfs.h', 'HAVE_SYS_STATFS_H' ],
-  [ 'sys/statvfs.h', 'HAVE_SYS_STATVFS_H' ],
-  [ 'sys/filio.h', 'HAVE_SYS_FILIO_H' ],
-  [ 'mntent.h', 'HAVE_MNTENT_H' ],
-  [ 'sys/mnttab.h', 'HAVE_SYS_MNTTAB_H' ],
-  [ 'sys/vfstab.h', 'HAVE_SYS_VFSTAB_H' ],
-  [ 'sys/mntctl.h', 'HAVE_SYS_mntctl_H' ],
-  [ 'fstab.h', 'HAVE_FSTAB_H' ],
-  [ 'linux/magic.h', 'HAVE_LINUX_MAGIC_H' ],
-  [ 'sys/prctl.h', 'HAVE_SYS_PRCTL_H' ],
-  [ 'dirent.h', 'HAVE_DIRENT_H' ], # Some versions of MSC lack these
-  [ 'sys/time.h', 'HAVE_SYS_TIME_H' ], # Some versions of MSC lack these
-  [ 'sys/times.h', 'HAVE_SYS_TIMES_H' ],
-  [ 'sys/wait.h', 'HAVE_SYS_WAIT_H' ],
-  [ 'unistd.h', 'HAVE_UNISTD_H' ],
-  [ 'values.h', 'HAVE_VALUES_H' ],
-  [ 'sys/types.h', 'HAVE_SYS_TYPES_H' ],
-  [ 'sys/uio.h', 'HAVE_SYS_UIO_H' ],
-  [ 'sys/mkdev.h', 'HAVE_SYS_MKDEV_H' ],
-  [ 'sys/mount.h', 'HAVE_SYS_MOUNT_H', include_sys_param_h_if_available ],
-  [ 'sys/sysctl.h', 'HAVE_SYS_SYSCTL_H', include_sys_param_h_if_available ],
-  [ 'crt_externs.h', 'HAVE_CRT_EXTERNS_H' ],
-  [ 'linux/netlink.h', 'HAVE_NETLINK', '#include <sys/socket.h>' ],
-  [ 'sys/inotify.h', 'HAVE_SYS_INOTIFY_H' ],
-  [ 'sys/event.h', 'HAVE_SYS_EVENT_H' ],
+  ['stdlib.h', 'HAVE_STDLIB_H'],
+  ['string.h', 'HAVE_STRING_H'],
+  ['strings.h', 'HAVE_STRINGS_H'],
+  ['memory.h', 'HAVE_MEMORY_H'],
+  ['alloca.h', 'HAVE_ALLOCA_H'],
+  ['locale.h', 'HAVE_LOCALE_H'],
+  ['xlocale.h', 'HAVE_XLOCALE_H'],
+  ['float.h', 'HAVE_FLOAT_H'],
+  ['limits.h', 'HAVE_LIMITS_H'],
+  ['pwd.h', 'HAVE_PWD_H'],
+  ['grp.h', 'HAVE_GRP_H'],
+  ['poll.h', 'HAVE_POLL_H'],
+  ['sys/param.h', 'HAVE_SYS_PARAM_H'],
+  ['sys/resource.h', 'HAVE_SYS_RESOURCE_H'],
+  ['mach/mach_time.h', 'HAVE_MACH_MACH_TIME_H'],
+  ['sys/select.h', 'HAVE_SYS_SELECT_H'],
+  ['stdint.h', 'HAVE_STDINT_H'],
+  ['inttypes.h', 'HAVE_INTTYPES_H'],
+  ['sched.h', 'HAVE_SCHED_H'],
+  ['malloc.h', 'HAVE_MALLOC_H'],
+  ['sys/vfs.h', 'HAVE_SYS_VFS_H'],
+  ['sys/vmount.h', 'HAVE_SYS_VMOUNT_H'],
+  ['sys/statfs.h', 'HAVE_SYS_STATFS_H'],
+  ['sys/statvfs.h', 'HAVE_SYS_STATVFS_H'],
+  ['sys/filio.h', 'HAVE_SYS_FILIO_H'],
+  ['mntent.h', 'HAVE_MNTENT_H'],
+  ['sys/mnttab.h', 'HAVE_SYS_MNTTAB_H'],
+  ['sys/vfstab.h', 'HAVE_SYS_VFSTAB_H'],
+  ['sys/mntctl.h', 'HAVE_SYS_mntctl_H'],
+  ['fstab.h', 'HAVE_FSTAB_H'],
+  ['linux/magic.h', 'HAVE_LINUX_MAGIC_H'],
+  ['sys/prctl.h', 'HAVE_SYS_PRCTL_H'],
+  ['dirent.h', 'HAVE_DIRENT_H'], # Some versions of MSC lack these
+  ['sys/time.h', 'HAVE_SYS_TIME_H'], # Some versions of MSC lack these
+  ['sys/times.h', 'HAVE_SYS_TIMES_H'],
+  ['sys/wait.h', 'HAVE_SYS_WAIT_H'],
+  ['unistd.h', 'HAVE_UNISTD_H'],
+  ['values.h', 'HAVE_VALUES_H'],
+  ['sys/types.h', 'HAVE_SYS_TYPES_H'],
+  ['sys/uio.h', 'HAVE_SYS_UIO_H'],
+  ['sys/mkdev.h', 'HAVE_SYS_MKDEV_H'],
+  ['sys/mount.h', 'HAVE_SYS_MOUNT_H'],
+  ['sys/sysctl.h', 'HAVE_SYS_SYSCTL_H'],
+  ['crt_externs.h', 'HAVE_CRT_EXTERNS_H'],
+  ['linux/netlink.h', 'HAVE_NETLINK'],
+  ['sys/inotify.h', 'HAVE_SYS_INOTIFY_H'],
+  ['sys/event.h', 'HAVE_SYS_EVENT_H'],
+  ['sys/stat.h', 'HAVE_SYS_STAT_H'],
 ]
 
 foreach h : headers
-  header_check_prefix = glib_conf_prefix
-  if h.length() == 3
-    header_check_prefix = header_check_prefix + h[2]
-  endif
-  if cc.has_header(h[0], prefix: header_check_prefix)
+  if cc.has_header(h[0])
     glib_conf.set(h[1], 1)
     glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(h[1])
   endif
 endforeach
 
 if glib_conf.has('HAVE_LOCALE_H')
-  if cc.compiles('''#include <locale.h>
-                    void foo() { LC_MESSAGES; }''')
+  if cc.has_header_symbol('locale.h', 'LC_MESSAGES')
     glib_conf.set('HAVE_LC_MESSAGES', 1)
   endif
 endif
@@ -182,140 +243,90 @@ foreach m : struct_members
   endif
 endforeach
 
-#FIXME: maybe we should add available includes all to the glib_conf_prefix list
-# functions
 functions = [
-  [ 'alloca', 'HAVE_ALLOCA', '#include <alloca.h>' ],
-  [ 'mmap', 'HAVE_MMAP', '#include <sys/mman.h>' ],
-  [ 'posix_memalign', 'HAVE_POSIX_MEMALIGN', '#include <stdlib.h>' ],
-  [ 'memalign', 'HAVE_MEMALIGN', '#include <malloc.h>' ],
-  [ 'valloc', 'HAVE_VALLOC', '#include <stdlib.h>' ],
-  [ 'fsync', 'HAVE_FSYNC', '''#ifdef HAVE_UNISTD_H
-                              #include <unistd.h>
-                              #endif''' ],
-  [ 'pipe2', 'HAVE_PIPE2', '''#define _GNU_SOURCE
-                              #include <fcntl.h>
-                              #include <unistd.h>''' ],
-  [ 'issetugid', 'HAVE_ISSETUGID', '#include <unistd.h>' ],
-  [ 'timegm', 'HAVE_TIMEGM', '#include <time.h>' ],
-  [ 'gmtime_r', 'HAVE_GMTIME_R', '#include <time.h>' ],
-  [ 'strerror_r', 'HAVE_STRERROR_R', '#include <string.h>' ],
-  [ 'lstat', 'HAVE_LSTAT', '''#include <sys/types.h>
-                              #include <sys/stat.h>
-                              #include <unistd.h>'''],
-  [ 'strsignal', 'HAVE_STRSIGNAL', '#include <string.h>' ],
-  [ 'vsnprintf', 'HAVE_VSNPRINTF', '#include <stdio.h>' ],
-  [ 'stpcpy', 'HAVE_STPCPY', '#include <string.h>' ],
-  [ 'strcasecmp', 'HAVE_STRCASECMP', '#include <strings.h>' ],
-  [ 'strncasecmp', 'HAVE_STRNCASECMP', '#include <strings.h>' ],
-  [ 'poll', 'HAVE_POLL', '#include <poll.h>' ],
-  [ 'vasprintf', 'HAVE_VASPRINTF', '''#define _GNU_SOURCE
-                                      #include <stdio.h>''' ],
-  [ 'setenv', 'HAVE_SETENV', '#include <stdlib.h>' ],
-  [ 'unsetenv', 'HAVE_UNSETENV', '#include <stdlib.h>' ],
-  [ 'getc_unlocked', 'HAVE_GETC_UNLOCKED', '#include <stdio.h>' ],
-  [ 'readlink', 'HAVE_READLINK', '#include <unistd.h>' ],
-  [ 'symlink', 'HAVE_SYMLINK', '#include <unistd.h>' ],
-  [ 'fdwalk', 'HAVE_FDWALK', '#include <stdlib.h>' ],
-  [ 'memmem', 'HAVE_MEMMEM', '''#define _GNU_SOURCE
-                                #include <string.h>''' ],
-# FIXME: this check doesn't work right, meson detects that it exists even if it's unusable
-#  [ 'lchmod', 'HAVE_LCHMOD', '''#include <sys/stat.h>
-#                                #include <unistd.h>''' ],
-  [ 'lchown', 'HAVE_LCHOWN', '#include <unistd.h>' ],
-  [ 'fchmod', 'HAVE_FCHMOD', '#include <sys/stat.h>' ],
-  [ 'fchown', 'HAVE_FCHOWN', '#include <unistd.h>' ],
-  [ 'utimes', 'HAVE_UTIMES', '#include <sys/time.h>' ],
-  [ 'getresuid', 'HAVE_GETRESUID', '''#define _GNU_SOURCE
-                                      #include <unistd.h>''' ],
-  [ 'getmntent_r', 'HAVE_GETMNTENT_R', '''#include <stdio.h>
-                                          #include <mntent.h>'''],
-  [ 'setmntent', 'HAVE_SETMNTENT', '''#include <stdio.h>
-                                      #include <mntent.h>'''],
-  [ 'endmntent', 'HAVE_ENDMNTENT', '''#include <stdio.h>
-                                      #include <mntent.h>'''],
-  [ 'hasmntopt', 'HAVE_HASMNTOPT', '''#include <stdio.h>
-                                      #include <mntent.h>'''],
-  [ 'getfsstat', 'HAVE_GETFSSTAT', '''#include <sys/param.h>
-                                      #include <sys/ucred.h>
-                                      #include <sys/mount.h''' ],
-  [ 'getvfsstat', 'HAVE_GETVFSSTAT', '''#include <sys/types.h>
-                                        #include <sys/statvfs.h>''' ],
-  [ 'fallocate', 'HAVE_FALLOCATE', '''#define _GNU_SOURCE
-                                      #include <fcntl.h>''' ],
-  [ 'localtime_r', 'HAVE_LOCALTIME_R', '#include <time.h>' ],
-  [ 'gmtime_r', 'HAVE_GMTIME_R', '#include <time.h>' ],
-  [ 'getpwuid_r', 'HAVE_GETPWUID_R', '''#include <sys/types.h>
-                                        #include <pwd.h>''' ],
-  [ 'getgrgid_r', 'HAVE_GETGRGID_R', '''#include <sys/types.h>
-                                        #include <grp.h>''' ],
-  [ 'prlimit', 'HAVE_PRLIMIT', '''#define _GNU_SOURCE
-                                  #include <sys/time.h>
-                                  #include <sys/resource.h>''' ],
-  [ 'snprintf', 'HAVE_SNPRINTF', '#include <stdio.h>' ],
-  [ 'strnlen', 'HAVE_STRNLEN', '#include <string.h>' ],
-  [ 'wcslen', 'HAVE_WCSLEN', '#include <wchar.h>' ],
-  [ 'wcsnlen', 'HAVE_WCSNLEN', '#include <wchar.h>' ],
-  [ 'mbrtowc', 'HAVE_MBRTOWC', '#include <wchar.h>' ],
-  [ 'wcrtomb', 'HAVE_WCRTOMB', '#include <wchar.h>' ],
-  [ 'newlocale', 'HAVE_NEWLOCALE', '#include <locale.h>' ],
-  [ 'uselocale', 'HAVE_USELOCALE', '#include <locale.h>' ],
-  [ 'strtod_l', 'HAVE_STRTOD_L', '''#define _GNU_SOURCE
-                                    #include <stdlib.h>
-                                    #ifdef HAVE_XLOCALE_H
-                                    #include <xlocale.h>
-                                    #endif''' ],
-  [ 'strtoll_l', 'HAVE_STRTOLL_L', '''#define _GNU_SOURCE
-                                      #include <stdlib.h>
-                                      #include <limits.h>
-                                      #ifdef HAVE_XLOCALE_H
-                                      #include <xlocale.h>
-                                      #endif''' ],
-  [ 'strtoull_l', 'HAVE_STRTOULL_L', '''#define _GNU_SOURCE
-                                        #include <stdlib.h>
-                                        #include <limits.h>
-                                        #ifdef HAVE_XLOCALE_H
-                                        #include <xlocale.h>
-                                        #endif''' ],
-  [ 'inotify_init1', 'HAVE_INOTIFY_INIT1', '#include <sys/inotify.h>' ],
-  [ 'kqueue', 'HAVE_KQUEUE', '#include <sys/event.h>' ],
-  [ 'kevent', 'HAVE_KEVENT', '#include <sys/event.h>' ],
-  [ 'getservent', 'HAVE_GETSERVENT', '#include <netdb.h>' ],
-  [ 'getprotobyname_r', 'HAVE_GETPROTOBYNAME_R', '#include <netdb.h>' ],
-  [ 'if_indextoname', 'HAVE_IF_INDEXTONAME', '#include <net/if.h>' ],
-  [ 'if_nametoindex', 'HAVE_IF_NAMETOINDEX', '#include <net/if.h>' ],
-  [ 'sendmmsg', 'HAVE_SENDMMSG', '''#define _GNU_SOURCE
-                                    #include <sys/socket.h>''' ],
-  [ 'recvmmsg', 'HAVE_RECVMMSG', '''#define _GNU_SOURCE
-                                    #include <sys/socket.h>''' ],
+  ['alloca', 'HAVE_ALLOCA'],
+  ['mmap', 'HAVE_MMAP'],
+  ['posix_memalign', 'HAVE_POSIX_MEMALIGN'],
+  ['memalign', 'HAVE_MEMALIGN'],
+  ['valloc', 'HAVE_VALLOC'],
+  ['fsync', 'HAVE_FSYNC'],
+  ['pipe2', 'HAVE_PIPE2'],
+  ['issetugid', 'HAVE_ISSETUGID'],
+  ['timegm', 'HAVE_TIMEGM'],
+  ['gmtime_r', 'HAVE_GMTIME_R'],
+  ['strerror_r', 'HAVE_STRERROR_R'],
+  ['lstat', 'HAVE_LSTAT'],
+  ['strsignal', 'HAVE_STRSIGNAL'],
+  ['vsnprintf', 'HAVE_VSNPRINTF'],
+  ['stpcpy', 'HAVE_STPCPY'],
+  ['poll', 'HAVE_POLL'],
+  ['vasprintf', 'HAVE_VASPRINTF'],
+  ['setenv', 'HAVE_SETENV'],
+  ['unsetenv', 'HAVE_UNSETENV'],
+  ['getc_unlocked', 'HAVE_GETC_UNLOCKED'],
+  ['readlink', 'HAVE_READLINK'],
+  ['symlink', 'HAVE_SYMLINK'],
+  ['fdwalk', 'HAVE_FDWALK'],
+  ['memmem', 'HAVE_MEMMEM'],
+  ['lchmod', 'HAVE_LCHMOD'],
+  ['lchown', 'HAVE_LCHOWN'],
+  ['fchmod', 'HAVE_FCHMOD'],
+  ['fchown', 'HAVE_FCHOWN'],
+  ['utimes', 'HAVE_UTIMES'],
+  ['getresuid', 'HAVE_GETRESUID'],
+  ['getmntent_r', 'HAVE_GETMNTENT_R'],
+  ['setmntent', 'HAVE_SETMNTENT'],
+  ['endmntent', 'HAVE_ENDMNTENT'],
+  ['hasmntopt', 'HAVE_HASMNTOPT'],
+  ['getfsstat', 'HAVE_GETFSSTAT'],
+  ['getvfsstat', 'HAVE_GETVFSSTAT'],
+  ['fallocate', 'HAVE_FALLOCATE'],
+  ['localtime_r', 'HAVE_LOCALTIME_R'],
+  ['gmtime_r', 'HAVE_GMTIME_R'],
+  ['getpwuid_r', 'HAVE_GETPWUID_R'],
+  ['getgrgid_r', 'HAVE_GETGRGID_R'],
+  ['prlimit', 'HAVE_PRLIMIT'],
+  ['strnlen', 'HAVE_STRNLEN'],
+  ['wcslen', 'HAVE_WCSLEN'],
+  ['wcsnlen', 'HAVE_WCSNLEN'],
+  ['mbrtowc', 'HAVE_MBRTOWC'],
+  ['wcrtomb', 'HAVE_WCRTOMB'],
+  ['newlocale', 'HAVE_NEWLOCALE'],
+  ['uselocale', 'HAVE_USELOCALE'],
+  ['strtod_l', 'HAVE_STRTOD_L'],
+  ['strtoll_l', 'HAVE_STRTOLL_L'],
+  ['strtoull_l', 'HAVE_STRTOULL_L'],
+  ['inotify_init1', 'HAVE_INOTIFY_INIT1'],
+  ['kqueue', 'HAVE_KQUEUE'],
+  ['kevent', 'HAVE_KEVENT'],
+  ['getservent', 'HAVE_GETSERVENT'],
+  ['getprotobyname_r', 'HAVE_GETPROTOBYNAME_R'],
+  ['if_indextoname', 'HAVE_IF_INDEXTONAME'],
+  ['if_nametoindex', 'HAVE_IF_NAMETOINDEX'],
+  ['sendmmsg', 'HAVE_SENDMMSG'],
+  ['recvmmsg', 'HAVE_RECVMMSG'],
 ]
 
 if glib_conf.has('HAVE_SYS_STATVFS_H')
-  functions += [ [ 'statvfs', 'HAVE_STATVFS', '#include <sys/statvfs.h>'] ]
+  functions += [['statvfs', 'HAVE_STATVFS']]
+else
+  have_func_statvfs = false
 endif
 if glib_conf.has('HAVE_SYS_STATFS_H') or glib_conf.has('HAVE_SYS_MOUNT_H')
-  functions += [ [ 'statfs', 'HAVE_STATFS', '''#ifdef HAVE_SYS_STATFS_H
-                                               #include <sys/statfs.h>
-                                               #endif
-                                               #ifdef HAVE_SYS_MOUNT_H
-                                               #include <sys/mount.h>
-                                               #endif'''] ]
+  functions += [['statfs', 'HAVE_STATFS']]
+else
+  have_func_statfs = false
 endif
 
 # AIX splice is something else
-if host_machine.system() != 'aix'
+if host_system != 'aix'
   functions += [
-    [ 'splice', 'HAVE_SPLICE', '''#define _GNU_SOURCE
-                                  #include <fcntl.h>''' ]
+    [ 'splice', 'HAVE_SPLICE' ]
   ]
 endif
 
 foreach f : functions
-  header_check_prefix = glib_conf_prefix
-  if f.length() == 3
-    header_check_prefix = header_check_prefix + f[2]
-  endif
-  if cc.has_function (f[0], prefix : header_check_prefix)
+  if cc.has_function(f[0])
     glib_conf.set(f[1], 1)
     glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(f[1])
     set_variable('have_func_' + f[0], true)
@@ -324,6 +335,34 @@ foreach f : functions
   endif
 endforeach
 
+# Special-case these functions that have alternative names on Windows/MSVC
+if cc.has_function('snprintf') or cc.has_header_symbol('stdio.h', 'snprintf')
+  glib_conf.set('HAVE_SNPRINTF', 1)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF 1\n'
+elif cc.has_function('_snprintf') or cc.has_header_symbol('stdio.h', '_snprintf')
+  hack_define = '1\n#define snprintf _snprintf'
+  glib_conf.set('HAVE_SNPRINTF', hack_define)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF ' + hack_define
+endif
+
+if cc.has_function('strcasecmp')
+  glib_conf.set('HAVE_STRCASECMP', 1)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP 1\n'
+elif cc.has_function('_stricmp')
+  hack_define = '1\n#define strcasecmp _stricmp'
+  glib_conf.set('HAVE_STRCASECMP', hack_define)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP ' + hack_define
+endif
+
+if cc.has_function('strncasecmp')
+  glib_conf.set('HAVE_STRNCASECMP', 1)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP 1\n'
+elif cc.has_function('_strnicmp')
+  hack_define = '1\n#define strncasecmp _strnicmp'
+  glib_conf.set('HAVE_STRNCASECMP', hack_define)
+  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP ' + hack_define
+endif
+
 # Check whether to use statfs or statvfs
 # Some systems have both statfs and statvfs, pick the most "native" for these
 if have_func_statfs and have_func_statvfs
@@ -358,15 +397,6 @@ else
   CARBON_LIBS=''
 endif
 
-# Check for nl_langinfo and CODESET
-if cc.links('''#include <langinfo.h>
-               int main (int argc, char ** argv) {
-                 char *codeset = nl_langinfo (CODESET);
-                 return 0;
-               }''', name : 'nl_langinfo and CODESET')
-  glib_conf.set('HAVE_LANGINFO_CODESET', 1)
-endif
-
 # Check for futex(2)
 if cc.links('''#include <linux/futex.h>
                #include <sys/syscall.h>
@@ -394,13 +424,12 @@ clock_gettime_test_code = '''
   int main (int argc, char ** argv) {
     return clock_gettime(CLOCK_REALTIME, &t);
   }'''
-# FIXME: or will librt be in the meson threads dep already?
-librt = [ ]
+librt = []
 if cc.links(clock_gettime_test_code, name : 'clock_gettime')
   glib_conf.set('HAVE_CLOCK_GETTIME', 1)
 elif cc.links(clock_gettime_test_code, args : '-lrt', name : 'clock_gettime in librt')
   glib_conf.set('HAVE_CLOCK_GETTIME', 1)
-  librt = find_library('rt')
+  librt = cc.find_library('rt')
 endif
 
 # if statfs() takes 2 arguments (Posix) or 4 (Solaris)
@@ -463,7 +492,7 @@ endif
 # AC_FUNC_VSNPRINTF_C99
 # Check whether there is a snprintf() function with C99 semantics installed.
 # AC_FUNC_SNPRINTF_C99
-if host_machine.system() == 'windows' and cc.get_id() == 'gcc' # FIXME: is it mingw on windows?
+if host_system == 'windows' and cc.get_id() == 'gcc'
   # Unfortunately the mingw implementations of C99-style snprintf and vsnprintf
   # don't seem to be quite good enough, at least not in mingw-runtime-3.14.
   # (Sorry, I don't know exactly what is the problem, but it is related to
@@ -558,7 +587,7 @@ main(void)
   endif
 endif
 
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   glib_conf.set('EXEEXT', '".exe"')
 else
   glib_conf.set('EXEEXT', '""')
@@ -566,30 +595,18 @@ endif
 
 # Check whether the printf() family supports Unix98 %n$ positional parameters
 # AC_FUNC_PRINTF_UNIX98
-printf_unix98_test_code = '''
-#include <stdio.h>
+# Nothing uses HAVE_UNIX98_PRINTF
 
-int
-main (void)
-{
-  char buffer[128];
-
-  sprintf (buffer, "%2\$d %3\$d %1\$d", 1, 2, 3);
-  if (strcmp ("2 3 1", buffer) == 0)
-    exit (0);
-  exit (1);
-}'''
-rres = cc.run(printf_unix98_test_code, name : 'printf unix98 position parameters')
-if rres.compiled() and rres.returncode() == 0
-  glib_conf.set('HAVE_UNIX98_PRINTF', 1)
-endif
+glib_conf.set('HAVE_DCGETTEXT', cc.has_header_symbol('libintl.h', 'dcgettext'))
 
 # Check for nl_langinfo and CODESET
+# FIXME: Check for HAVE_BIND_TEXTDOMAIN_CODESET
 if cc.links('''#include <langinfo.h>
                int main (int argc, char ** argv) {
                  char *codeset = nl_langinfo (CODESET);
                  return 0;
-               }''', name : 'nl_langinfo (CODESET)')
+               }''', name : 'nl_langinfo and CODESET')
+  glib_conf.set('HAVE_LANGINFO_CODESET', 1)
   glib_conf.set('HAVE_CODESET', 1)
 endif
 
@@ -634,8 +651,7 @@ if not cc.compiles('''signed char x;''', name : 'signed')
 endif
 
 # Check if the ptrdiff_t type exists
-if cc.compiles('''#include <stddef.h>
-                  ptrdiff_t x;''', name : 'ptrdiff_t')
+if cc.has_header_symbol('stddef.h', 'ptrdiff_t')
   glib_conf.set('HAVE_PTRDIFF_T', 1)
 endif
 
@@ -649,8 +665,9 @@ if cc.links('''#include <signal.h>
   glib_conf.set('HAVE_SIG_ATOMIC_T', 1)
 endif
 
-# Check if 'long long' works.
+# Check if 'long long' works and what format can be used to print it
 # jm_AC_TYPE_LONG_LONG
+# Nothing uses HAVE_LONG_LONG_FORMAT and HAVE_INT64_AND_I64
 if cc.compiles('''long long ll = 1LL;
                   int i = 63;
                   int some_func (void) {
@@ -673,16 +690,12 @@ if cc.compiles('''/* The Stardent Vistra knows sizeof(long double), but does not
 endif
 
 #dnl Test whether <stddef.h> has the 'wchar_t' type.
-if cc.compiles('''#include <stddef.h>
-                  wchar_t foo = (wchar_t)'\0';''',
-               name : 'wchar_t')
+if cc.has_header_symbol('stddef.h', 'wchar_t')
   glib_conf.set('HAVE_WCHAR_T', 1)
 endif
 
 # Test whether <wchar.h> has the 'wint_t' type.
-if cc.compiles('''#include <wchar.h>
-                  wint_t foo = (wchar_t)'\0';''',
-               name : 'wint_t')
+if cc.has_header_symbol('wchar.h', 'wint_t')
   glib_conf.set('HAVE_WINT_T', 1)
 endif
 
@@ -735,13 +748,28 @@ else
   long_long_size = 0
 endif
 sizet_size = cc.sizeof('size_t')
-ssizet_size = cc.sizeof('ssize_t')
+if cc.get_id() == 'msvc'
+  ssizet_size = cc.sizeof('SSIZE_T', prefix : '#include <BaseTsd.h>')
+else
+  ssizet_size = cc.sizeof('ssize_t')
+endif
+
+# On Windows, MSVC supports both ll and I64 as format specifiers for 64-bit
+# integers, but some versions (at least 4.7.x) of MinGW only support I64.
+if host_system == 'windows'
+  int64_m = '"I64'
+else
+  int64_m = '"ll'
+endif
 
 char_align = cc.alignment('char')
 short_align = cc.alignment('short')
 int_align = cc.alignment('int')
 voidp_align = cc.alignment('void*')
 long_align = cc.alignment('long')
+long_long_align = cc.alignment('long long')
+# NOTE: We don't check for size of __int64 because long long is guaranteed to
+# be 64-bit in C99, and it is available on all supported compilers
 sizet_align = cc.alignment('size_t')
 
 glib_conf.set('ALIGNOF_UNSIGNED_LONG', long_align)
@@ -755,47 +783,44 @@ glib_conf.set('SIZEOF_SIZE_T', sizet_size)
 glib_conf.set('SIZEOF_SSIZE_T', ssizet_size)
 glib_conf.set('SIZEOF_VOID_P', voidp_size)
 
-if long_size == 2
-  # configure.ac does not work if this is the case. So we don't either.
-  gint16 = 'long'
-endif
-if int_size == 2
-  gint16 = 'int'
-  gint16_modifier='""'
-  gint16_format='"i"'
-  guint16_format='"u"'
-endif
 if short_size == 2
   gint16 = 'short'
   gint16_modifier='"h"'
   gint16_format='"hi"'
   guint16_format='"hu"'
+elif int_size == 2
+  gint16 = 'int'
+  gint16_modifier='""'
+  gint16_format='"i"'
+  guint16_format='"u"'
+else
+  error('Compiler provides no native 16-bit integer type')
 endif
 glibconfig_conf.set('gint16', gint16)
 glibconfig_conf.set('gint16_modifier', gint16_modifier)
 glibconfig_conf.set('gint16_format', gint16_format)
 glibconfig_conf.set('guint16_format', guint16_format)
 
-if long_size == 4
-  gint32 = 'long'
-  gint32_modifier='"l"'
-  gint32_format='"li"'
-  guint32_format='"lu"'
-  guint32_align = long_align
-endif
-if int_size == 4
-  gint32 = 'int'
-  gint32_modifier='""'
-  gint32_format='"i"'
-  guint32_format='"u"'
-  guint32_align = int_align
-endif
 if short_size == 4
   gint32 = 'short'
   gint32_modifier='"h"'
   gint32_format='"hi"'
   guint32_format='"hu"'
   guint32_align = short_align
+elif int_size == 4
+  gint32 = 'int'
+  gint32_modifier='""'
+  gint32_format='"i"'
+  guint32_format='"u"'
+  guint32_align = int_align
+elif long_size == 4
+  gint32 = 'long'
+  gint32_modifier='"l"'
+  gint32_format='"li"'
+  guint32_format='"lu"'
+  guint32_align = long_align
+else
+  error('Compiler provides no native 32-bit integer type')
 endif
 glibconfig_conf.set('gint32', gint32)
 glibconfig_conf.set('gint32_modifier', gint32_modifier)
@@ -803,20 +828,6 @@ glibconfig_conf.set('gint32_format', gint32_format)
 glibconfig_conf.set('guint32_format', guint32_format)
 glib_conf.set('ALIGNOF_GUINT32', guint32_align)
 
-if long_long_size == 8
-  # Currently broken.
-  gint64 = 'long long'
-endif
-if long_size == 8
-  gint64 = 'long'
-  gint64_modifier='"l"'
-  gint64_format='"li"'
-  guint64_format='"lu"'
-  glib_extension=''
-  gint64_constant='(val##L)'
-  guint64_constant='(val##UL)'
-  guint64_align = long_align
-endif
 if int_size == 8
   gint64 = 'int'
   gint64_modifier='""'
@@ -826,10 +837,26 @@ if int_size == 8
   gint64_constant='(val)'
   guint64_constant='(val)'
   guint64_align = int_align
-endif
-if short_size == 8
-  # Another one broken in configure.ac
-  gint64 = 'short'
+elif long_size == 8
+  gint64 = 'long'
+  glib_extension=''
+  gint64_modifier='"l"'
+  gint64_format='"li"'
+  guint64_format='"lu"'
+  gint64_constant='(val##L)'
+  guint64_constant='(val##UL)'
+  guint64_align = long_align
+elif long_long_size == 8
+  gint64 = 'long long'
+  glib_extension=''
+  gint64_modifier=int64_m + '"'
+  gint64_format=int64_m + 'i"'
+  guint64_format=int64_m + 'u"'
+  gint64_constant='(val##LL)'
+  guint64_constant='(val##ULL)'
+  guint64_align = long_long_align
+else
+  error('Compiler provides no native 64-bit integer type')
 endif
 glibconfig_conf.set('gint64', gint64)
 glibconfig_conf.set('gint64_modifier', gint64_modifier)
@@ -839,7 +866,7 @@ glibconfig_conf.set('gint64_constant', gint64_constant)
 glibconfig_conf.set('guint64_constant', guint64_constant)
 glib_conf.set('ALIGNOF_GUINT64', guint64_align)
 
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   glibconfig_conf.set('g_pid_type', 'void*')
   if host_machine.cpu_family() == 'x86_64'
     glibconfig_conf.set('g_pollfd_format', '"%#I64x"')
@@ -874,10 +901,10 @@ elif sizet_size == long_size
   glibconfig_conf.set('glib_msize_type', 'LONG')
 elif sizet_size == long_long_size
   glibconfig_conf.set('glib_size_type_define', 'long long')
-  glibconfig_conf.set('gsize_modifier', '"I64"')
-  glibconfig_conf.set('gssize_modifier', '"I64"')
-  glibconfig_conf.set('gsize_format', '"I64u"')
-  glibconfig_conf.set('gssize_format', '"I64i"')
+  glibconfig_conf.set('gsize_modifier', int64_m + '"')
+  glibconfig_conf.set('gssize_modifier', int64_m + '"')
+  glibconfig_conf.set('gsize_format', int64_m + 'u"')
+  glibconfig_conf.set('gssize_format', int64_m + 'i"')
   glibconfig_conf.set('glib_msize_type', 'INT64')
 else
   error('Could not determine size of size_t.')
@@ -899,32 +926,28 @@ elif voidp_size == long_size
   glibconfig_conf.set('glib_gpui_cast', '(gulong)')
 elif voidp_size == long_long_size
   glibconfig_conf.set('glib_intptr_type_define', 'long long')
-  glibconfig_conf.set('gintptr_modifier', '"I64"')
-  glibconfig_conf.set('gintptr_format', '"I64i"')
-  glibconfig_conf.set('guintptr_format', '"I64u"')
+  glibconfig_conf.set('gintptr_modifier', int64_m + '"')
+  glibconfig_conf.set('gintptr_format', int64_m + 'i"')
+  glibconfig_conf.set('guintptr_format', int64_m + 'u"')
   glibconfig_conf.set('glib_gpi_cast', '(gint64)')
   glibconfig_conf.set('glib_gpui_cast', '(guint64)')
-# FIXME
-#elif voidp_size == __int64_size
-#  glib_intptr_type_define=__int64
-#  gintptr_modifier='"I64"'
-#  gintptr_format='"I64i"'
-#  guintptr_format='"I64u"'
-#  glib_gpi_cast='(gint64)'
-#  glib_gpui_cast='(guint64)'
 else
   error('Could not determine size of void *')
 endif
 
+if long_size != 8 and long_long_size != 8 and int_size != 8
+  error('GLib requires a 64-bit type. You might want to consider using the GNU C compiler.')
+endif
+
 glibconfig_conf.set('gintbits', int_size * 8)
 glibconfig_conf.set('glongbits', long_size * 8)
 glibconfig_conf.set('gsizebits', sizet_size * 8)
 glibconfig_conf.set('gssizebits', ssizet_size * 8)
 
 # FIXME: maybe meson should tell us the libsuffix?
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   g_module_suffix = 'dll'
-elif host_machine.system() == 'darwin'
+elif host_system == 'darwin'
   g_module_suffix = 'dylib'
 else
   g_module_suffix = 'so'
@@ -995,7 +1018,7 @@ va_list_val_copy_prog = '''
 glib_va_val_copy = false
 if cc.compiles(va_list_val_copy_prog, name : 'va_lists can be copied as values')
   # FIXME: what to do when cross-compiling?
-  if cc.run(va_list_val_copy_prog, 'va_lists can be copied as values').returncode() == 0
+  if cc.run(va_list_val_copy_prog, name : 'va_lists can be copied as values').returncode() == 0
     glib_va_val_copy = true
   endif
 endif
@@ -1050,6 +1073,7 @@ has_systypes = cc.has_header('sys/types.h')
 if has_syspoll
   glibconfig_conf.set('GLIB_HAVE_SYS_POLL_H', true)
 endif
+has_winsock2 = cc.has_header('winsock2.h')
 
 if has_syspoll and has_systypes
   templ = '''#include<sys/poll.h>
@@ -1059,23 +1083,26 @@ int main(int argc, char **argv) {
   printf("%d\n", (int)@0@);
   return 0;
 }'''
-  value_POLLIN = cc.run(templ.format('POLLIN')).stdout().strip()
-  value_POLLOUT = cc.run(templ.format('POLLOUT')).stdout().strip()
-  value_POLLPRI = cc.run(templ.format('POLLPRI')).stdout().strip()
-  value_POLLERR = cc.run(templ.format('POLLERR')).stdout().strip()
-  value_POLLHUP = cc.run(templ.format('POLLHUP')).stdout().strip()
-  value_POLLNVAL = cc.run(templ.format('POLLNVAL')).stdout().strip()
+elif has_winsock2
+  templ = '''#define _WIN32_WINNT 0x0600
+#include <stdio.h>
+#include <winsock2.h>
+int main(int argc, char **argv) {
+  printf("%d\n", (int)@0@);
+  return 0;
+}'''
 else
   # FIXME?
   error('FIX POLL* defines')
-  value_POLLIN = 1
-  value_POLLOUT = 4
-  value_POLLPRI = 2
-  value_POLLERR = 8
-  value_POLLHUP = 16
-  value_POLLNVAL = 32
 endif
 
+value_POLLIN = cc.run(templ.format('POLLIN')).stdout().strip()
+value_POLLOUT = cc.run(templ.format('POLLOUT')).stdout().strip()
+value_POLLPRI = cc.run(templ.format('POLLPRI')).stdout().strip()
+value_POLLERR = cc.run(templ.format('POLLERR')).stdout().strip()
+value_POLLHUP = cc.run(templ.format('POLLHUP')).stdout().strip()
+value_POLLNVAL = cc.run(templ.format('POLLNVAL')).stdout().strip()
+
 glibconfig_conf.set('g_pollin', value_POLLIN)
 glibconfig_conf.set('g_pollout', value_POLLOUT)
 glibconfig_conf.set('g_pollpri', value_POLLPRI)
@@ -1085,7 +1112,7 @@ glibconfig_conf.set('g_pollnval', value_POLLNVAL)
 
 # Internet address families
 # FIXME: what about Cygwin (G_WITH_CYGWIN)
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   glib_inet_includes= '''
 #include <winsock2.h>
 '''
@@ -1112,7 +1139,7 @@ int main(int argc, char **argv) {
   return 0;
 }'''
   # FIXME: fix for cross-compilation
-  if meson.is_cross_build()
+  if not meson.has_exe_wrapper()
     error('Fix sys define detection for cross build')
   endif
   val = cc.run(templ.format(glib_inet_includes, d[0])).stdout().strip()
@@ -1128,7 +1155,7 @@ if host_cpu_family == 'x86' or host_cpu_family == 'x86_64' or host_cpu_family ==
 elif host_cpu_family.startswith('sparc') or host_cpu_family.startswith('alpha') or 
host_cpu_family.startswith('powerpc') or host_cpu_family == 'ia64'
   glib_memory_barrier_needed = true
 else
-  # FIXME: should warn perhaps
+  error('Unknown host cpu: ' + host_cpu_family)
   glib_memory_barrier_needed = true
 endif
 glibconfig_conf.set('G_ATOMIC_OP_MEMORY_BARRIER_NEEDED', glib_memory_barrier_needed)
@@ -1151,12 +1178,32 @@ endif
 thread_dep = dependency('threads')
 
 # Determination of thread implementation
-if host_machine.system() == 'windows'
+if host_system == 'windows'
   glibconfig_conf.set('g_threads_impl_def', 'WIN32')
   glib_conf.set('THREADS_WIN32', 1)
 else
   glibconfig_conf.set('g_threads_impl_def', 'POSIX')
   glib_conf.set('THREADS_POSIX', 1)
+  if cc.has_header_symbol('pthread.h', 'pthread_attr_setstacksize')
+    glib_conf.set('HAVE_PTHREAD_ATTR_SETSTACKSIZE', 1)
+  endif
+  if cc.has_header_symbol('pthread.h', 'pthread_condattr_setclock')
+    glib_conf.set('HAVE_PTHREAD_CONDATTR_SETCLOCK', 1)
+  endif
+  if cc.has_header_symbol('pthread.h', 'pthread_cond_timedwait_relative_np')
+    glib_conf.set('HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP', 1)
+  endif
+  if cc.links('''#include <pthread.h>
+                 int main() {
+                   pthread_setname_np("example");
+                 }''', name : 'pthread_setname_np(const char*)')
+    glib_conf.set('HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID', 1)
+  elif cc.links('''#include <pthread.h>
+                 int main() {
+                   pthread_setname_np(pthread_self(), "example");
+                 }''', name : 'pthread_setname_np(pthread_t, const char*)')
+    glib_conf.set('HAVE_PTHREAD_SETNAME_NP_WITH_TID', 1)
+  endif
 endif
 
 # FIXME: how to do this when cross-compiling?
@@ -1185,40 +1232,59 @@ else
 endif
 
 # Tests for iconv
+#
+# First, we check if the C library provides iconv, then GNU libiconv, then
+# a native implementation
+# FIXME: add option as well
+#
 # USE_LIBICONV_GNU: Using GNU libiconv
-# USE_LIBICONV_NATIVE: Using a native implementation of iconv in a separate library
-# On Windows we use a native implementation
-if host_machine.system() == 'windows'
+# USE_LIBICONV_NATIVE: Using a native impl of iconv in a separate library
+#
+# We should never use the MinGW C library's iconv. On Windows we use the
+# GNU implementation that ships with MinGW.
+
+# On Windows, just always use the built-in implementation
+if host_system == 'windows'
+  libiconv = []
+  glib_conf.set('USE_LIBICONV_NATIVE', true)
+# Check C library; never check MinGW C library
+elif cc.has_function('iconv_open')
+  libiconv = []
+# Check for libiconv
+elif cc.has_header_symbol('iconv.h', 'libiconv_open')
+  glib_conf.set('USE_LIBICONV_GNU', true)
+  libiconv = [cc.find_library('iconv')]
+# Check for a custom iconv implementation
+elif cc.has_header_symbol('iconv.h', 'iconv_open')
   glib_conf.set('USE_LIBICONV_NATIVE', true)
-  libiconv = find_library('iconv')
+  libiconv = [cc.find_library('iconv')]
 else
-  # FIXME: add option as well
-  if cc.has_function('iconv_open', prefix : '#include <iconv.h>', name : 'C library iconv')
-    libiconv = [ ]
-  # FIXME: this is all wrong, meson needs a more intuitive check for this, like cc.has_lib_function() or such
-  elif cc.compiles('''#include <iconv.h>
-                      void somefunc (void) {
-                        libiconv_open("foo", "bar")
-                      }''', args : '-liconv', name : 'GNU libiconv')
-    glib_conf.set('USE_LIBICONV_GNU', true)
-    libiconv = find_library('iconv')
-  elif cc.compiles('''#include <iconv.h>
-                      void somefunc (void) {
-                        iconv_open("foo", "bar")
-                      }''', args : '-liconv', name : 'other libiconv')
-    glib_conf.set('USE_LIBICONV_NATIVE', true)
-    libiconv = find_library('iconv')
-  else
-    error('No iconv() implementation found in C library or libiconv')
-  endif
+  error('No iconv() implementation found in C library or libiconv')
 endif
 
-pcre = dependency('libpcre') # Should check for Unicode support, too. FIXME
-glib_conf.set('USE_SYSTEM_PCRE', '/**/')
+pcre = dependency('libpcre', required : false) # Should check for Unicode support, too. FIXME
+glib_conf.set('USE_SYSTEM_PCRE', pcre.found())
 
-libm = find_library('m')
+libm = cc.find_library('m', required : false)
 libffi_dep = dependency('libffi', version : '>= 3.0.0')
 libz_dep = dependency('zlib')
+# Only used on non-glibc targets
+libintl = cc.find_library('intl', required : false)
+
+if host_system == 'windows'
+  winsock2 = cc.find_library('ws2_32')
+endif
+
+# Needed for glib-mkenums
+perl = find_program('perl')
+
+python = find_program('python3', required : false)
+if not python.found()
+  # All our scripts are compatible with python 2, so it's ok if this is Python 2
+  # Also, we don't check for 'python2' because if the user doesn't have Python
+  # installed, we want them to see that we want 'python', not 'python2'.
+  python = find_program('python')
+endif
 
 # FIXME: defines in config.h that are not actually used anywhere
 # (we add them for now to minimise the diff)
@@ -1226,7 +1292,25 @@ glib_conf.set('HAVE_DLFCN_H', 1)
 glib_conf.set('__EXTENSIONS__', 1)
 glib_conf.set('STDC_HEADERS', 1)
 # THREADS_NONE
-glib_conf.set('SIZEOF___INT64', 0)
+glib_conf.set('SIZEOF___INT64', 8)
+
+# Various substs needed for our pkg-config files
+# FIXME: Derive these from the dependency() objects (Meson support needed)
+glib_conf.set('ZLIB_LIBS', '-lz')
+glib_conf.set('LIBFFI_LIBS', '-lffi')
+if libintl.found()
+  glib_conf.set('INTLLIBS', '-lintl')
+endif
+if libiconv.length() != 0
+  glib_conf.set('ICONV_LIBS', '-liconv')
+endif
+if pcre.found()
+  glib_conf.set('PCRE_LIBS', '-lpcre')
+endif
+glib_conf.set('GIO_MODULE_DIR', '${libdir}/gio/modules')
+# FIXME: Missing:
+# @G_MODULE_LIBS@ @SELINUX_LIBS@ @COCOA_LIBS@ @CARBON_LIBS@ @G_LIBS_EXTRA@
+# @PCRE_REQUIRES@ @GLIB_EXTRA_CFLAGS@ @G_THREAD_CFLAGS@
 
 subdir('glib')
 subdir('gobject')
@@ -1234,4 +1318,43 @@ subdir('gthread')
 subdir('gmodule')
 subdir('gio')
 
-configure_file(input : 'config.h.meson', output : 'config.h', configuration : glib_conf)
+# Configure and install pkg-config files
+pc_files = [
+  'gobject-2.0.pc',
+  'glib-2.0.pc',
+  'gthread-2.0.pc',
+  'gmodule-2.0.pc',
+  'gmodule-export-2.0.pc',
+  'gmodule-no-export-2.0.pc',
+  'gio-2.0.pc',
+]
+if host_system == 'windows'
+  pc_files += ['gio-windows-2.0.pc']
+else
+  pc_files += ['gio-unix-2.0.pc']
+endif
+
+foreach pc : pc_files
+  configure_file(input : pc + '.in',
+    install : true,
+    install_dir : glib_pkgconfigreldir,
+    output : pc,
+    configuration : glib_conf)
+endforeach
+
+# NOTE: We skip glib-zip.in because the filenames it assumes don't match ours
+
+# Install glib-gettextize executable
+configure_file(input : 'glib-gettextize.in',
+  install : true,
+  install_dir : 'bin',
+  output : 'glib-gettextize',
+  configuration : glib_conf)
+
+# Install m4 macros that other projects use
+install_data('m4macros/glib-2.0.m4', 'm4macros/glib-gettext.m4', 'm4macros/gsettings.m4',
+  install_dir : 'share/aclocal')
+
+configure_file(input : 'config.h.meson',
+  output : 'config.h',
+  configuration : glib_conf)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]