Skip to content
Commits on Source (41)
Overview of changes in GLib 2.67.5
==================================
* Fix more issues with `glib_typeof` macro from 2.67.3–2.67.4 (work by
Iain Lane, Simon McVittie) (#2331, !1975)
* Fix regression with some FD mappings passed to `g_subprocess_launcher_spawnv()`
caused by changes for #2097 in GLib 2.67.4 (work by Olivier Fourdan,
Philip Withnall) (#2332)
* Fix detection of `str[n]casecmp()` when building with `clang-cl` (work by
Aleksandr Mezin) (#2337)
* Use zlib from subproject if configured with `wrap_mode=forcefallback` (work by
Seungha Yang) (!1959)
* Bump Visual Studio compilation requirement to VS 2012, and Windows 8 SDK for
GLib 2.67.x onwards (work by Chun-wei Fan) (!1970)
* Bugs fixed:
- #832 Some tweaks re: GRWLock
- #2331 glib 2.67.3: <glib.h> can no longer be included in extern "C" blocks
- #2332 Glib 2.67.4 causes gnome-shell to exit when spawning Xwayland on demand
- #2333 Missing relation between g_file_info_get_size() and G_FILE_ATTRIBUTE_STANDARD_SIZE attribute in documentation
- #2337 Linking fails when building with clang-cl because of str[n]casecmp
- !1936 tests: Fix leak of dlopened module in pollable test
- !1954 Change SkipAsyncData fields to be gsize (and not gssize)
- !1956 The ETag returned by various GFile functions is nullable
- !1959 meson: Use subproject zlib if "wrap_mode=forcefallback" was specified
- !1961 gkeyfilesettingsbackend: check for errors when creating file monitors
- !1970 README.win32.md: Mention about Window 8+ SDK requirement
- !1971 gio/tests/pollable.c: Fix build on non-Linux UNIX
- !1975 gatomic.h: Make `glib_typeof` API break opt in.
* Translation updates:
- Basque
- Danish
- English (United Kingdom)
- Galician
- German
- Indonesian
- Lithuanian
- Portuguese
- Portuguese (Brazil)
- Slovenian
Overview of changes in GLib 2.67.4
==================================
......
......@@ -161,22 +161,9 @@ To overcome this problem, please set your system's locale setting for non-Unicod
English (United States), reboot, and restart the build, and the code should build
normally.
### Visual Studio 2008 hacks
### Support for pre-2012 Visual Studio
- You need to run the following lines from your build directory, to embed the
manifests that are generated during the build, assuming the built binaries
are installed to `$(PREFIX)`, after a successful build/installation:
```cmd
> for /r %f in (*.dll.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f $(PREFIX)\bin\%~nf;2
> for /r %f in (*.exe.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f $(PREFIX)\bin\%~nf;1
```
- If building for amd64/x86_64/x64, sometimes the compilation of sources may seem to hang, which
is caused by an optimization issue in the 2008 x64 compiler. You need to use Task Manager to
remove all running instances of `cl.exe`, which will cause the build process to terminate. Update
the build flags of the sources that hang on compilation by changing its `"/O2"` flag to `"/O1"`
in `build.ninja`, and retry the build, where things should continue to build normally. At the
time of writing, this is needed for compiling `glib/gtestutils.c`, `gio/gsettings.c`,
`gio/gsettingsschema.c` and `gio/tests/gsubprocess-testprog.c`
This release of GLib requires at least the Windows 8 SDK in order to be built
successfully using Visual Studio, which means that it is no longer supported to
build GLib with Visual Studio 2008 nor 2010. People that still need to use
Visual Studio 2008 or 2010 should continue to use glib-2.66.x.
......@@ -1104,8 +1104,8 @@ g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
typedef struct
{
gssize bytes_skipped;
gssize count;
gsize bytes_skipped;
gsize count;
} SkipAsyncData;
static void
......@@ -1186,6 +1186,7 @@ skip_fill_buffer_callback (GObject *source_object,
priv->pos += data->count;
}
g_assert (data->bytes_skipped <= G_MAXSSIZE);
g_task_return_int (task, data->bytes_skipped);
}
......@@ -1243,9 +1244,12 @@ g_buffered_input_stream_skip_async (GInputStream *stream,
if (count > priv->len)
{
/* Large request, shortcut buffer */
base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
/* If 'count > G_MAXSSIZE then 'g_input_stream_skip_async()'
* will return an error anyway before calling this.
* Assert that this is never called for too big `count` for clarity. */
g_assert ((gssize) count >= 0);
g_input_stream_skip_async (base_stream,
count,
io_priority, cancellable,
......
......@@ -7057,7 +7057,7 @@ g_file_query_default_handler_finish (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
* @etag_out: (out) (optional): a location to place the current entity tag for the file,
* @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
......@@ -7345,7 +7345,7 @@ g_file_load_partial_contents_async (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
* @etag_out: (out) (optional): a location to place the current entity tag for the file,
* @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
......@@ -7443,7 +7443,7 @@ g_file_load_contents_async (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
* @etag_out: (out) (optional): a location to place the current entity tag for the file,
* @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
......@@ -7481,7 +7481,7 @@ g_file_load_contents_finish (GFile *file,
* or %NULL
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
* @new_etag: (out) (optional): a location to a new [entity tag][gfile-etag]
* @new_etag: (out) (optional) (nullable): a location to a new [entity tag][gfile-etag]
* for the document. This should be freed with g_free() when no longer
* needed, or %NULL
* @cancellable: optional #GCancellable object, %NULL to ignore
......@@ -7789,7 +7789,7 @@ g_file_replace_contents_bytes_async (GFile *file,
* g_file_replace_contents_finish:
* @file: input #GFile
* @res: a #GAsyncResult
* @new_etag: (out) (optional): a location of a new [entity tag][gfile-etag]
* @new_etag: (out) (optional) (nullable): a location of a new [entity tag][gfile-etag]
* for the document. This should be freed with g_free() when it is no
* longer needed, or %NULL
* @error: a #GError, or %NULL
......
......@@ -1733,9 +1733,11 @@ g_file_info_get_content_type (GFileInfo *info)
* g_file_info_get_size:
* @info: a #GFileInfo.
*
* Gets the file's size.
* Gets the file's size (in bytes). The size is retrieved through the value of
* the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted
* from #guint64 to #goffset before returning the result.
*
* Returns: a #goffset containing the file's size.
* Returns: a #goffset containing the file's size (in bytes).
**/
goffset
g_file_info_get_size (GFileInfo *info)
......
......@@ -605,19 +605,24 @@ g_keyfile_settings_backend_finalize (GObject *object)
g_hash_table_unref (kfsb->system_locks);
g_free (kfsb->defaults_dir);
g_file_monitor_cancel (kfsb->file_monitor);
g_object_unref (kfsb->file_monitor);
if (kfsb->file_monitor)
{
g_file_monitor_cancel (kfsb->file_monitor);
g_object_unref (kfsb->file_monitor);
}
g_object_unref (kfsb->file);
g_file_monitor_cancel (kfsb->dir_monitor);
g_object_unref (kfsb->dir_monitor);
if (kfsb->dir_monitor)
{
g_file_monitor_cancel (kfsb->dir_monitor);
g_object_unref (kfsb->dir_monitor);
}
g_object_unref (kfsb->dir);
g_free (kfsb->root_group);
g_free (kfsb->prefix);
G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)
->finalize (object);
G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object);
}
static void
......@@ -724,6 +729,7 @@ static void
g_keyfile_settings_backend_constructed (GObject *object)
{
GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);
GError *error = NULL;
const char *path;
if (kfsb->file == NULL)
......@@ -749,15 +755,31 @@ g_keyfile_settings_backend_constructed (GObject *object)
if (g_mkdir_with_parents (path, 0700) == -1)
g_warning ("Failed to create %s: %s", path, g_strerror (errno));
kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL);
kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL);
kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error);
if (!kfsb->file_monitor)
{
g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
g_clear_error (&error);
}
else
{
g_signal_connect (kfsb->file_monitor, "changed",
G_CALLBACK (file_changed), kfsb);
}
compute_checksum (kfsb->digest, NULL, 0);
kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error);
if (!kfsb->dir_monitor)
{
g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
g_clear_error (&error);
}
else
{
g_signal_connect (kfsb->dir_monitor, "changed",
G_CALLBACK (dir_changed), kfsb);
}
g_signal_connect (kfsb->file_monitor, "changed",
G_CALLBACK (file_changed), kfsb);
g_signal_connect (kfsb->dir_monitor, "changed",
G_CALLBACK (dir_changed), kfsb);
compute_checksum (kfsb->digest, NULL, 0);
g_keyfile_settings_backend_keyfile_writable (kfsb);
g_keyfile_settings_backend_keyfile_reload (kfsb);
......
......@@ -42,8 +42,8 @@ struct _GSubprocessLauncher
gint stderr_fd;
gchar *stderr_path;
GArray *source_fds;
GArray *target_fds; /* always the same length as source_fds */
GArray *source_fds; /* GSubprocessLauncher has ownership of the FD elements */
GArray *target_fds; /* always the same length as source_fds; elements are just integers and not FDs in this process */
gboolean closed_fd;
GSpawnChildSetupFunc child_setup_func;
......
......@@ -596,16 +596,16 @@ g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
* @target_fd: Target descriptor for child process
*
* Transfer an arbitrary file descriptor from parent process to the
* child. This function takes "ownership" of the fd; it will be closed
* child. This function takes ownership of the @source_fd; it will be closed
* in the parent when @self is freed.
*
* By default, all file descriptors from the parent will be closed.
* This function allows you to create (for example) a custom pipe() or
* socketpair() before launching the process, and choose the target
* This function allows you to create (for example) a custom `pipe()` or
* `socketpair()` before launching the process, and choose the target
* descriptor in the child.
*
* An example use case is GNUPG, which has a command line argument
* --passphrase-fd providing a file descriptor number where it expects
* `--passphrase-fd` providing a file descriptor number where it expects
* the passphrase to be written.
*/
void
......@@ -661,11 +661,11 @@ g_subprocess_launcher_close (GSubprocessLauncher *self)
g_assert (self->target_fds != NULL);
g_assert (self->source_fds->len == self->target_fds->len);
/* Note: Don’t close the target_fds, as they’re only valid FDs in the
* child process. This code never executes in the child process. */
for (i = 0; i < self->source_fds->len; i++)
{
(void) close (g_array_index (self->source_fds, int, i));
(void) close (g_array_index (self->target_fds, int, i));
}
(void) close (g_array_index (self->source_fds, int, i));
g_clear_pointer (&self->source_fds, g_array_unref);
g_clear_pointer (&self->target_fds, g_array_unref);
}
......
......@@ -1494,23 +1494,44 @@ test_subprocess_launcher_close (void)
GSubprocessLauncher *launcher;
GSubprocess *proc;
GPtrArray *args;
int fd;
int fd, fd2;
gboolean is_open;
fd = dup(0);
/* Open two arbitrary FDs. One of them, @fd, will be transferred to the
* launcher, and the other’s FD integer will be used as its target FD, giving
* the mapping `fd → fd2` if a child process were to be spawned.
*
* The launcher will then be closed, which should close @fd but *not* @fd2,
* as the value of @fd2 is only valid as an FD in a child process. (A child
* process is not actually spawned in this test.)
*/
fd = dup (0);
fd2 = dup (0);
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
g_subprocess_launcher_take_fd (launcher, fd, fd);
g_subprocess_launcher_take_fd (launcher, fd, fd2);
is_open = fcntl (fd, F_GETFD) != -1;
g_assert_true (is_open);
is_open = fcntl (fd2, F_GETFD) != -1;
g_assert_true (is_open);
g_subprocess_launcher_close (launcher);
is_open = fcntl (fd, F_GETFD) != -1;
g_assert_false (is_open);
is_open = fcntl (fd2, F_GETFD) != -1;
g_assert_true (is_open);
/* Now test that actually trying to spawn the child gives %G_IO_ERROR_CLOSED,
* as g_subprocess_launcher_close() has been called. */
args = get_test_subprocess_args ("cat", NULL);
proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
g_ptr_array_free (args, TRUE);
g_assert_null (proc);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_CLOSED);
g_clear_error (error);
close (fd2);
g_object_unref (launcher);
}
......
......@@ -187,25 +187,28 @@ test_pollable_unix_pty (void)
{
int (*openpty_impl) (int *, int *, char *, void *, void *);
int a, b, status;
#ifdef __linux__
void *handle;
#endif
g_test_summary ("Test that PTYs are considered pollable");
#ifdef __linux__
dlopen ("libutil.so", RTLD_GLOBAL | RTLD_LAZY);
handle = dlopen ("libutil.so", RTLD_GLOBAL | RTLD_LAZY);
#endif
openpty_impl = dlsym (RTLD_DEFAULT, "openpty");
if (openpty_impl == NULL)
{
g_test_skip ("System does not support openpty()");
return;
goto close_libutil;
}
status = openpty_impl (&a, &b, NULL, NULL, NULL);
if (status == -1)
{
g_test_skip ("Unable to open PTY");
return;
goto close_libutil;
}
in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (a, TRUE));
......@@ -218,6 +221,13 @@ test_pollable_unix_pty (void)
close (a);
close (b);
close_libutil:
#ifdef __linux__
dlclose (handle);
#else
return;
#endif
}
static void
......
......@@ -26,6 +26,11 @@
#include <glib/gtypes.h>
#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
/* for glib_typeof */
#include <type_traits>
#endif
G_BEGIN_DECLS
GLIB_AVAILABLE_IN_ALL
......@@ -103,7 +108,7 @@ G_END_DECLS
__atomic_store ((gint *)(atomic), &gais_temp, __ATOMIC_SEQ_CST); \
}))
#if defined(glib_typeof)
#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
......@@ -120,7 +125,7 @@ G_END_DECLS
(void) (0 ? (gpointer) * (atomic) : NULL); \
__atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
}))
#else /* if !defined(glib_typeof) */
#else /* if !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
......@@ -137,7 +142,7 @@ G_END_DECLS
(void) (0 ? (gpointer) *(atomic) : NULL); \
__atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
}))
#endif /* !defined(glib_typeof) */
#endif /* if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68) */
#define g_atomic_int_inc(atomic) \
(G_GNUC_EXTENSION ({ \
......@@ -302,7 +307,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
gapg_result; \
}))
#if defined(glib_typeof)
#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
......@@ -311,7 +316,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
*(atomic) = (glib_typeof (*(atomic))) (gsize) (newval); \
}))
#else /* if !defined(glib_typeof) */
#else /* if !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
......@@ -320,7 +325,7 @@ G_END_DECLS
__asm__ __volatile__ ("" : : : "memory"); \
*(atomic) = (gpointer) (gsize) (newval); \
}))
#endif /* defined(glib_typeof) */
#endif /* if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68) */
#define g_atomic_int_inc(atomic) \
(G_GNUC_EXTENSION ({ \
......@@ -423,7 +428,7 @@ G_END_DECLS
#define g_atomic_int_dec_and_test(atomic) \
(g_atomic_int_dec_and_test ((gint *) (atomic)))
#if defined(glib_typeof)
#if defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)
/* The (void *) cast in the middle *looks* redundant, because
* g_atomic_pointer_get returns void * already, but it's to silence
* -Werror=bad-function-cast when we're doing something like:
......@@ -433,7 +438,7 @@ G_END_DECLS
* non-pointer-typed result. */
#define g_atomic_pointer_get(atomic) \
(glib_typeof (*(atomic))) (void *) ((g_atomic_pointer_get) ((void *) atomic))
#else /* !defined(glib_typeof) */
#else /* !(defined(glib_typeof) && (!defined(glib_typeof_2_68) || GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68)) */
#define g_atomic_pointer_get(atomic) \
(g_atomic_pointer_get (atomic))
#endif
......
......@@ -238,7 +238,12 @@
#define glib_typeof(t) __typeof__ (t)
#elif defined(__cplusplus) && __cplusplus >= 201103L
/* C++11 decltype() is close enough for our usage */
#include <type_traits>
/* This needs `#include <type_traits>`, but we have guarded this feature with a
* `GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68` check, and such a check
* cannot be enforced in this header due to include ordering requirements.
* Within GLib itself, which use `glib_typeof` need to add the include
* themselves. See other examples in GLib for how to do this.
*/
#define glib_typeof(t) typename std::remove_reference<decltype (t)>::type
#define glib_typeof_2_68
#endif
......
......@@ -31,6 +31,11 @@
#include <glib/gutils.h>
#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
/* for glib_typeof */
#include <type_traits>
#endif
G_BEGIN_DECLS
/**
......
......@@ -24,6 +24,11 @@
#include <glib/gmem.h>
#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
/* for glib_typeof */
#include <type_traits>
#endif
G_BEGIN_DECLS
GLIB_AVAILABLE_IN_2_58
......
......@@ -537,10 +537,13 @@ g_rw_lock_clear (GRWLock *rw_lock)
* g_rw_lock_writer_lock:
* @rw_lock: a #GRWLock
*
* Obtain a write lock on @rw_lock. If any thread already holds
* Obtain a write lock on @rw_lock. If another thread currently holds
* a read or write lock on @rw_lock, the current thread will block
* until all other threads have dropped their locks on @rw_lock.
*
* Calling g_rw_lock_writer_lock() while the current thread already
* owns a read or write lock on @rw_lock leads to undefined behaviour.
*
* Since: 2.32
*/
void
......@@ -556,8 +559,9 @@ g_rw_lock_writer_lock (GRWLock *rw_lock)
* g_rw_lock_writer_trylock:
* @rw_lock: a #GRWLock
*
* Tries to obtain a write lock on @rw_lock. If any other thread holds
* a read or write lock on @rw_lock, it immediately returns %FALSE.
* Tries to obtain a write lock on @rw_lock. If another thread
* currently holds a read or write lock on @rw_lock, it immediately
* returns %FALSE.
* Otherwise it locks @rw_lock and returns %TRUE.
*
* Returns: %TRUE if @rw_lock could be locked
......@@ -595,13 +599,19 @@ g_rw_lock_writer_unlock (GRWLock *rw_lock)
* @rw_lock: a #GRWLock
*
* Obtain a read lock on @rw_lock. If another thread currently holds
* the write lock on @rw_lock, the current thread will block. If another thread
* does not hold the write lock, but is waiting for it, it is implementation
* defined whether the reader or writer will block. Read locks can be taken
* the write lock on @rw_lock, the current thread will block until the
* write lock was (held and) released. If another thread does not hold
* the write lock, but is waiting for it, it is implementation defined
* whether the reader or writer will block. Read locks can be taken
* recursively.
*
* It is implementation-defined how many threads are allowed to
* hold read locks on the same lock simultaneously. If the limit is hit,
* Calling g_rw_lock_reader_lock() while the current thread already
* owns a write lock leads to undefined behaviour. Read locks however
* can be taken recursively, in which case you need to make sure to
* call g_rw_lock_reader_unlock() the same amount of times.
*
* It is implementation-defined how many read locks are allowed to be
* held on the same lock simultaneously. If the limit is hit,
* or if a deadlock is detected, a critical warning will be emitted.
*
* Since: 2.32
......
......@@ -28,6 +28,11 @@
#include <gobject/gsignal.h>
#include <gobject/gboxed.h>
#if defined(glib_typeof_2_68) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_68
/* for glib_typeof */
#include <type_traits>
#endif
G_BEGIN_DECLS
/* --- type macros --- */
......
project('glib', 'c', 'cpp',
version : '2.67.4',
version : '2.67.5',
# NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
meson_version : '>= 0.49.2',
default_options : [
......@@ -662,7 +662,7 @@ elif cc.has_function('_snprintf') or cc.has_header_symbol('stdio.h', '_snprintf'
glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF ' + hack_define
endif
if cc.has_function('strcasecmp')
if cc.has_function('strcasecmp', prefix: '#include <strings.h>')
glib_conf.set('HAVE_STRCASECMP', 1)
glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP 1\n'
elif cc.has_function('_stricmp')
......@@ -671,7 +671,7 @@ elif cc.has_function('_stricmp')
glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP ' + hack_define
endif
if cc.has_function('strncasecmp')
if cc.has_function('strncasecmp', prefix: '#include <strings.h>')
glib_conf.set('HAVE_STRNCASECMP', 1)
glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP 1\n'
elif cc.has_function('_strnicmp')
......@@ -2004,9 +2004,15 @@ endif
libm = cc.find_library('m', required : false)
libffi_dep = dependency('libffi', version : '>= 3.0.0', fallback : ['libffi', 'ffi_dep'])
# Don't use the bundled ZLib sources until we are sure that we can't find it on
# the system
libz_dep = dependency('zlib', required : false)
if get_option('wrap_mode') == 'forcefallback'
# Respects "wrap_mode=forcefallback" option
libz_dep = subproject('zlib').get_variable('zlib_dep')
else
# Don't use the bundled ZLib sources until we are sure that we can't find it on
# the system
libz_dep = dependency('zlib', required : false)
endif
if not libz_dep.found()
if cc.get_id() != 'msvc' and cc.get_id() != 'clang-cl'
libz_dep = cc.find_library('z', required : false)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.