diff --git a/.gitignore b/.gitignore
index eda54ed0867910797b5d1b96b8086f45c1bcc58f..744d70fe9092b547608fa22be694026c3b5e963a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,6 @@ tags
*.pc
.*.swp
.sw?
-*.rc
*.gcno
*.gcda
*.gcov
diff --git a/build-aux/meson.build b/build-aux/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..7f3f2ffda33f6904817207cefccde8f22ba8508a
--- /dev/null
+++ b/build-aux/meson.build
@@ -0,0 +1 @@
+subdir('win32')
diff --git a/build-aux/win32/app.c b/build-aux/win32/app.c
new file mode 100644
index 0000000000000000000000000000000000000000..e158c3b4d62e22fdf9fe68ffe4c790da7c948d39
--- /dev/null
+++ b/build-aux/win32/app.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2025 Luca Bacci
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ *
+ * Author: Luca Bacci
+ */
+
+#include "config.h"
+
+#include
+
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER
+#include
+#endif
+
+static void
+set_process_wide_settings (void)
+{
+#if defined (_M_IX86) || defined (__i386__)
+ /* https://learn.microsoft.com/en-us/archive/blogs/michael_howard/faq-about-heapsetinformation-in-windows-vista-and-heap-based-buffer-overruns */
+ /* https://web.archive.org/web/20080825034220/https://blogs.msdn.com/sdl/archive/2008/06/06/corrupted-heap-termination-redux.aspx */
+ HeapSetInformation (NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+
+ /* https://learn.microsoft.com/en-us/archive/blogs/michael_howard/new-nx-apis-added-to-windows-vista-sp1-windows-xp-sp3-and-windows-server-2008 */
+ SetProcessDEPPolicy (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
+#endif
+
+ SetErrorMode (GetErrorMode () | SEM_FAILCRITICALERRORS);
+}
+
+static void
+set_crt_non_interactive (void)
+{
+ /* The Debug CRT may show UI dialogs even in console applications.
+ * Direct to stderr instead.
+ */
+ _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
+
+ _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
+
+ _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
+}
+
+static void
+set_stderr_unbuffered_mode (void)
+{
+ /* MSVCRT.DLL can open stderr in full-buffering mode. That depends on
+ * the type of output device; for example, it's fully buffered for
+ * named pipes but not for console devices.
+ *
+ * Having a fully buffered stderr is not a good default since we can
+ * loose important messages before a crash. Moreover, POSIX forbids
+ * full buffering on stderr. So here we set stderr to unbuffered mode.
+ *
+ * Note: line buffering mode would be good enough, but the Windows C
+ * RunTime library implements it the same as full buffering:
+ *
+ * "for some systems, _IOLBF provides line buffering. However, for
+ * Win32, the behavior is the same as _IOFBF: Full Buffering"
+ *
+ * https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setvbuf#remarks
+ *
+ * References:
+ *
+ * - https://sourceforge.net/p/mingw/mailman/message/27121137/
+ */
+#if !defined (_UCRT)
+ int ret = setvbuf (stderr, NULL, _IONBF, 0);
+ assert (ret == 0);
+#endif
+}
+
+static void
+early_flush_exit_handler (void)
+{
+ /* There are two ways to flush open streams: calling fflush with NULL
+ * argument and calling _flushall. The former flushes output streams
+ * only, the latter flushes both input and output streams.
+ * We should not do anything with input streams here since flushing
+ * means * discarding * data.
+ */
+ fflush (NULL);
+}
+
+static void
+register_early_flush_at_exit (void)
+{
+ /* Implement the two-phase flushing at process exit.
+ *
+ * The C RunTime library flushes open streams within its DllMain handler.
+ * This goes against the rules for DllMain, as each stream is protected
+ * by a lock and locks must not be acquired in DllMain.
+ *
+ * So we flush from app code using an atexit handler. The handler runs when
+ * the application is in a fully working state and thus is completely safe.
+ *
+ * This ensures that all important data is flushed. Anything that is written
+ * after exit will be flushed lately by the C RunTime library (and therefore
+ * may be skipped).
+ *
+ * See comments in "%ProgramFiles(x86)%\Windows Kits\10\Source\\
+ * \ucrt\stdio\fflush.cpp" for more informations.
+ *
+ * References:
+ *
+ * - https://devblogs.microsoft.com/oldnewthing/20070503-00/?p=27003
+ * - https://devblogs.microsoft.com/oldnewthing/20100122-00/?p=15193
+ * - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
+ */
+ int ret = atexit (early_flush_exit_handler);
+ assert (ret == 0);
+}
+
+/* Boilerplate for CRT constructor */
+
+#ifdef _MSC_VER
+static void startup (void);
+
+__pragma (section (".CRT$XCT", long, read))
+
+__declspec (allocate (".CRT$XCT"))
+const void (*ptr_startup) (void) = startup;
+
+#ifdef _M_IX86
+__pragma (comment (linker, "/INCLUDE:" "_ptr_startup"))
+#else
+__pragma (comment (linker, "/INCLUDE:" "ptr_startup"))
+#endif
+#else
+static void __attribute__((constructor)) startup (void);
+#endif
+
+static void
+startup (void)
+{
+ set_crt_non_interactive ();
+ set_process_wide_settings ();
+ set_stderr_unbuffered_mode ();
+ register_early_flush_at_exit ();
+}
diff --git a/build-aux/win32/app.manifest.xml b/build-aux/win32/app.manifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..57ec3d31d00995238687713649f316e71e1fd4e5
--- /dev/null
+++ b/build-aux/win32/app.manifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build-aux/win32/app.rc b/build-aux/win32/app.rc
new file mode 100644
index 0000000000000000000000000000000000000000..ce9785df1ca77f7ea780f07f783ec35a2cc503d3
--- /dev/null
+++ b/build-aux/win32/app.rc
@@ -0,0 +1,6 @@
+#pragma code_page(65001)
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest.xml"
diff --git a/build-aux/win32/lib.rc.in b/build-aux/win32/lib.rc.in
new file mode 100644
index 0000000000000000000000000000000000000000..0dac990ba2e13b365d5ed946da9bdb0a305e254f
--- /dev/null
+++ b/build-aux/win32/lib.rc.in
@@ -0,0 +1,35 @@
+#pragma code_page(65001)
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR@,@MINOR@,@MICRO@,0
+ PRODUCTVERSION @MAJOR@,@MINOR@,@MICRO@,0
+ FILEFLAGSMASK 0
+ FILEFLAGS 0
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "The GLib developer community"
+ VALUE "FileDescription", "@DESCRIPTION@"
+ VALUE "FileVersion", "@MAJOR@.@MINOR@.@MICRO@"
+ VALUE "InternalName", "@NAME@"
+ VALUE "LegalCopyright", "© @COPYRIGHTYEAR@ the GLib developer community. © 1995-2011 Peter Mattis, Spencer Kimball, Josh MacDonald and others."
+ VALUE "OriginalFilename", "@FILENAME@"
+ VALUE "ProductName", "GLib"
+ VALUE "ProductVersion", "@MAJOR@.@MINOR@.@MICRO@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+ END
diff --git a/build-aux/win32/meson.build b/build-aux/win32/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..cf8c56ffa81715b930d5486f03345e767dd1366b
--- /dev/null
+++ b/build-aux/win32/meson.build
@@ -0,0 +1,23 @@
+
+if host_system == 'windows'
+ static_lib = static_library('os-profile-app-static-lib',
+ sources: ['app.c'],
+ include_directories: [configinc])
+
+ resources = windows.compile_resources('app.rc',
+ depend_files: ['app.manifest.xml'])
+
+ app_profile_dep = declare_dependency(link_whole: [static_lib],
+ sources: [resources])
+else
+ app_profile_dep = declare_dependency()
+endif
+
+rc_conf_base = configuration_data({
+ 'MAJOR': major_version,
+ 'MINOR': minor_version,
+ 'MICRO': micro_version,
+ 'COPYRIGHTYEAR': '2025',
+})
+
+lib_rc_in = files('lib.rc.in')
diff --git a/fuzzing/meson.build b/fuzzing/meson.build
index addbe907172539dd8d6c97b86e22974d150e7d6c..a66c2dd2150b9d5880bee4ee87aec17646fe47ae 100644
--- a/fuzzing/meson.build
+++ b/fuzzing/meson.build
@@ -47,7 +47,7 @@ fuzz_targets = [
'fuzz_variant_text',
]
-deps = [libgmodule_dep, libgio_dep, libglib_dep, libgobject_dep]
+deps = [libgmodule_dep, libgio_dep, libglib_dep, libgobject_dep, app_profile_dep]
extra_sources = []
extra_c_args = cc.get_supported_arguments('-Werror=unused-function')
diff --git a/gio/gio.rc.in b/gio/gio.rc.in
deleted file mode 100644
index 3b19b3ee130eb43a77d3ac2e01400ae6a01a53d3..0000000000000000000000000000000000000000
--- a/gio/gio.rc.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- FILEFLAGSMASK 0
- FILEFLAGS 0
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE VFT2_UNKNOWN
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0"
- BEGIN
- VALUE "CompanyName", "The GLib developer community"
- VALUE "FileDescription", "Gio"
- VALUE "FileVersion", "@GLIB_VERSION@.0"
- VALUE "InternalName", "libgio-2.0-@LT_CURRENT_MINUS_AGE@"
- VALUE "LegalCopyright", "Copyright 2006-2011 Red Hat, Inc. and others."
- VALUE "OriginalFilename", "libgio-2.0-@LT_CURRENT_MINUS_AGE@.dll"
- VALUE "ProductName", "GLib"
- VALUE "ProductVersion", "@GLIB_VERSION@"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
- END
diff --git a/gio/meson.build b/gio/meson.build
index 201d2935fd16397b7536564722f294f79aaf27b8..8730291b37476d3ecccdc706cbf23fbd71208c8a 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -426,6 +426,7 @@ if host_system != 'windows'
endif
gio_launch_desktop = executable('gio-launch-desktop', launch_desktop_sources,
+ dependencies: [app_profile_dep],
include_directories : glibinc,
install : true,
install_dir : multiarch_libexecdir,
@@ -473,13 +474,21 @@ else
)
if glib_build_shared
- gio_win_rc = configure_file(
- input: 'gio.rc.in',
+ gio_rc_conf = configuration_data({
+ 'NAME': 'GIO',
+ 'FILENAME': (cc.get_argument_syntax() == 'msvc' ? '' : 'lib') + 'gio-' + glib_api_version + '-' + soversion.to_string() + '.dll',
+ 'DESCRIPTION': 'Gio is a library providing general purpose I/O, networking, IPC, settings, and other high level application functionality',
+ })
+ gio_rc_conf.merge_from(rc_conf_base)
+ lib_rc = configure_file(
+ input: lib_rc_in,
output: 'gio.rc',
- configuration: glibconfig_conf,
+ configuration: gio_rc_conf,
)
- gio_win_res = windows.compile_resources(gio_win_rc)
- win32_sources += [gio_win_res]
+ win32_sources += [windows.compile_resources(lib_rc,
+ # Workaround for https://github.com/llvm/llvm-project/issues/63426
+ args: ['-c', '65001'],
+ )]
endif
gio_win32_include_headers = files(
@@ -1039,14 +1048,14 @@ gio_tool = executable('gio', gio_tool_sources,
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
executable('gresource', 'gresource-tool.c',
install : true,
install_tag : 'bin',
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c',
install : true,
@@ -1055,7 +1064,7 @@ gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodu
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
glib_compile_schemas = executable('glib-compile-schemas',
['glib-compile-schemas.c'],
@@ -1064,7 +1073,7 @@ glib_compile_schemas = executable('glib-compile-schemas',
install_tag : 'bin',
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, gvdb_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, gvdb_dep, app_profile_dep])
glib_compile_resources = executable('glib-compile-resources',
[gconstructor_as_data_h, 'glib-compile-resources.c'],
@@ -1073,7 +1082,7 @@ glib_compile_resources = executable('glib-compile-resources',
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, gvdb_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, gvdb_dep, app_profile_dep])
install_data('gresource.dtd',
install_dir: get_option('datadir') / dtds_subdir,
install_tag: 'devel',
@@ -1094,7 +1103,7 @@ executable('gsettings', 'gsettings-tool.c',
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
install_data('gschema.dtd',
install_dir : get_option('datadir') / schemas_subdir,
install_tag : 'devel',
@@ -1111,7 +1120,7 @@ executable('gdbus', 'gdbus-tool.c',
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
if host_system != 'windows' and not glib_have_cocoa
executable('gapplication', 'gapplication-tool.c',
@@ -1120,7 +1129,7 @@ if host_system != 'windows' and not glib_have_cocoa
c_args : gio_c_args,
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
- dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
+ dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep, app_profile_dep])
endif
if enable_systemtap
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index e719008e472870604c8faade600ff0f681e5d854..efd5e2ff7984368d4a5f50dfcd27c869e383ca27 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -635,7 +635,7 @@ if host_machine.system() != 'windows'
# This test is currently unreliable
executable('gdbus-overflow', 'gdbus-overflow.c',
c_args : test_c_args,
- dependencies : common_gio_tests_deps,
+ dependencies : common_gio_tests_deps + [app_profile_dep],
install_dir : installed_tests_execdir,
install_tag : 'tests',
install : installed_tests_enabled)
@@ -1129,7 +1129,7 @@ foreach program_name, extra_args : test_extra_programs
program_name : executable(program_name,
sources: [source, extra_sources],
c_args : test_c_args,
- dependencies : common_gio_tests_deps + extra_args.get('dependencies', []),
+ dependencies : common_gio_tests_deps + extra_args.get('dependencies', []) + [app_profile_dep],
install_dir : installed_tests_execdir,
install_tag : 'tests',
install : install,
@@ -1168,7 +1168,7 @@ foreach test_name, extra_args : gio_tests
exe = executable(test_name, [source, extra_sources],
c_args : test_c_args + extra_args.get('c_args', []),
cpp_args : test_cpp_args + extra_args.get('cpp_args', []),
- dependencies : common_gio_tests_deps + extra_args.get('dependencies', []),
+ dependencies : common_gio_tests_deps + extra_args.get('dependencies', []) + [app_profile_dep],
install_rpath : extra_args.get('install_rpath', ''),
install_dir: installed_tests_execdir,
install_tag: 'tests',
diff --git a/gio/tests/static-link/meson.build b/gio/tests/static-link/meson.build
index c0b638fe6cf0eed8f4ae1b8b49ac8248016167d4..558840d0e673d4b07da0762645f9466af6d87418 100644
--- a/gio/tests/static-link/meson.build
+++ b/gio/tests/static-link/meson.build
@@ -3,6 +3,9 @@ project('test-static-link', 'c')
# This is a dummy project that static links against installed gio.
# See gio/tests/static-link.py.
app = executable('test-static-link', 'app.c',
- dependencies : dependency('gio-2.0', static : true)
+ dependencies : [
+ dependency('gio-2.0', static : true),
+ app_profile_dep,
+ ]
)
test('test-static-link', app)
diff --git a/girepository/compiler/meson.build b/girepository/compiler/meson.build
index eb704761e2c57c4a78e3fbe141a2c887a13f3d98..c3fce078e1c0bb6e0c8d78c6ad6472f9f76dc055 100644
--- a/girepository/compiler/meson.build
+++ b/girepository/compiler/meson.build
@@ -20,6 +20,7 @@ gicompilerepository = executable('gi-compile-repository', 'compiler.c',
libgirepository_dep,
libgirepository_internals_dep,
libgio_dep,
+ app_profile_dep,
],
install: true,
c_args: custom_c_args,
diff --git a/girepository/decompiler/meson.build b/girepository/decompiler/meson.build
index b6090f61f6b531395be61bb08cac064042b2e119..a2fb904b48bd15b5b94e72d5f10b517b1348e799 100644
--- a/girepository/decompiler/meson.build
+++ b/girepository/decompiler/meson.build
@@ -20,6 +20,7 @@ gidecompiletypelib = executable('gi-decompile-typelib', 'decompiler.c',
libgirepository_dep,
libgirepository_internals_dep,
libgio_dep,
+ app_profile_dep,
],
install: true,
c_args: custom_c_args,
diff --git a/girepository/inspector/meson.build b/girepository/inspector/meson.build
index 4467e6df80b6079d4a55fef3d4a2cdd065dd1ff5..81d43e3eb840fd60561604191ff91bb0d02e6c69 100644
--- a/girepository/inspector/meson.build
+++ b/girepository/inspector/meson.build
@@ -19,6 +19,7 @@ giinspecttypelib = executable('gi-inspect-typelib', 'inspector.c',
dependencies: [
libgirepository_dep,
libgio_dep,
+ app_profile_dep,
],
install: true,
c_args: custom_c_args,
diff --git a/girepository/meson.build b/girepository/meson.build
index b08801891b6b05a3a70fb97284afe1d1113c4b82..3d1793e355a696bf1a966f917b8acd1fb949371c 100644
--- a/girepository/meson.build
+++ b/girepository/meson.build
@@ -225,7 +225,8 @@ executable('gi-dump-types',
dependencies: [
libgirepository_dep,
libgiounix_dep,
- libgiowin32_dep
+ libgiowin32_dep,
+ app_profile_dep,
],
)
diff --git a/girepository/tests/meson.build b/girepository/tests/meson.build
index b804346fb48c0af49e027e6f44df636dfa4841e2..4d3f64a6d3311a9c2c234112cd782d131628e0dc 100644
--- a/girepository/tests/meson.build
+++ b/girepository/tests/meson.build
@@ -96,7 +96,7 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [libm, thread_dep, libgirepository_dep]
+test_deps = [libm, thread_dep, libgirepository_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GIRepository"', '-UG_DISABLE_ASSERT', warning_sign_conversion_args]
test_cpp_args = test_cargs
diff --git a/glib/glib-mirroring-tab/meson.build b/glib/glib-mirroring-tab/meson.build
index 4b14ecf3be80a90b0f222509cabcbabdb58908cc..2900be203d3bc352e8731cc62361f6bd6b675a23 100644
--- a/glib/glib-mirroring-tab/meson.build
+++ b/glib/glib-mirroring-tab/meson.build
@@ -1,5 +1,5 @@
gen_mirroring_tab = executable('gen-mirroring-tab',
['gen-mirroring-tab.c', 'packtab.c'],
- dependencies : [libglib_dep],
+ dependencies : [libglib_dep, app_profile_dep],
install: false,
)
\ No newline at end of file
diff --git a/glib/glib.rc.in b/glib/glib.rc.in
deleted file mode 100644
index c69f644011612c64247acffbd142104ae97f6372..0000000000000000000000000000000000000000
--- a/glib/glib.rc.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- FILEFLAGSMASK 0
- FILEFLAGS 0
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE VFT2_UNKNOWN
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0"
- BEGIN
- VALUE "CompanyName", "The GLib developer community"
- VALUE "FileDescription", "GLib"
- VALUE "FileVersion", "@GLIB_VERSION@.0"
- VALUE "InternalName", "libglib-2.0-@LT_CURRENT_MINUS_AGE@"
- VALUE "LegalCopyright", "Copyright 1995-2011 Peter Mattis, Spencer Kimball, Josh MacDonald and others."
- VALUE "OriginalFilename", "libglib-2.0-@LT_CURRENT_MINUS_AGE@.dll"
- VALUE "ProductName", "GLib"
- VALUE "ProductVersion", "@GLIB_VERSION@"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
- END
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 99d6e4c4dd9d9733db5f511936ca4f56ccc1d8bb..5affaddecdb183a943bfb0c0de1a1d91c292740f 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -205,6 +205,8 @@
* process will inherit the parent's stderr. Otherwise, the child's
* stderr will not be visible, but it will be captured to allow
* later tests with [func@GLib.test_trap_assert_stderr].
+ * @G_TEST_SUBPROCESS_INHERIT_DESCRIPTORS: If this flag is given, the
+ * child process will inherit the parent’s open file descriptors.
*
* Flags to pass to [func@GLib.test_trap_subprocess] to control input and output.
*
@@ -4175,7 +4177,7 @@ g_test_trap_subprocess_with_envp (const char *test_path,
g_ptr_array_add (argv, NULL);
flags = G_SPAWN_DO_NOT_REAP_CHILD;
- if (test_log_fd != -1)
+ if ((test_flags & G_TEST_SUBPROCESS_INHERIT_DESCRIPTORS) || test_log_fd != -1)
flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
if (test_flags & G_TEST_SUBPROCESS_INHERIT_STDIN)
flags |= G_SPAWN_CHILD_INHERITS_STDIN;
diff --git a/glib/gtestutils.h b/glib/gtestutils.h
index 6dae09cf7b113550c7580c07b2a2c469534dfd85..ca9782ae78394c520eb9b07c66bd80cb1eacf427 100644
--- a/glib/gtestutils.h
+++ b/glib/gtestutils.h
@@ -540,7 +540,8 @@ typedef enum {
G_TEST_SUBPROCESS_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0,
G_TEST_SUBPROCESS_INHERIT_STDIN = 1 << 0,
G_TEST_SUBPROCESS_INHERIT_STDOUT = 1 << 1,
- G_TEST_SUBPROCESS_INHERIT_STDERR = 1 << 2
+ G_TEST_SUBPROCESS_INHERIT_STDERR = 1 << 2,
+ G_TEST_SUBPROCESS_INHERIT_DESCRIPTORS GLIB_AVAILABLE_ENUMERATOR_IN_2_88 = 1 << 3,
} G_GNUC_FLAG_ENUM GTestSubprocessFlags;
GLIB_AVAILABLE_IN_2_38
diff --git a/glib/meson.build b/glib/meson.build
index 209bcbfd119b68998ff87b609e00a0e8a55b92f9..8b1ce5c7720198b2a53ff22311e12cc74ecc4a15 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -355,14 +355,23 @@ platform_deps = []
if host_system == 'windows'
if glib_build_shared
- glib_win_rc = configure_file(
- input: 'glib.rc.in',
+ glib_rc_conf = configuration_data({
+ 'NAME': 'GLib',
+ 'FILENAME': (cc.get_argument_syntax() == 'msvc' ? '' : 'lib') + 'glib-' + glib_api_version + '-' + soversion.to_string() + '.dll',
+ 'DESCRIPTION': 'GLib is a general-purpose, portable utility library',
+ })
+ glib_rc_conf.merge_from(rc_conf_base)
+ lib_rc = configure_file(
+ input: lib_rc_in,
output: 'glib.rc',
- configuration: glibconfig_conf,
+ configuration: glib_rc_conf,
)
- glib_win_res = windows.compile_resources(glib_win_rc)
- glib_sources += [glib_win_res]
+ glib_sources += [windows.compile_resources(lib_rc,
+ # Workaround for https://github.com/llvm/llvm-project/issues/63426
+ args: ['-c', '65001'],
+ )]
endif
+
glib_sources += files('gwin32.c', 'gspawn-win32.c', 'giowin32.c')
platform_deps = [winsock2, cc.find_library('winmm')]
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
@@ -496,23 +505,23 @@ if host_system == 'windows'
install : true,
win_subsystem : 'windows',
include_directories : configinc,
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, app_profile_dep])
gspawn_helpers += executable('gspawn-win32-helper-console', 'gspawn-win32-helper.c',
install : true,
c_args : ['-DHELPER_CONSOLE'],
include_directories : configinc,
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, app_profile_dep])
else
gspawn_helpers += executable('gspawn-win64-helper', 'gspawn-win32-helper.c',
install : true,
win_subsystem : 'windows',
include_directories : configinc,
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, app_profile_dep])
gspawn_helpers += executable('gspawn-win64-helper-console', 'gspawn-win32-helper.c',
install : true,
c_args : ['-DHELPER_CONSOLE'],
include_directories : configinc,
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, app_profile_dep])
endif
else
gtester = executable('gtester', 'gtester.c',
@@ -520,7 +529,7 @@ else
install_tag : 'bin-devel',
c_args : ['-UG_DISABLE_ASSERT'],
include_directories : configinc,
- dependencies : [libglib_dep])
+ dependencies : [libglib_dep, app_profile_dep])
# Provide tools for others when we're a subproject and they use the Meson GNOME module
meson.override_find_program('gtester', gtester)
diff --git a/glib/tests/meson.build b/glib/tests/meson.build
index c4fec0c13c08724f4b3dbe55d7c732df35a0fec8..301c06c9d4f2baa9835480c181a967b6b03959e6 100644
--- a/glib/tests/meson.build
+++ b/glib/tests/meson.build
@@ -400,8 +400,8 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [libm, thread_dep, libglib_dep]
-test_deps_static = [libm, thread_dep, libglib_static_dep]
+test_deps = [libm, thread_dep, libglib_dep, app_profile_dep]
+test_deps_static = [libm, thread_dep, libglib_static_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GLib"', '-UG_DISABLE_ASSERT']
test_cpp_args = test_cargs
diff --git a/glib/tests/win32.c b/glib/tests/win32.c
index 5cef08a2e5ec352027c5bc013be07b0ab06b0385..760bf77d59e7b75048d74bef3983628615ecc94f 100644
--- a/glib/tests/win32.c
+++ b/glib/tests/win32.c
@@ -25,8 +25,15 @@
#include
#include
+#include
+
#include
+#include
+#include
+#include
+#include
#include
+#include /* for RTL_OSVERSIONINFO */
#define COBJMACROS
#include
@@ -138,6 +145,267 @@ test_clear_com (void)
CoUninitialize ();
}
+static void
+test_subprocess_stderr_buffering_mode (void)
+{
+ int ret = fprintf (stderr, "hello world\n");
+ g_assert_cmpint (ret, >, 0);
+
+ /* We want to exit without flushing stdio streams. We could
+ * use _Exit here, but the C standard doesn't specify whether
+ * _Exit flushes stdio streams or not.
+ * The Windows C RunTime library doesn't flush streams, but
+ * we should not rely on implementation details which may
+ * change in the future. Use TerminateProcess.
+ */
+ TerminateProcess (GetCurrentProcess (), 0);
+}
+
+static void
+test_stderr_buffering_mode (void)
+{
+ /* MSVCRT.DLL can open stderr in full-buffering mode.
+ * This can cause loss of important messages before
+ * a crash. Additionally, POSIX disallows full buffering
+ * of stderr, so this is not good for portability.
+ * We have a workaround in the app-profile dependency
+ * that we add to each executable.
+ */
+ g_test_trap_subprocess ("/win32/subprocess/stderr-buffering-mode",
+ 0,
+ G_TEST_SUBPROCESS_DEFAULT);
+ g_test_trap_assert_passed ();
+ g_test_trap_assert_stderr ("hello world?\n");
+}
+
+#ifndef _WIN32_WINNT_WIN10
+#define _WIN32_WINNT_WIN10 0x0A00
+#endif
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS 0
+#endif
+
+static void
+test_manifest_os_compatibility (void)
+{
+ const WORD highest_known_major_minor_word = _WIN32_WINNT_WIN10;
+
+ HMODULE module_handle = LoadLibraryEx (L"NTDLL.DLL", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (module_handle == NULL)
+ {
+ g_error ("%s (%s) failed: %s",
+ "LoadLibraryEx", "NTDLL.DLL",
+ g_win32_error_message (GetLastError ()));
+ }
+
+ typedef NTSTATUS (WINAPI *ptr_RtlGetVersion_t) (RTL_OSVERSIONINFOW *);
+
+ ptr_RtlGetVersion_t ptr_RtlGetVersion =
+ (ptr_RtlGetVersion_t) GetProcAddress (module_handle, "RtlGetVersion");
+ if (ptr_RtlGetVersion == NULL)
+ {
+ g_error ("%s (%s, %s) failed: %s",
+ "GetProcAddress", "NTDLL.DLL", "RtlGetVersion",
+ g_win32_error_message (GetLastError ()));
+ }
+
+ /* RtlGetVersion is not subject to compatibility settings
+ * present in the activation context, it always returns
+ * the real OS version.
+ */
+ RTL_OSVERSIONINFOW rtl_os_version_info;
+ rtl_os_version_info.dwOSVersionInfoSize = sizeof (rtl_os_version_info);
+
+ NTSTATUS status = ptr_RtlGetVersion (&rtl_os_version_info);
+ if (status != STATUS_SUCCESS)
+ {
+ g_error ("%s failed",
+ "RtlGetVersion");
+ }
+
+ /* Now verify if the activation context contains up-to-date
+ * compatibility info.
+ */
+ OSVERSIONINFO os_version_info;
+ os_version_info.dwOSVersionInfoSize = sizeof (os_version_info);
+
+ BOOL success = GetVersionEx (&os_version_info);
+ if (!success)
+ {
+ g_error ("%s failed: %s",
+ "GetVersionEx",
+ g_win32_error_message (GetLastError ()));
+ }
+
+ if (rtl_os_version_info.dwMajorVersion != os_version_info.dwMajorVersion ||
+ rtl_os_version_info.dwMinorVersion != os_version_info.dwMinorVersion ||
+ rtl_os_version_info.dwBuildNumber != os_version_info.dwBuildNumber)
+ {
+ WORD rtl_major_minor_word = MAKEWORD ((BYTE)rtl_os_version_info.dwMinorVersion,
+ (BYTE)rtl_os_version_info.dwMajorVersion);
+
+ if (rtl_major_minor_word > highest_known_major_minor_word)
+ g_error ("Please, update the manifest XML and the test's constant");
+
+ g_assert_cmpuint (rtl_os_version_info.dwMajorVersion, ==, os_version_info.dwMajorVersion);
+ g_assert_cmpuint (rtl_os_version_info.dwMinorVersion, ==, os_version_info.dwMinorVersion);
+ g_assert_cmpuint (rtl_os_version_info.dwBuildNumber, ==, os_version_info.dwBuildNumber);
+ }
+
+ FreeLibrary (module_handle);
+}
+
+typedef struct {
+ FILE *stream;
+ bool done;
+ GMutex mutex;
+ GCond cond;
+} StreamLockData_t;
+
+static gpointer
+thread_acquire_stdio_stream_lock (gpointer user_data)
+{
+ StreamLockData_t *data = (StreamLockData_t *) user_data;
+ FILE *stream = data->stream;
+
+ /* For the test to be effective, this thread must be holding
+ * the stream lock when the subprocess "main function" (i.e.
+ * test_subprocess_early_flush) returns.
+ *
+ * This simulates a thread doing I/O on a stream at the time
+ * exit invokes ExitProcess. Note that _lock_file is exactly
+ * what stdio functions call internally.
+ */
+
+ _lock_file (stream);
+
+ g_mutex_lock (&data->mutex);
+ data->done = true;
+ g_cond_signal (&data->cond);
+ g_mutex_unlock (&data->mutex);
+ data = NULL;
+
+ /* Sleep a bit to let the main thread exit. Note: if somehow
+ * the main thread doesn't exit in time, this test will
+ * succeed but won't actually verify anything.
+ */
+ g_usleep (1 * G_USEC_PER_SEC);
+
+ _unlock_file (stream);
+
+ return NULL;
+}
+
+static void
+test_subprocess_early_stdio_flush (void)
+{
+ int64_t fd;
+ FILE *stream;
+ int ret;
+
+ fd = g_ascii_strtoull (g_getenv ("G_TEST_PIPE_FD"), NULL, 10);
+ g_assert_cmpuint (fd, >=, 0);
+ g_assert_cmpuint (fd, <=, INT_MAX);
+
+ stream = _fdopen ((int) fd, "w");
+ g_assert_nonnull (stream);
+
+ ret = setvbuf (stream, NULL, _IOFBF, 1024);
+ g_assert_cmpint (ret, ==, 0);
+
+ ret = fprintf (stream, "hello world");
+ g_assert_cmpint (ret, ==, (int) strlen ("hello world"));
+ g_assert_false (ferror (stream));
+
+ StreamLockData_t data;
+ memset (&data, 0, sizeof (data));
+ data.stream = stream;
+ data.done = false;
+
+ GThread *thread = g_thread_new ("lock stdio stream",
+ thread_acquire_stdio_stream_lock,
+ (gpointer) &data);
+ g_thread_unref (thread);
+
+ /* Wait until the worker thread has acquired the stream lock.
+ */
+ g_mutex_lock (&data.mutex);
+ while (!data.done)
+ g_cond_wait (&data.cond, &data.mutex);
+ g_mutex_unlock (&data.mutex);
+
+ /* If the early flush is not implemented, the C RunTime will attempt
+ * to acquire the stream's internal CRITICAL_SECTION from DllMain.
+ * Then the process will be terminated abruptly (with the same exit
+ * code passed to exit) leaving stream unflushed.
+ */
+}
+
+static gpointer
+thread_read_pipe (gpointer user_data)
+{
+ int fd = GPOINTER_TO_INT (user_data);
+ const char *iter = "hello world";
+ int size = (int) strlen (iter);
+
+ while (size > 0)
+ {
+ char buffer[20];
+ int ret = _read (fd, buffer, sizeof (buffer));
+
+ g_assert_cmpint (ret, >, 0);
+ g_assert_cmpint (ret, <=, size);
+
+ g_assert_cmpmem (buffer, ret, iter, ret);
+
+ iter += ret;
+ size -= ret;
+ }
+
+ return NULL;
+}
+
+static void
+test_early_stdio_flush (void)
+{
+ int pipe_fds[2];
+ int pipe_read;
+ int pipe_write;
+ char buffer[10];
+ GStrv envp = NULL;
+ GError *error = NULL;
+ int ret;
+
+ ret = _pipe (pipe_fds, 1024, _O_BINARY);
+ if (ret < 0)
+ g_error ("%s failed: %s", "_pipe", g_strerror (errno));
+
+ pipe_read = pipe_fds[0];
+ pipe_write = pipe_fds[1];
+
+ g_snprintf (buffer, sizeof (buffer), "%i", pipe_write);
+ envp = g_get_environ ();
+ envp = g_environ_setenv (g_steal_pointer (&envp), "G_TEST_PIPE_FD", buffer, TRUE);
+
+ GThread *thread = g_thread_new ("read pipe",
+ thread_read_pipe,
+ GINT_TO_POINTER (pipe_read));
+
+ typedef const char * const * GStrvConst_t;
+ g_test_trap_subprocess_with_envp ("/win32/subprocess/early-stdio-flush",
+ (GStrvConst_t) envp, 0,
+ G_TEST_SUBPROCESS_INHERIT_DESCRIPTORS);
+ g_test_trap_assert_passed ();
+
+ g_close (pipe_write, &error);
+ g_assert_no_error (error);
+
+ g_thread_join (thread);
+
+ g_close (pipe_read, NULL);
+ g_strfreev (envp);
+}
+
int
main (int argc,
char *argv[])
@@ -161,5 +429,11 @@ main (int argc,
g_test_add_func ("/win32/subprocess/illegal_instruction", test_illegal_instruction);
g_test_add_func ("/win32/com/clear", test_clear_com);
+ g_test_add_func ("/win32/subprocess/stderr-buffering-mode", test_subprocess_stderr_buffering_mode);
+ g_test_add_func ("/win32/stderr-buffering-mode", test_stderr_buffering_mode);
+ g_test_add_func ("/win32/manifest-os-compatibility", test_manifest_os_compatibility);
+ g_test_add_func ("/win32/subprocess/early-stdio-flush", test_subprocess_early_stdio_flush);
+ g_test_add_func ("/win32/early-stdio-flush", test_early_stdio_flush);
+
return g_test_run();
}
diff --git a/gmodule/gmodule.rc.in b/gmodule/gmodule.rc.in
deleted file mode 100644
index c3d762da908308420f435d6d509c4c44175bc4a7..0000000000000000000000000000000000000000
--- a/gmodule/gmodule.rc.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- FILEFLAGSMASK 0
- FILEFLAGS 0
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE VFT2_UNKNOWN
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0"
- BEGIN
- VALUE "CompanyName", "The GLib developer community"
- VALUE "FileDescription", "GModule"
- VALUE "FileVersion", "@GLIB_VERSION@.0"
- VALUE "InternalName", "libgmodule-2.0-@LT_CURRENT_MINUS_AGE@"
- VALUE "LegalCopyright", "Copyright 1998-2011 Tim Janik and others."
- VALUE "OriginalFilename", "libgmodule-2.0-@LT_CURRENT_MINUS_AGE@.dll"
- VALUE "ProductName", "GLib"
- VALUE "ProductVersion", "@GLIB_VERSION@"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
- END
diff --git a/gmodule/meson.build b/gmodule/meson.build
index 37a8fa42d5e5bade394abf4dcebf097a7f522532..5a226319c06e9b5471a99a2767be6a1bc228f8c2 100644
--- a/gmodule/meson.build
+++ b/gmodule/meson.build
@@ -79,13 +79,21 @@ gmodule_visibility_h = custom_target(
gmodule_sources = [gmodule_c, gmodule_visibility_h, gmodule_deprecated_c]
if host_system == 'windows' and glib_build_shared
- gmodule_win_rc = configure_file(
- input: 'gmodule.rc.in',
+ gmodule_rc_conf = configuration_data({
+ 'NAME': 'GModule',
+ 'FILENAME': (cc.get_argument_syntax() == 'msvc' ? '' : 'lib') + 'gmodule-' + glib_api_version + '-' + soversion.to_string() + '.dll',
+ 'DESCRIPTION': 'Portable API for dynamically loading modules',
+ })
+ gmodule_rc_conf.merge_from(rc_conf_base)
+ lib_rc = configure_file(
+ input: lib_rc_in,
output: 'gmodule.rc',
- configuration: glibconfig_conf,
+ configuration: gmodule_rc_conf,
)
- gmodule_win_res = windows.compile_resources(gmodule_win_rc)
- gmodule_sources += [gmodule_win_res]
+ gmodule_sources += [windows.compile_resources(lib_rc,
+ # Workaround for https://github.com/llvm/llvm-project/issues/63426
+ args: ['-c', '65001'],
+ )]
endif
libgmodule = library('gmodule-2.0',
diff --git a/gmodule/tests/meson.build b/gmodule/tests/meson.build
index e7d7b3dd1e150b303252ed59b9ae8463e009eddc..64e6040e06529e8ea7b51aa43542a8f57602abe0 100644
--- a/gmodule/tests/meson.build
+++ b/gmodule/tests/meson.build
@@ -74,7 +74,7 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [libm, thread_dep, libglib_dep, libgmodule_dep]
+test_deps = [libm, thread_dep, libglib_dep, libgmodule_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GModule"', '-UG_DISABLE_ASSERT', warning_sign_conversion_args]
test_cpp_args = test_cargs
diff --git a/gobject/gobject.rc.in b/gobject/gobject.rc.in
deleted file mode 100644
index 1c73e934b20bbe0e04c83c2ccba59f4ca944e853..0000000000000000000000000000000000000000
--- a/gobject/gobject.rc.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- FILEFLAGSMASK 0
- FILEFLAGS 0
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE VFT2_UNKNOWN
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0"
- BEGIN
- VALUE "CompanyName", "The GLib developer community"
- VALUE "FileDescription", "GObject"
- VALUE "FileVersion", "@GLIB_VERSION@.0"
- VALUE "InternalName", "libgobject-2.0-@LT_CURRENT_MINUS_AGE@"
- VALUE "LegalCopyright", "Copyright 1998-2011 Tim Janik, Red Hat, Inc. and others"
- VALUE "OriginalFilename", "libgobject-2.0-@LT_CURRENT_MINUS_AGE@.dll"
- VALUE "ProductName", "GLib"
- VALUE "ProductVersion", "@GLIB_VERSION@"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
- END
diff --git a/gobject/meson.build b/gobject/meson.build
index 91823af79a739e092dec244e59d3a51faea9bf45..54266f32c2ba0d6f65fa470ac536206512ab30ef 100644
--- a/gobject/meson.build
+++ b/gobject/meson.build
@@ -61,13 +61,21 @@ gobject_sources += files(
)
if host_system == 'windows' and glib_build_shared
- gobject_win_rc = configure_file(
- input: 'gobject.rc.in',
+ gobject_rc_conf = configuration_data({
+ 'NAME': 'GObject',
+ 'FILENAME': (cc.get_argument_syntax() == 'msvc' ? '' : 'lib') + 'gobject-' + glib_api_version + '-' + soversion.to_string() + '.dll',
+ 'DESCRIPTION': 'The base type system and object class',
+ })
+ gobject_rc_conf.merge_from(rc_conf_base)
+ lib_rc = configure_file(
+ input: lib_rc_in,
output: 'gobject.rc',
- configuration: glibconfig_conf,
+ configuration: gobject_rc_conf,
)
- gobject_win_res = windows.compile_resources(gobject_win_rc)
- gobject_sources += [gobject_win_res]
+ gobject_sources += [windows.compile_resources(lib_rc,
+ # Workaround for https://github.com/llvm/llvm-project/issues/63426
+ args: ['-c', '65001'],
+ )]
endif
if enable_dtrace
@@ -171,7 +179,7 @@ meson.override_dependency('gobject-2.0', libgobject_dep)
gobject_query = executable('gobject-query', 'gobject-query.c',
install : true,
install_tag : 'bin-devel',
- dependencies : [libglib_dep, libgobject_dep])
+ dependencies : [libglib_dep, libgobject_dep, app_profile_dep])
install_data('gobject_gdb.py',
install_dir : glib_pkgdatadir / 'gdb',
diff --git a/gobject/tests/meson.build b/gobject/tests/meson.build
index 214df48459a04ae91a46900544fe6b8cb15ef12e..e26acf12748615763fd3a6bd515e2a1761eb239c 100644
--- a/gobject/tests/meson.build
+++ b/gobject/tests/meson.build
@@ -28,35 +28,10 @@ marshalers_c = custom_target('marshalers_c',
],
)
-# We must embed custom-dispatch.exe with an application
-# manifest to pacify UAC in order to run on 32-bit Windows
-# builds, otherwise the test will not run as UAC will kill it.
-extra_custom_dispatch_objs = []
-if embed_uac_manifest
- uac_exe_pkg = 'gobject'
- uac_exe_name = 'custom-dispatch'
-
- # Well, we have to forgo the xxx.exe.manifest in the output listing, since
- # compile_resources doesn't like to consume targets with multiple outputs,
- # and the xxx.exe.manifest and xxx.rc are tied together
- uac_rc = custom_target(
- '@0@.rc'.format(uac_exe_name),
- output: ['@0@.rc'.format(uac_exe_name)],
- command: [gen_uac_manifest,
- '-p=@0@'.format(uac_exe_pkg),
- '-n=@0@'.format(uac_exe_name),
- '--pkg-version=@0@'.format(meson.project_version()),
- '--output-dir=@OUTDIR@'],
- )
- extra_custom_dispatch_objs = import('windows').compile_resources(uac_rc)
-endif
-
gobject_tests = {
'notify-init' : {},
'notify-init2' : {},
- 'custom-dispatch' : {
- 'extra_objs' : extra_custom_dispatch_objs,
- },
+ 'custom-dispatch' : {},
'qdata' : {},
'accumulator' : {
'source' : ['accumulator.c', marshalers_h, marshalers_c],
@@ -178,13 +153,12 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [libm, thread_dep, libglib_dep, libgobject_dep]
+test_deps = [libm, thread_dep, libglib_dep, libgobject_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GLib-GObject"', '-UG_DISABLE_ASSERT', warning_sign_conversion_args]
test_cpp_args = test_cargs
foreach test_name, extra_args : gobject_tests
source = extra_args.get('source', test_name + '.c')
- extra_objs = extra_args.get('extra_objs', [])
install = installed_tests_enabled and extra_args.get('install', true)
if install
@@ -201,7 +175,7 @@ foreach test_name, extra_args : gobject_tests
)
endif
- exe = executable(test_name, source, extra_objs,
+ exe = executable(test_name, source,
c_args : test_cargs + extra_args.get('c_args', []),
cpp_args : test_cpp_args + extra_args.get('cpp_args', []),
dependencies : test_deps + extra_args.get('dependencies', []),
diff --git a/gobject/tests/performance/meson.build b/gobject/tests/performance/meson.build
index 0147f7c85e79c517c449116eb79207513ddbb8ac..ae1a2094338cdee7efe744546a2b023c665e343e 100644
--- a/gobject/tests/performance/meson.build
+++ b/gobject/tests/performance/meson.build
@@ -11,7 +11,7 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [libm, thread_dep, libglib_dep, libgobject_dep]
+test_deps = [libm, thread_dep, libglib_dep, libgobject_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GLib-GObject"', '-UG_DISABLE_ASSERT']
foreach test_name, extra_args : gobject_tests
diff --git a/gthread/gthread.rc.in b/gthread/gthread.rc.in
deleted file mode 100644
index 9e45fdff9581f55c2e2f68efc56d2e52208dd8b1..0000000000000000000000000000000000000000
--- a/gthread/gthread.rc.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#include
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
- FILEFLAGSMASK 0
- FILEFLAGS 0
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE VFT2_UNKNOWN
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0"
- BEGIN
- VALUE "CompanyName", "The GLib developer community"
- VALUE "FileDescription", "GThread"
- VALUE "FileVersion", "@GLIB_VERSION@.0"
- VALUE "InternalName", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@"
- VALUE "LegalCopyright", "Copyright 1995-2011 Peter Mattis, Spencer Kimball, Josh MacDonald, Sebastian Wilhelmi and others."
- VALUE "OriginalFilename", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@.dll"
- VALUE "ProductName", "GLib"
- VALUE "ProductVersion", "@GLIB_VERSION@"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
- END
diff --git a/gthread/meson.build b/gthread/meson.build
index 9b492eed64eb24d7ffad73d16aa9a085485d5cee..62fbe47fb51601149088fef021d250d09fb97d07 100644
--- a/gthread/meson.build
+++ b/gthread/meson.build
@@ -3,13 +3,21 @@
gthread_sources = ['gthread-impl.c']
if host_system == 'windows' and glib_build_shared
- gthread_win_rc = configure_file(
- input: 'gthread.rc.in',
+ gthread_rc_conf = configuration_data({
+ 'NAME': 'GThread',
+ 'FILENAME': (cc.get_argument_syntax() == 'msvc' ? '' : 'lib') + 'gthread-' + glib_api_version + '-' + soversion.to_string() + '.dll',
+ 'DESCRIPTION': 'Portable threading API',
+ })
+ gthread_rc_conf.merge_from(rc_conf_base)
+ lib_rc = configure_file(
+ input: lib_rc_in,
output: 'gthread.rc',
- configuration: glibconfig_conf,
+ configuration: gthread_rc_conf,
)
- gthread_win_res = windows.compile_resources(gthread_win_rc)
- gthread_sources += [gthread_win_res]
+ gthread_sources += [windows.compile_resources(lib_rc,
+ # Workaround for https://github.com/llvm/llvm-project/issues/63426
+ args: ['-c', '65001'],
+ )]
endif
libgthread = library('gthread-2.0',
diff --git a/gthread/tests/meson.build b/gthread/tests/meson.build
index 66b50caf76b7907563757623d44c2db6e7640c6f..ebb67929c95f74740426324357de2103c5633e1e 100644
--- a/gthread/tests/meson.build
+++ b/gthread/tests/meson.build
@@ -6,7 +6,7 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_deps = [thread_dep, libglib_dep, libgthread_dep]
+test_deps = [thread_dep, libglib_dep, libgthread_dep, app_profile_dep]
test_cargs = ['-DG_LOG_DOMAIN="GLib-GThread"', '-UG_DISABLE_ASSERT', warning_sign_conversion_args]
test_cpp_args = test_cargs
diff --git a/meson.build b/meson.build
index f30ca58066951c8c7a92ce37c707d309b1a00d77..f6b9f5135d1d5bdb37bf7f936fcf10444d49711e 100644
--- a/meson.build
+++ b/meson.build
@@ -2717,6 +2717,7 @@ pkg = import('pkgconfig')
windows = import('windows')
gnome = import('gnome')
+subdir('build-aux')
subdir('tools')
subdir('glib')
subdir('gobject')
diff --git a/tools/generate-uac-manifest.py b/tools/generate-uac-manifest.py
deleted file mode 100644
index a99f0a92f781c337f20743cbad53e7f2473bcddd..0000000000000000000000000000000000000000
--- a/tools/generate-uac-manifest.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright © 2021 Chun-wei Fan.
-#
-# SPDX-License-Identifier: LGPL-2.1-or-later
-#
-# Original author: Chun-wei Fan
-
-"""
-This script generates a Windows manifest file and optionally a resource file to
-determine whether a specified program requires UAC elevation
-"""
-
-import os
-import argparse
-
-DOMAIN_NAME = "gnome"
-
-
-def main():
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument(
- "-p", "--package", required=True, help="package name of the executable"
- )
- parser.add_argument("-n", "--name", required=True, help="name of executable")
- parser.add_argument(
- "--pkg-version", required=True, dest="version", help="version of package"
- )
- parser.add_argument(
- "--require-admin",
- action="store_true",
- dest="admin",
- default=False,
- help="require admin access to application",
- )
- parser.add_argument(
- "--input-resource-file",
- dest="resource",
- default=None,
- help="existing .rc file to embed UAC manifest (do not generate a new .rc file), must have included windows.h in it",
- )
- parser.add_argument(
- "--output-dir",
- dest="outdir",
- default=None,
- help="directory to output resulting files",
- )
- args = parser.parse_args()
-
- if args.resource is not None:
- if not os.path.isfile(args.resource):
- raise FileNotFoundError(
- "Specified resource file '%s' does not exist" % args.resource
- )
-
- generate_manifest(args.package, args.name, args.version, args.admin, args.outdir)
- write_rc_file(args.name, args.resource, args.outdir)
-
-
-def generate_manifest(package, name, version, admin, outdir):
- if version.count(".") == 0:
- manifest_package_version = version + ".0.0.0"
- elif version.count(".") == 1:
- manifest_package_version = version + ".0.0"
- elif version.count(".") == 2:
- manifest_package_version = version + ".0"
- elif version.count(".") == 3:
- manifest_package_version = version
- else:
- parts = version.split(".")
- manifest_package_version = ""
- for x in (0, 1, 2, 3):
- if x == 0:
- manifest_package_version += parts[x]
- else:
- manifest_package_version += "." + parts[x]
-
- if outdir is not None:
- output_file_base_name = os.path.join(outdir, name)
- else:
- output_file_base_name = name
-
- outfile = open(output_file_base_name + ".exe.manifest", "w+")
- outfile.write("\n")
- outfile.write(
- "\n"
- )
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write(" \n")
- outfile.write("\n")
- outfile.close()
-
-
-def write_rc_file(name, resource, outdir):
- if outdir is not None:
- output_file_base_name = os.path.join(outdir, name)
- else:
- output_file_base_name = name
-
- if resource is None:
- outfile = open(output_file_base_name + ".rc", "w+")
- outfile.write("#define WIN32_LEAN_AND_MEAN\n")
- outfile.write("#include \n")
- else:
- if resource != output_file_base_name + ".rc":
- outfile = open(output_file_base_name + ".rc", "w+")
- else:
- outfile = open(output_file_base_name + ".final.rc", "w+")
- srcfile = open(resource, "r")
- outfile.write(srcfile.read())
- srcfile.close()
-
- outfile.write("\n")
- outfile.write(
- 'CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "%s.exe.manifest"' % name
- )
- outfile.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/tools/meson.build b/tools/meson.build
index 257312ebf93fc6c04aa4ecd503cef4181b4bff69..e80d4be982541072840dbb285f4caca8c02fba6c 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -24,11 +24,3 @@ if host_system != 'windows'
endif
gen_visibility_macros = find_program('gen-visibility-macros.py')
-
-# This is only needed for 32-bit (x86) Windows builds
-if host_system == 'windows' and host_machine.cpu_family() == 'x86'
- embed_uac_manifest = true
- gen_uac_manifest = find_program('generate-uac-manifest.py')
-else
- embed_uac_manifest = false
-endif