Fix ABI breakage for versioned symbols in 3.2.7

Add 3.2 versions of the symbols whose version was "fixed" in ed7defadd2
(Fix multiple errors in the version script, 2025-01-01), breaking ABI as
they were not available in their old version any more.

Add wxELF_VERSION() macro which allows to define the symbol with the
given ELF version and use it, in conjunction with the existing version
in the version script, to have both WXU_3.2.N and WXU_3.2 versions of
all the symbols affected by the changes in that commit.

Closes #25327.
This commit is contained in:
Vadim Zeitlin
2025-04-15 02:23:32 +02:00
parent ed70ea9e98
commit f3eb19ce2e
7 changed files with 79 additions and 18 deletions
+1
View File
@@ -257,6 +257,7 @@ All:
- Allow initializing wxVector<> from std::initializer_list<> (#25290).
- Update Brazilian Portuguese translations (Felipe).
- Ensure that all headers are installed by CMake (Maarten Bent, #25266).
- Fix ABI breakage for versioned symbols in 3.2.7 under Unix (#25327).
All (GUI):
+58
View File
@@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/elfversion.h
// Purpose: Helper macro for assigning ELF version to a symbol.
// Author: Vadim Zeitlin
// Created: 2025-04-14
// Copyright: (c) 2025 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_ELFVERSION_H_
#define _WX_PRIVATE_ELFVERSION_H_
// We suppose that if version script is supported, then .symver assembler
// directive is also supported.
#ifdef wxHAVE_VERSION_SCRIPT
// Prefer to use the attribute if it is available, as it works with LTO,
// unlike the assembler directive.
#ifdef __has_attribute
#if __has_attribute(__symver__)
#define wxELF_SYMVER(sym, symver) __attribute__((__symver__(symver)))
#endif
#endif
#ifndef wxELF_SYMVER
#define wxELF_SYMVER(sym, symver) __asm__(".symver " sym "," symver);
#endif
// Our version tag depends on whether we're using Unicode or not.
#if wxUSE_UNICODE
#define wxMAKE_ELF_VERSION_TAG(ver) "WXU_" ver
#else
#define wxMAKE_ELF_VERSION_TAG(ver) "WX_" ver
#endif
// This macro is used to repair ABI compatibility problems with the symbols
// versions: unfortunately, some symbols were initially added with the
// wrong "3.2" version tag because their definitions in the version script
// were erroneous, and, even more unfortunately, they were later corrected
// to use a different version tag, which made the symbols with the old
// version unavailable in the shared library. This macro allows to define
// both the old, compatible version ("3.2") and the new ("3.2.N") one for
// the given symbol to restore ABI compatibility with the previous releases
// without breaking it with the release containing the corrected version.
//
// The parameters are the mangled symbol name (the simplest way to get is
// probably to use nm or readelf on the object file or library) and the
// part of the version after "WX[U]_", i.e. the version number itself.
//
// Note that this macro takes strings, not symbols, and that it includes
// the trailing semicolon for consistency with the empty version below.
#define wxELF_VERSION_COMPAT(sym, ver) \
wxELF_SYMVER(sym, sym "@" wxMAKE_ELF_VERSION_TAG("3.2")) \
wxELF_SYMVER(sym, sym "@@" wxMAKE_ELF_VERSION_TAG(ver))
#else
#define wxELF_VERSION_COMPAT(sym, ver)
#endif
#endif // _WX_PRIVATE_ELFVERSION_H_
+5
View File
@@ -49,6 +49,8 @@
#include "wx/private/threadinfo.h"
#include "wx/uilocale.h"
#include "wx/private/elfversion.h"
#ifdef __WINDOWS__
#include "wx/dynlib.h"
#include "wx/scopedarray.h"
@@ -1420,11 +1422,13 @@ bool wxTranslations::AddCatalog(const wxString& domain,
}
#endif // !wxUSE_UNICODE
wxELF_VERSION_COMPAT("_ZN14wxTranslations19AddAvailableCatalogERK8wxString", "3.2.3")
bool wxTranslations::AddAvailableCatalog(const wxString& domain)
{
return AddAvailableCatalog(domain, wxLANGUAGE_ENGLISH_US);
}
wxELF_VERSION_COMPAT("_ZN14wxTranslations19AddAvailableCatalogERK8wxString10wxLanguage", "3.2.6")
bool wxTranslations::AddAvailableCatalog(const wxString& domain, wxLanguage msgIdLanguage)
{
return DoAddCatalog(domain, msgIdLanguage) == Translations_Found;
@@ -1563,6 +1567,7 @@ wxString wxTranslations::GetBestTranslation(const wxString& domain,
return lang;
}
wxELF_VERSION_COMPAT("_ZN14wxTranslations27GetBestAvailableTranslationERK8wxString", "3.2.3")
wxString wxTranslations::GetBestAvailableTranslation(const wxString& domain)
{
// Determine the best language from the ones with actual translation file:
+4
View File
@@ -32,6 +32,7 @@
#include "wx/language.h"
#endif
#include "wx/private/elfversion.h"
#include "wx/private/uilocale.h"
#define TRACE_I18N wxS("i18n")
@@ -612,6 +613,7 @@ wxString wxUILocale::GetLocalizedName(wxLocaleName name, wxLocaleForm form) cons
}
#if wxUSE_DATETIME
wxELF_VERSION_COMPAT("_ZNK10wxUILocale12GetMonthNameEN10wxDateTime5MonthENS0_9NameFlagsE", "3.2.3")
wxString wxUILocale::GetMonthName(wxDateTime::Month month, wxDateTime::NameFlags flags) const
{
if (!m_impl)
@@ -620,6 +622,7 @@ wxString wxUILocale::GetMonthName(wxDateTime::Month month, wxDateTime::NameFlags
return m_impl->GetMonthName(month, flags);
}
wxELF_VERSION_COMPAT("_ZNK10wxUILocale14GetWeekDayNameEN10wxDateTime7WeekDayENS0_9NameFlagsE", "3.2.3")
wxString wxUILocale::GetWeekDayName(wxDateTime::WeekDay weekday, wxDateTime::NameFlags flags) const
{
if (!m_impl)
@@ -677,6 +680,7 @@ wxUILocale::~wxUILocale()
/* static */
wxELF_VERSION_COMPAT("_ZN10wxUILocale17GetSystemLocaleIdEv", "3.2.2")
wxLocaleIdent wxUILocale::GetSystemLocaleId()
{
wxUILocale defaultLocale(wxUILocaleImpl::CreateUserDefault());
+3
View File
@@ -32,6 +32,8 @@
#include "wx/filefn.h" // ::wxGetCwd
#include "wx/modalhook.h"
#include "wx/private/elfversion.h"
//-----------------------------------------------------------------------------
// "clicked" for OK-button
//-----------------------------------------------------------------------------
@@ -500,6 +502,7 @@ void wxFileDialog::GTKSelectionChanged(const wxString& filename)
UpdateExtraControlUI();
}
wxELF_VERSION_COMPAT("_ZN12wxFileDialog11AddShortcutERK8wxStringi", "3.2.1")
bool wxFileDialog::AddShortcut(const wxString& directory, int WXUNUSED(flags))
{
wxGtkError error;
+4
View File
@@ -28,6 +28,8 @@
#include "wx/scopedptr.h"
#include "wx/private/elfversion.h"
#include "wx/gtk/private/wrapgdk.h"
#include "wx/gtk/private/backend.h"
#ifdef GDK_WINDOWING_WAYLAND
@@ -633,6 +635,7 @@ wxGLCanvasEGL::~wxGLCanvasEGL()
gs_alreadySetSwapInterval.erase(this);
}
wxELF_VERSION_COMPAT("_ZN13wxGLCanvasEGL23CreateWaylandSubsurfaceEv", "3.2.3")
void wxGLCanvasEGL::CreateWaylandSubsurface()
{
#ifdef GDK_WINDOWING_WAYLAND
@@ -671,6 +674,7 @@ void wxGLCanvasEGL::CreateWaylandSubsurface()
#endif
}
wxELF_VERSION_COMPAT("_ZN13wxGLCanvasEGL24DestroyWaylandSubsurfaceEv", "3.2.3")
void wxGLCanvasEGL::DestroyWaylandSubsurface()
{
#ifdef GDK_WINDOWING_WAYLAND
+4 -18
View File
@@ -18,9 +18,10 @@
# };
#
# If a symbols should have been added in this way, but is forgotten then it
# cannot be added in the next release. This is because it has already been
# released with the generic branch version due to the final wildcard below,
# and once released its version cannot be changed.
# cannot be added to the next release version tag, but we can workaround the
# problem by using wxELF_VERSION_COMPAT() macro in the source code. Note that
# this is why some version tags are defined here even if no symbols are
# assigned to them: they are used by that macro.
# When adding a new section here, don't forget to modify the version in
# build/bakefiles/version.bkl to indicate that new APIs have been added and
@@ -36,35 +37,20 @@
# public symbols added in 3.2.6 (please keep in alphabetical order):
@WX_VERSION_TAG@.6 {
extern "C++" {
"wxTranslations::AddAvailableCatalog(wxString const&, wxLanguage)";
};
};
# public symbols added in 3.2.3 (please keep in alphabetical order):
@WX_VERSION_TAG@.3 {
extern "C++" {
"wxGLCanvasEGL::CreateWaylandSubsurface()";
"wxGLCanvasEGL::DestroyWaylandSubsurface()";
"wxTranslations::AddAvailableCatalog(wxString const&)";
"wxTranslations::GetBestAvailableTranslation(wxString const&)";
"wxUILocale::GetMonthName(wxDateTime::Month, wxDateTime::NameFlags) const";
"wxUILocale::GetWeekDayName(wxDateTime::WeekDay, wxDateTime::NameFlags) const";
};
};
# public symbols added in 3.2.2 (please keep in alphabetical order):
@WX_VERSION_TAG@.2 {
extern "C++" {
"wxUILocale::GetSystemLocaleId()";
};
};
# public symbols added in 3.2.1
@WX_VERSION_TAG@.1 {
extern "C++" {
"wxApp::GTKAllowDiagnosticsControl()";
"wxFileDialogBase::AddShortcut(wxString const&, int)";
};
};