]> git.saurik.com Git - wxWidgets.git/blame - docs/tech/tn0020.txt
fix part of proposal at http://news.gmane.org/find-root.php?message_id=%3c45A2343E...
[wxWidgets.git] / docs / tech / tn0020.txt
CommitLineData
d69f7c58 1 Binary Compatibility and wxWidgets
e6d67b57
VZ
2 ==================================
30. Purpose
4----------
5
d69f7c58 6This is broad technote covering all aspects of binary compatibility with
e6d67b57
VZ
7wxWidgets.
8
91. Releases
10-----------
11
12General overview of releases can be found in tn0012.txt, but for
13completeness the wxWidgets release version number is as follows:
14
152.6.2
16
17Where
18
19 2 6 2
20Major Minor Release
21
22(I.E. Major.Minor.Release).
23
d69f7c58
VZ
24All versions with EVEN minor version component (e.g. 2.4.x, 2.6.x etc.)
25are expected to be binary compatible (ODD minors are development versions
26and the compatibility constraints don't apply to them). Note that by
27preserving binary compatibility we mean BACKWARDS compatibility only,
28meaning that applications built with old wxWidgets headers should continue
29to work with new wxWidgets (shared/dynamic) libraries without the need to
30rebuild. There is no requirement to preserve compatibility in the other
31direction (i.e. make new headers compatible with old libraries) as this
32would preclude any additions whatsoever to the stable branch. But see
33also section (4).
e6d67b57 34
d69f7c58
VZ
35
362. What kind of changes are NOT binary compatible
e6d67b57
VZ
37-------------------------------------------------
38
39If its still up, the KDE guide is a good reference:
40http://developer.kde.org/documentation/other/binarycompatibility.html
41
d69f7c58 42The changes that are NOT binary compatible:
e6d67b57
VZ
43- Adding a virtual function
44- Changing the name of a any function or variable
45- Changing the signature of a virtual function (adding a parameter,
46even a default one)
47- Changing the order of the virtual functions in a class
48["switching" them, etc.]
d69f7c58 49- Changing access privileges to a function (protected to private etc.)
e6d67b57
VZ
50[unlike KDE we need to support windows so this is not allowed]
51- Adding a member variable
52- Changing the order of non-static member variables
53
54
d69f7c58
VZ
553. Changes which are compatible
56-------------------------------
57
58- Adding a new class
59- Adding a new non-virtual method to an existing class
60- Overriding the implementation of an existing virtual function
61[this is considered to be backwards binary compatible until we find a
62 counter example; currently it's known to work with Apple gcc at least]
63- Anything which doesn't result in ABI change at all, e.g. adding new
64 macros, constants and, of course, private changes in the implementation
65
66
674. wxABI_VERSION and "forward" binary compatibility
e6d67b57
VZ
68--------------------------------------------------
69
d69f7c58
VZ
70As mentioned we do not support "forward" binary compatibility, that is the
71ability to run applications compiled with new wxWidgets headers on systems
72with old wxWidgets libraries.
73
74However, for the developers who want to ensure that their application works
75with some fixed old wxWidgets version and doesn't (inadvertently) require
76features added in later releases, we provide the macro wxABI_VERSION which
77can be defined to restrict the API exported by wxWidgets headers to that of
78a fixed old release.
e6d67b57 79
d69f7c58
VZ
80For this to work, all new symbols added to binary compatible releases must
81be #if'ed with wxABI_VERSION.
e6d67b57
VZ
82
83The layout of wxABI_VERSION is as follows:
84
8520602
86
87where
88
6afac89e 89 2 06 02
e6d67b57
VZ
90Major Minor Release
91
d69f7c58 92I.E. it corresponds to the wxWidgets release in (1).
e6d67b57
VZ
93
94An example of using wxABI_VERSION is as follows for symbols
95only in a 2.6.2 release:
96
97#if wxABI_VERSION >= 20602 /* 2.6.2+ only */
98bool Load(const wxURI& location, const wxURI& proxy);
99
100wxFileOffset GetDownloadProgress();
101wxFileOffset GetDownloadTotal();
102
103bool ShowPlayerControls(
104 wxMediaCtrlPlayerControls flags =
105 wxMEDIACTRLPLAYERCONTROLS_DEFAULT);
106
107//helpers for the wxPython people
108bool LoadURI(const wxString& fileName)
109{ return Load(wxURI(fileName)); }
110bool LoadURIWithProxy(const wxString& fileName, const wxString& proxy)
111{ return Load(wxURI(fileName), wxURI(proxy)); }
112#endif
113
114
d69f7c58 1155. Workarounds for adding virtual functions
e6d67b57
VZ
116-------------------------------------------
117
d69f7c58 118Originally the idea for adding virtual functions to binary compatible
e6d67b57
VZ
119releases was to pad out some empty "reserved" functions and then
120rename those later when someone needed to add a virtual function.
121
122However, after there was some actual testing of the idea a lot of
123controversy erupted. Eventually we decided against the idea, and
124instead devised a new method for doing so called wxShadowObject.
125
126wxShadowObject is a class derived from wxObject that provides a means
127of adding functions and/or member variables to a class internally
128to wxWidgets. It does so by storing these in a hash map inside of
129it, looking it up when the function etc. is called. wxShadowObject
130is generally stored inside a reserved member variable.
131
132wxShadowObject resides in include/wx/clntdata.h.
133
134To use wxShadowObject, you first call AddMethod or AddField with
135the first parameter being the name of the field and/or method
136you want, and the second parameter being the value of the
137field and/or method.
138
139In the case of fields this is a void*, and in the case of method
140is a wxShadowObjectMethod which is a typedef:
141typedef int (*wxShadowObjectMethod)(void*, void*);
142
143After you add a field, you can set it via SetField with the same
d69f7c58 144parameters as AddField, the second parameter being the value to set
e6d67b57
VZ
145the field to. You can get the field after you call AddField
146via GetField, with the parameters as the other two field functions,
147only in the case the second parameter is the fallback
148value for the field in the case of it not being found in the
149hash map.
150
151You can call a method after you add it via InvokeMethod, which
152returns a bool indicating whether or not the method was found
153in the hash map, and has 4 parameters. The first parameter is
154the name of the method you wish to call, the second is the first
155parameter passed to the wxShadowObjectMethod, the third is the
156second parameter passed to that wxShadowObjectMethod, and the
157fourth is the return value of the wxShadowObjectMethod.
158
d69f7c58 1596. version-script.in
e6d67b57
VZ
160--------------------
161
162For ld/libtool we use sun-style version scripts. Basically
d69f7c58 163anything which fits the conditions of being #if'ed via wxABI_VERSION
e6d67b57
VZ
164needs to go here also.
165
6afac89e
MW
166See 'info ld scripts version' on a GNU system, it's online here:
167http://www.gnu.org/software/binutils/manual/ld-2.9.1/html_node/ld_25.html
168
169Or see chapter 5 of the 'Linker and Libraries Guide' for Solaris, available
170online here:
171http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWdev/LLM/p1.html
172
e6d67b57
VZ
173The file has the layout as follows:
174
175@WX_VERSION_TAG@.X
176
177Where X is the current Release as mentioned earlier, i.e. 2. This
178is following by an opening bracket "{", followed by "global:",
6afac89e 179followed by patterns matching added symbols, then followed by "}", and then
e6d67b57
VZ
180the file is either followed by earlier Releases or ended by
181a @WX_VERSION_TAG@ block without the period or Release.
182
6afac89e
MW
183The patterns used to specify added symbols are globbing patters and can
184contain wildcards such as '*'.
185
186For example for a new class member such as:
187 wxFont wxGenericListCtrl::GetItemFont( long item ) const;
188
189the mangled symbol might be:
190 _ZNK17wxGenericListCtrl11GetItemFontEl
191
192so a line like this could be added to version-script.in:
193 *wxGenericListCtrl*GetItemFont*;
194
195Allow for the fact that the name mangling is going to vary from compiler to
196complier.
197
198When adding a class you can match all the symbols it adds with a single
199pattern, so long as that pattern is not likely to also match other symbols.
200For example for wxLogBuffer a line like this:
201 *wxLogBuffer*;
202
203
d69f7c58
VZ
2047. Checking the version information in libraries and programs
205-------------------------------------------------------------
6afac89e
MW
206
207On Sun there is a tool for this, see pvs(1). On GNU you can use objdump, below
208are some examples.
209
210To see what versions of each library a program (or library) depends on:
211
212$ objdump -p widgets | sed -ne '/Version References/,/^$/p'
213Version References:
214 required from libgcc_s.so.1:
215 0x0b792650 0x00 10 GCC_3.0
216 required from libwx_based-2.6.so.0:
217 0x0cca2546 0x00 07 WXD_2.6
218 required from libstdc++.so.6:
219 0x056bafd3 0x00 09 CXXABI_1.3
220 0x08922974 0x00 06 GLIBCXX_3.4
221 required from libwx_gtk2d_core-2.6.so.0:
222 0x0a2545d2 0x00 08 WXD_2.6.2
223 0x0cca2546 0x00 05 WXD_2.6
224 required from libc.so.6:
225 0x09691a75 0x00 04 GLIBC_2.2.5
226
227To see what WXD_2.6.2 symbols a program uses:
228
229$ objdump -T widgets | grep 'WXD_2\.6\.2'
2300000000000000000 g DO *ABS* 0000000000000000 WXD_2.6.2 WXD_2.6.2
23100000000004126d8 DF *UND* 0000000000000177 WXD_2.6.2 _ZN19wxTopLevelWindowGTK20RequestUserAttentionEi
232
233To see what WXD_2.6.2 symbols a library defines:
234
235$ objdump -T libwx_based-2.6.so | grep 'WXD_2\.6\.2' | grep -v 'UND\|ABS'
2360000000000259a10 w DO .data 0000000000000018 WXD_2.6.2 _ZTI19wxMessageOutputBest
23700000000002599e0 w DO .data 0000000000000028 WXD_2.6.2 _ZTV19wxMessageOutputBest
238000000000010a98e w DF .text 000000000000003e WXD_2.6.2 _ZN19wxMessageOutputBestD0Ev
2390000000000114efb w DO .rodata 000000000000000e WXD_2.6.2 _ZTS11wxLogBuffer
2400000000000255590 w DO .data 0000000000000018 WXD_2.6.2 _ZTI11wxLogBuffer
241000000000011b550 w DO .rodata 0000000000000016 WXD_2.6.2 _ZTS19wxMessageOutputBest
24200000000000bfcc8 g DF .text 00000000000000dd WXD_2.6.2 _ZN11wxLogBuffer5DoLogEmPKcl
243000000000010a3a6 g DF .text 0000000000000153 WXD_2.6.2 _ZN19wxMessageOutputBest6PrintfEPKcz
24400000000000c0b22 w DF .text 000000000000004b WXD_2.6.2 _ZN11wxLogBufferD0Ev
24500000000000bfc3e g DF .text 0000000000000089 WXD_2.6.2 _ZN11wxLogBuffer5FlushEv
24600000000000c0ad6 w DF .text 000000000000004b WXD_2.6.2 _ZN11wxLogBufferD1Ev
24700000000000b1130 w DF .text 0000000000000036 WXD_2.6.2 _ZN11wxLogBufferC1Ev
24800000000000c095c w DF .text 0000000000000029 WXD_2.6.2 _ZN19wxMessageOutputBestC1Ev
24900000000000c08e8 w DF .text 000000000000003e WXD_2.6.2 _ZN19wxMessageOutputBestD1Ev
25000000000002554c0 w DO .data 0000000000000038 WXD_2.6.2 _ZTV11wxLogBuffer
25100000000000bfda6 g DF .text 0000000000000036 WXD_2.6.2 _ZN11wxLogBuffer11DoLogStringEPKcl
25200000000000abe10 g DF .text 0000000000000088 WXD_2.6.2 _ZN14wxZipFSHandler7CleanupEv
e6d67b57 253
e6d67b57 254
d69f7c58 2558. Testing binary compatibility between releases
e6d67b57
VZ
256------------------------------------------------
257
d69f7c58 258An easy way of testing binary compatibility is just to build wxWidgets
e6d67b57
VZ
259in dll/dynamic library mode and then switch out the current library
260in question with an earlier stable version of the library, then running
261the application in question again. If it runs OK then there is usually
d69f7c58 262binary compatibility between those releases.
e6d67b57
VZ
263
264You can also break into your debugger or whatever program you want
265to use and check the memory layout of the class. If it is the same
d69f7c58 266then it is binary compatible.
e6d67b57 267
172f04f5
VZ
268Also remember to look at http://www.wxwidgets.org/bincompat.html page which
269summarizes the results of testing of all the samples built against old
270libraries headers with the new library binaries under Unix.
271
e6d67b57
VZ
272
273=== EOF ===
274
275Author: RN
276Version: $Id$