From c217e8c21f65188944904deabfee1571a2ff5009 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Fri, 5 Jul 2024 01:50:05 +0900 Subject: [PATCH] vk_entrypoints_gen: Rework ATTR_WEAK to unify Unix and MinGW The way ATTR_WEAK works is changed to eliminate the "don't declare as weak on MinGW" weirdness. When a weak is not undefined, MinGW requires the definition to be a regular symbol. Instead of declaring as weak everywhere, we now declare the symbol as a regular by default, and only make it weak when it needs to fallback to NULL when undefined, which is only needed for the dispatch table. This unifies the approach for Unix and MinGW. The name ATTR_WEAK is changed to VK_ENTRY_WEAK since it's now controlled by the entrypoint specific VK_ENTRY_USE_WEAK flag. Reviewed-by: Mike Blumenkrantz Part-of: --- src/vulkan/util/vk_entrypoints_gen.py | 30 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/vulkan/util/vk_entrypoints_gen.py b/src/vulkan/util/vk_entrypoints_gen.py index 74502149104..d665ab6b293 100644 --- a/src/vulkan/util/vk_entrypoints_gen.py +++ b/src/vulkan/util/vk_entrypoints_gen.py @@ -49,11 +49,20 @@ extern "C" { #endif % endif -/* clang wants function declarations in the header to have weak attribute */ -#if !defined(_MSC_VER) && !defined(__MINGW32__) -#define ATTR_WEAK __attribute__ ((weak)) +/* Entrypoint symbols are optional, and resolves to NULL if undefined. + * On Unix, this semantics is achieved through weak symbols. + * Note that we only declare the symbols as weak when it needs to be optional; + * otherwise, the symbol is declared as a regular symbol. + * This is to workaround a MinGW limitation: on MinGW, the definition for a + * weak symbol must be regular, or the linker will end up resolving to one of + * the fallback symbols with the absolute value of 0. + * On MSVC, weak symbols are not well supported, so we use the functionally + * equivalent /alternatename. + */ +#if !defined(_MSC_VER) && defined(VK_ENTRY_USE_WEAK) +#define VK_ENTRY_WEAK __attribute__ ((weak)) #else -#define ATTR_WEAK +#define VK_ENTRY_WEAK #endif % for p in instance_prefixes: @@ -78,7 +87,7 @@ extern const struct vk_device_entrypoint_table ${tmpl_prefix}_device_entrypoints #ifdef ${e.guard} % endif % for p in physical_device_prefixes: - VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) ATTR_WEAK; + VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) VK_ENTRY_WEAK; % endfor % if e.guard is not None: #endif // ${e.guard} @@ -90,7 +99,7 @@ extern const struct vk_device_entrypoint_table ${tmpl_prefix}_device_entrypoints #ifdef ${e.guard} % endif % for p in physical_device_prefixes: - VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) ATTR_WEAK; + VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) VK_ENTRY_WEAK; % endfor % if e.guard is not None: #endif // ${e.guard} @@ -102,7 +111,7 @@ extern const struct vk_device_entrypoint_table ${tmpl_prefix}_device_entrypoints #ifdef ${e.guard} % endif % for p in device_prefixes: - VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) ATTR_WEAK; + VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) VK_ENTRY_WEAK; % endfor % if tmpl_prefix: @@ -131,6 +140,11 @@ extern const struct vk_device_entrypoint_table ${tmpl_prefix}_device_entrypoints TEMPLATE_C = Template(COPYRIGHT + """ /* This file generated from ${filename}, don't edit directly. */ +/* This file is the only place we rely on undefined symbols to fall back to + * NULL. Other files use regular symbol declarations. + * See also comments on VK_ENTRY_WEAK. + */ +#define VK_ENTRY_USE_WEAK 1 #include "${header}" /* Weak aliases for all potential implementations. These will resolve to @@ -161,8 +175,6 @@ TEMPLATE_C = Template(COPYRIGHT + """ #endif #endif #else - VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) __attribute__ ((weak)); - % if entrypoints == device_entrypoints: % for v in tmpl_variants: extern template