backport of r58600

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@58601 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-02-01 17:19:25 +00:00
parent 66ddd74d23
commit a00dee1c36
2 changed files with 97 additions and 14 deletions

View File

@@ -3,13 +3,13 @@
0. Purpose
----------
This is broad technote covering all aspects of binary compatibility with
This is a broad technote covering all aspects of binary compatibility with
wxWidgets.
1. Releases
-----------
General overview of releases can be found in tn0012.txt, but for
General overview of releases can be found in tn0012.txt, but for
completeness the wxWidgets release version number is as follows:
2.6.2
@@ -37,12 +37,12 @@ also section (4).
-------------------------------------------------
If its still up, the KDE guide is a good reference:
http://developer.kde.org/documentation/other/binarycompatibility.html
http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
The changes that are NOT binary compatible:
- Adding a virtual function
- Changing the name of a any function or variable
- Changing the signature of a virtual function (adding a parameter,
- Changing the signature of a virtual function (adding a parameter,
even a default one)
- Changing the order of the virtual functions in a class
["switching" them, etc.]
@@ -63,6 +63,7 @@ even a default one)
- Adding a new class
- Adding a new non-virtual method to an existing class
- Adding a new constructor to an existing class
- Overriding the implementation of an existing virtual function
[this is considered to be backwards binary compatible until we find a
counter example; currently it's known to work with Apple gcc at least]
@@ -113,7 +114,7 @@ bool ShowPlayerControls(
//helpers for the wxPython people
bool LoadURI(const wxString& fileName)
{ return Load(wxURI(fileName)); }
bool LoadURIWithProxy(const wxString& fileName, const wxString& proxy)
bool LoadURIWithProxy(const wxString& fileName, const wxString& proxy)
{ return Load(wxURI(fileName), wxURI(proxy)); }
#endif
@@ -139,7 +140,7 @@ wxShadowObject resides in include/wx/clntdata.h.
To use wxShadowObject, you first call AddMethod or AddField with
the first parameter being the name of the field and/or method
you want, and the second parameter being the value of the
you want, and the second parameter being the value of the
field and/or method.
In the case of fields this is a void*, and in the case of method
@@ -150,15 +151,15 @@ After you add a field, you can set it via SetField with the same
parameters as AddField, the second parameter being the value to set
the field to. You can get the field after you call AddField
via GetField, with the parameters as the other two field functions,
only in the case the second parameter is the fallback
value for the field in the case of it not being found in the
hash map.
only in the case the second parameter is the fallback
value for the field in the case of it not being found in the
hash map.
You can call a method after you add it via InvokeMethod, which
returns a bool indicating whether or not the method was found
in the hash map, and has 4 parameters. The first parameter is
the name of the method you wish to call, the second is the first
parameter passed to the wxShadowObjectMethod, the third is the
parameter passed to the wxShadowObjectMethod, the third is the
second parameter passed to that wxShadowObjectMethod, and the
fourth is the return value of the wxShadowObjectMethod.
@@ -183,7 +184,7 @@ The file has the layout as follows:
Where X is the current Release as mentioned earlier, i.e. 2. This
is following by an opening bracket "{", followed by "global:",
followed by patterns matching added symbols, then followed by "}", and then
the file is either followed by earlier Releases or ended by
the file is either followed by earlier Releases or ended by
a @WX_VERSION_TAG@ block without the period or Release.
The patterns used to specify added symbols are globbing patters and can
@@ -270,10 +271,15 @@ binary compatibility between those releases.
You can also break into your debugger or whatever program you want
to use and check the memory layout of the class. If it is the same
then it is binary compatible.
(In GDB the command x/d will show addresses as pointers to functions if
possible so you can see if the order of the functions in vtbl doesn't change.)
Also remember to look at http://www.wxwidgets.org/bincompat.html page which
summarizes the results of testing of all the samples built against old
libraries headers with the new library binaries under Unix.
Another way to check for binary compatibility is to build wxWidgets in shared mode
and use the 'abicheck.sh --generate' script before doing your changes to generate
the current ABI (if the 'expected_abi' file is not already in the repo).
Then rebuild wxWidgets with your changes and use 'abicheck.sh' to compare the
resulting ABI with the expected one.
Note that the abicheck.sh script is in the "lib" folder.
=== EOF ===

77
lib/abicheck.sh Executable file
View File

@@ -0,0 +1,77 @@
#!/bin/bash
# Script originally based on GTK+'s own abicheck.sh; it should be run anytime
# there is a change in the stable branch of wxWidgets which could lead to an
# ABI breakage and thus result in a binary-incompatible change (see tech docs).
#
# $Id$
expected_abi_file="expected_abi"
actual_abi_file="actual_abi"
if [[ "$1" == "--generate" ]]; then
# IMPORTANT: we need a shared build of wxWidgets to proceed
if [[ $(echo *.so) == "*.so" ]]; then
echo "No shared objects (*.so) were found... aborting"
exit 1
fi
# generated the "expected ABI" for later comparison
rm -f $expected_abi_file
for library in *.so; do
# NOTE: don't use -C option as otherwise cut won't work correctly
nm -D -g --defined-only $library | cut -d ' ' -f 3 | sort >>$expected_abi_file
done
echo "Expected wxWidgets ABI generated in \"$expected_abi_file\"..."
elif [[ -z "$1" ]]; then
if [[ ! -f "$expected_abi_file" ]]; then
echo "The file containing the expected wxWidgets ABI '$expected_abi_file' does not exist!"
echo "Please generate it first using the '--generate' option"
exit 1
fi
echo "Comparing actual ABI with the expected ABI (loading it from \"$expected_abi_file\")..."
# IMPORTANT: we need a shared build of wxWidgets to do the check
if [[ $(echo *.so) == "*.so" ]]; then
echo "No shared objects (*.so) were found... aborting"
exit 1
fi
rm -f $actual_abi_file
for library in *.so; do
# NOTE: don't use -C option as otherwise cut won't work correctly
nm -D -g --defined-only $library | cut -d ' ' -f 3 | sort >>$actual_abi_file
done
result=`diff -u $expected_abi_file $actual_abi_file`
if [[ -z "$result" ]]; then
echo "No binary (in)compatible changes were found."
else
echo "========================================================="
echo "WARNING: Possible binary-incompatible changes were found:"
echo "========================================================="
echo
echo "$result"
# this doesn't necessarly indicate that binary compatibility was surely
# broken; e.g. adding non-virtual methods will generate a new line in the
# $actual_abi_file but that's a compatible change.
fi
else
echo "Usage: $0 [--generate]"
echo "When running without options, compares the wxWidgets ABI saved in '$expected_abi_file'"
echo "with the current ABI of the .so files of the working directory."
echo "When --generate is given, saves in '$expected_abi_file' the ABI of the .so files"
echo "(for later comparisons)."
fi