HTML source code, style-sheets, scripts, and images for deployment on mingw.osdn.io
修订版 | 1be8036421b4832b76a9ee9f6483554500e17758 (tree) |
---|---|
时间 | 2021-11-23 07:14:05 |
作者 | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Publish note on DLL version management.
* dllver.html: New file.
* docrefs.html: Add reference link.
@@ -0,0 +1,603 @@ | ||
1 | +<!DOCTYPE HTML><!-- | |
2 | + * | |
3 | + * dllver.html | |
4 | + * | |
5 | + * Adaptation of Charles S. Wilson's observations on DLL naming, and | |
6 | + * ABI version identification conventions. | |
7 | + * | |
8 | + * | |
9 | + * $Id$ | |
10 | + * | |
11 | + * Written by Keith Marshall <keith@users.osdn.me> | |
12 | + * Copyright (C) 2021, MinGW.OSDN Project | |
13 | + * | |
14 | + * | |
15 | + * Redistribution and use in source and 'compiled' forms (SGML, HTML, | |
16 | + * PDF, PostScript, RTF, etc) with or without modification, are permitted | |
17 | + * provided that the following conditions are met: | |
18 | + * | |
19 | + * 1. Redistributions of source code must retain the above copyright | |
20 | + * notice, this list of conditions and the following disclaimer as | |
21 | + * the first lines of this file, unmodified. | |
22 | + * | |
23 | + * 2. Redistributions in compiled form (transformed to other DTDs, | |
24 | + * converted to PDF, PostScript, RTF and other formats) must | |
25 | + * reproduce the above copyright notice, this list of conditions | |
26 | + * and the following disclaimer in the documentation and/or other | |
27 | + * materials provided with the distribution. | |
28 | + * | |
29 | + * THIS DOCUMENTATION IS PROVIDED BY THE MINGW.OSDN PROJECT "AS IS" | |
30 | + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
31 | + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
32 | + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE MINGW.OSDN PROJECT, OR | |
33 | + * ITS CONTRIBUTORS, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
34 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
35 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
36 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
37 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
38 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
39 | + * OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | |
40 | + * DAMAGE. | |
41 | + * | |
42 | + * | |
43 | + * Note: this page assumes browser support for the following numeric | |
44 | + * HTML entity codes: | |
45 | + * | |
46 | + * ‑ non-breaking hyphen | |
47 | + * ‘ typographic left (opening) single quote | |
48 | + * ’ typographic apostrophe/right (closing) single quote | |
49 | + * “ typographic left (opening) double quote | |
50 | + * ” typographic right (closing) double quote | |
51 | + * | |
52 | +--> | |
53 | +<script class="masthead"> | |
54 | + set_page("title", "MinGW Software Deployment Guide"); | |
55 | + set_page("subtitle", "HOWTO Manage a Collection of Installed MinGW DLLs"); | |
56 | +</script><!-- masthead --> | |
57 | +<div class="masthead" style="display: none"> | |
58 | +<p class="byline">Posted: 22-Nov-2021, by Keith; Last Update: 22-Nov-2021</p> | |
59 | +</div><!-- masthead --> | |
60 | +<div class="overlapped" id="introduction"> | |
61 | +<h3>Introduction</h3> | |
62 | +<p>This Mini‑HOWTO offers advice on installation, | |
63 | +and explains the conventions which have been adopted by MinGW, | |
64 | +(and also by Cygwin), | |
65 | +to identify disparate versions of similarly named shared libraries, (DLLs), | |
66 | +and so mitigate the “DLL Hell” which may arise, | |
67 | +as a result of software dependencies on potentially | |
68 | +incompatible versions of such DLLs. | |
69 | +</p> | |
70 | +<p>The content herein is derived from an original web document, | |
71 | +originally posted by Soren Andersen, (a.k.a. Perlspinr), | |
72 | +and now accessible only via <a rel="noopener noreferrer" target="_blank" | |
73 | + href="http://web.archive.org/web/20080516135947/http://home.att.net/~perlspinr/build_platforms/cygwin/libversioning.html" | |
74 | +>this WayBack Machine archive</a>; | |
75 | +this, in turn, | |
76 | +was inspired by a no‑longer‑accessible posting, | |
77 | +by Charles (Chuck) Wilson, | |
78 | +on a mailing‑list discussing | |
79 | +Portable Network Graphics (PNG) implementation; | |
80 | +the original content has been generalized, | |
81 | +to eliminate PNG‑specific references, | |
82 | +and expanded upon, in a MinGW‑specific context. | |
83 | +</p> | |
84 | +</div><!-- introduction --> | |
85 | + | |
86 | +<div class="overlapped" id="definitions"> | |
87 | +<h3>Definitions</h3> | |
88 | +<dl class="hanging-indent"> | |
89 | +<dt>PE</dt> | |
90 | +<dd>The Microsoft <em>Portable Executable</em>  | |
91 | +file format; an adaptation of the <em>common object file format</em>, | |
92 | +it is sometimes identified as <em>PE‑COFF</em>. | |
93 | +</dd> | |
94 | +<dt>ELF</dt> | |
95 | +<dd><em>Executable and Linkable Format</em> ; | |
96 | +this is an alternative executable, and shared library file format, | |
97 | +used by GNU/Linux, and several Unix systems; | |
98 | +it is <em>not</em> used by MS‑Windows. | |
99 | +</dd> | |
100 | +<dt>DLL</dt> | |
101 | +<dd>A <em>dynamic link library</em> ; | |
102 | +this is the terminology favoured by Microsoft, | |
103 | +when referring to shared libraries. | |
104 | +</dd> | |
105 | +<dt>Dynamic Linker</dt> | |
106 | +<dd>An operating system facility, | |
107 | +responsible for loading executable program files, | |
108 | +and shared libraries, | |
109 | +and resolving (linking) symbolic references across | |
110 | +executable file and shared library boundaries, | |
111 | +to construct a run‑time process image. | |
112 | +</dd> | |
113 | +<dt>Entry Point</dt> | |
114 | +<dd>This is any one of the publicly visible variable names, | |
115 | +or function names, which is exported by a specific DLL. | |
116 | +</dd> | |
117 | +<dt>Interface</dt> | |
118 | +<dd>This represents the aggregate of all <em>entry points</em>, | |
119 | +which are exported by the DLL. | |
120 | +</dd> | |
121 | +<dt>API</dt> | |
122 | +<dd>This represents the <em>application programming interface</em> ; | |
123 | +it is, effectively, the <em>interface</em>, | |
124 | +characterized by the <em>entry point</em> names, | |
125 | +data types, and function prototypes. | |
126 | +</dd> | |
127 | +<dt>ABI</dt> | |
128 | +<dd>This is the <em>application binary interface</em> ; | |
129 | +it represents, and is characterized by, | |
130 | +the machine‑level implementation of the <em>interface</em>. | |
131 | +</dd></dl> | |
132 | +</div><!-- definitions --> | |
133 | + | |
134 | +<div class="overlapped" id="dll-references"> | |
135 | +<h3>How the MS‑Windows Dynamic Linker Resolves Shared Library References</h3> | |
136 | +<p>When a <em>PE</em>  file, | |
137 | +(typically, but not restricted to, | |
138 | +an <em>executable</em>  | |
139 | +‘<em><code>*.exe</code></em> ’, | |
140 | +or a <em>shared library</em>  | |
141 | +‘<em><code>*.dll</code></em> ’ | |
142 | +file), is created, the <em>build‑time</em>  linker, | |
143 | +(e.g. the MinGW linker ... <em>not</em>  | |
144 | +the <em>dynamic linker</em><span class="nowrap"> ),</span> | |
145 | +embeds references, within the <em>PE</em>  file itself, | |
146 | +to any shared libraries on which it depends. | |
147 | +Each such reference takes the form of just a DLL file name, | |
148 | +<em>without</em>  any directory path name qualification, | |
149 | +and there is no direct analogue for the <em>ELF</em>  | |
150 | +<span class="nowrap">‘<em><code>rpath</code></em> ’</span> | |
151 | +feature. | |
152 | +</p> | |
153 | +<p>When the Windows <em>dynamic linker</em>  creates a new process image, | |
154 | +it first loads the <em>PE</em>  executable program file into memory. | |
155 | +It then attempts to load each shared library, | |
156 | +named as a DLL reference within the <em>PE</em>  file, | |
157 | +(and iteratively, | |
158 | +any further named DLL references within the loaded DLLs themselves), | |
159 | +mapping each one into the process address space, | |
160 | +and resolving symbol references across DLL boundaries; | |
161 | +only after all named DLLs have been loaded, | |
162 | +and all symbol references successfully resolved, | |
163 | +will execution of the process commence. | |
164 | +</p> | |
165 | +<p>To locate each DLL, named in <em>PE</em>  file references, | |
166 | +the MS‑Windows <em>dynamic linker</em> will search | |
167 | +in each of the following directories, in turn; | |
168 | +(this search will continue, through the directory sequence, | |
169 | +only as far as is necessary to locate the <em>first</em>  | |
170 | +DLL file, with a name which matches the reference): | |
171 | +</p><ol> | |
172 | +<li>The directory from which the executable file, itself, was loaded. | |
173 | +</li> | |
174 | +<li>The current working directory, at process start‑up time. | |
175 | +</li> | |
176 | +<li>The Windows system directory; | |
177 | +the path name for this directory may be identified, | |
178 | +by calling the <code>GetSystemDirectory()</code> function. | |
179 | +</li> | |
180 | +<li>The Windows directory; | |
181 | +the path name for this directory may be identified, | |
182 | +by calling the <code>GetWindowsDirectory()</code> function. | |
183 | +</li> | |
184 | +<li>The sequence of directories, taken in turn, | |
185 | +listed in the <code>PATH</code> environment variable; | |
186 | +(note that this is the path searched for executables themselves; | |
187 | +the <code>LIBPATH</code> environment variable is <em>not</em> considered, | |
188 | +and <code>LD_LIBRARY_PATH</code> — a standard environment variable | |
189 | +which is commonly associated with <em>ELF</em>  shared libraries — | |
190 | +has no defined purpose in the MS‑Windows environment). | |
191 | +</li></ol> | |
192 | +<p>Note that each uniquely named DLL file, | |
193 | +irrespective of the directory path from whence it is loaded, | |
194 | +will be mapped into the process address space only once. | |
195 | +Furthermore, if the instance of each named DLL, | |
196 | +which is located first in the above directory search sequence, | |
197 | +fails to resolve all <em>entry points</em>  | |
198 | +which it is expected to provide, | |
199 | +process execution will fail; | |
200 | +the search will <em>not</em>  be resumed, | |
201 | +even if a similarly named DLL file, | |
202 | +from a later directory in the search sequence, | |
203 | +may be an alternative version, | |
204 | +from which the missing <em>entry points</em>  | |
205 | +could have been resolved. | |
206 | +</p> | |
207 | +<p>It is important to ensure that, | |
208 | +if an application requires a particular version of any DLL, | |
209 | +that the correct DLL is installed in a location whence it will be identified | |
210 | +early in the preceding search sequence. | |
211 | +In a conventional MinGW installation, | |
212 | +(typically in <code>C:\MinGW</code>), | |
213 | +this is normally achieved by installation of <em>both</em>  | |
214 | +the <code>*.exe</code> files, <em>and</em>  their associated DLLs, | |
215 | +in the common <code>C:\MinGW\bin</code> directory, | |
216 | +so that DLL identification is completed in accordance with rule (1), above. | |
217 | +</p> | |
218 | +<p>Alternatively, | |
219 | +for any application whose <code>*.exe</code> files are <em>not</em>  | |
220 | +installed in the <code>C:\MinGW\bin</code> directory, | |
221 | +(since <code>C:\MinGW\bin</code> will typically be listed within | |
222 | +the user’s <code>PATH</code> environment variable), | |
223 | +MinGW DLLs may be identified in accordance with rule (5). | |
224 | +When applications depend on this DLL identification stratagem, | |
225 | +it is <em>strongly</em>  recommended that <em>all</em>  | |
226 | +MinGW DLLs be kept fully up to date, | |
227 | +to ensure that compatibility is maintained, | |
228 | +as explained below, | |
229 | +for <em>all</em>  dependent applications, | |
230 | +regardless of age. | |
231 | +</p> | |
232 | +</div><!-- dll-references --> | |
233 | + | |
234 | +<div class="overlapped" id="implementation"> | |
235 | +<h3>How MinGW Shared Library Version Numbers are Assigned</h3> | |
236 | +<p>The single value, | |
237 | +as assigned as a MinGW shared library version number, | |
238 | +is derived from an effective GNU libtool <em>current:revision:age</em> triplet, | |
239 | +which itself, is managed in accordance with the convention described in | |
240 | +<a rel="noopener noreferrer" target="_blank" | |
241 | + href="https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html#Libtool-versioning" | |
242 | +>libtool‑versioning section of the GNU libtool manual</a>: | |
243 | +</p> | |
244 | +<div class="box-out"> | |
245 | +<p>[...] libtool library versions are described by three integers: | |
246 | +</p> | |
247 | +<dl class="hanging-indent" style="margin-top: 0.2em"> | |
248 | +<dt>current</dt> | |
249 | +<dd>The most recent interface [<em>ABI</em> version] number | |
250 | +that this library implements. | |
251 | +</dd> | |
252 | +<dt>revision</dt> | |
253 | +<dd>The implementation [revision] number of | |
254 | +the <em><code>current</code></em>  interface. | |
255 | +</dd> | |
256 | +<dt>age</dt> | |
257 | +<dd>The difference between [the <em>ABI</em> version numbers of] | |
258 | +the newest and oldest interfaces that this library implements. | |
259 | +In other words, | |
260 | +the library implements all the interface numbers in the range from number | |
261 | +<em><code>current</code> <code>-</code> <code>age</code></em>  | |
262 | +to <em><code>current</code></em>. | |
263 | +</dd></dl> | |
264 | +</div><!-- box-out --> | |
265 | +<p>These <em><code>current:revision:age</code></em> attributes are assigned, | |
266 | +by the maintainer of the library, | |
267 | +as specified in <a rel="noopener noreferrer" target="_blank" | |
268 | + href="https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info" | |
269 | +>the immediately following section of the GNU libtool manual</a>: | |
270 | +</p> | |
271 | +<div class="box-out"> | |
272 | +<p>Here are a set of rules to help you update your library version information: | |
273 | +</p><ol> | |
274 | +<li>Start with version information of ‘<code>0:0:0</code>’ | |
275 | +for each libtool library. | |
276 | +</li> | |
277 | +<li>Update the version information only immediately before a public release | |
278 | +of your software. More frequent updates are unnecessary, and only guarantee | |
279 | +that the current interface number gets larger faster. | |
280 | +</li> | |
281 | +<li>If the library source code has changed at all, | |
282 | +since the [version information was last updated], | |
283 | +then increment <em><code>revision</code></em>  <span class="nowrap">(i.e. | |
284 | +‘<em><code>current:revision:age</code></em> ’</span> becomes | |
285 | +‘<span class="nowrap"><em><code>current:revision</code></em> <!-- | |
286 | +--><code>+</code> <code>1<em>:age</em></code> ’<!-- | |
287 | +--> ).</span> | |
288 | +</li> | |
289 | +<li>If any interfaces have been added, removed, | |
290 | +or changed since the last update, | |
291 | +increment <em><code>current</code></em>, | |
292 | +and set <em><code>revision</code></em>  to <code>0</code>. | |
293 | +</li> | |
294 | +<li>If any interfaces [i.e. <em>entry points</em> ] | |
295 | +have been added since the last public release, | |
296 | +then increment <em><code>age</code></em>. | |
297 | +</li> | |
298 | +<li>If any interfaces [i.e. <em>entry points</em> ] have been removed, | |
299 | +or [the <em>data type</em> or <em>function prototype</em> | |
300 | +of any <em>entry point</em> has been] changed since the last public release, | |
301 | +then set <em><code>age</code></em>  to <code>0</code>. | |
302 | +</li></ol> | |
303 | +<p><em><strong>Never</strong></em> try to set the interface numbers | |
304 | +so that they correspond to the release number of your package. | |
305 | +This is an abuse that only fosters misunderstanding of | |
306 | +the purpose of library versions. [...] | |
307 | +</p> | |
308 | +<p>The following explanation | |
309 | +may help [you] to understand the above rules a bit better: | |
310 | +consider that there are three possible kinds of reactions | |
311 | +from users of your library to changes in a shared library: | |
312 | +</p><ol> | |
313 | +<li>Programs using the previous version | |
314 | +may use the new version as drop-in replacement, | |
315 | +and programs using the new version can also work with the previous one. | |
316 | +In other words, no recompiling nor relinking is needed. | |
317 | +In this case, bump <em><code>revision</code></em>  only, | |
318 | +don’t touch <em><code>current</code></em>  | |
319 | +[or] <em><code>age</code></em>. | |
320 | +</li> | |
321 | +<li>Programs using the previous version | |
322 | +may use the new version as drop-in replacement, | |
323 | +but programs using the new version may use <em>APIs</em> | |
324 | +[which are] not present in the previous one. | |
325 | +In other words, a program linking against the new version | |
326 | +may fail with “unresolved symbols” | |
327 | +if [deployed with] the old version at runtime: | |
328 | +set <em><code>revision</code></em>  to <code>0</code>, | |
329 | +bump [i.e. increment both] <em><code>current</code></em>  | |
330 | +and <em><code>age</code></em>. | |
331 | +</li> | |
332 | +<li>Programs may need to be changed, | |
333 | +recompiled, and relinked in order to use the new version. | |
334 | +Bump <em><code>current</code></em>, | |
335 | +set [both] <em><code>revision</code></em>  | |
336 | +and <em><code>age</code></em>  to <code>0</code>. | |
337 | +</li></ol> | |
338 | +<p>In the above description, | |
339 | +<em>programs</em> using the library in question may also be | |
340 | +replaced by other libraries using it. | |
341 | +</p> | |
342 | +</div><!-- box-out --> | |
343 | +<p>To derive the single‑valued MinGW shared library version number, | |
344 | +from the GNU libtool compatible | |
345 | +<em><code>current:revision:age</code></em>  triplet, | |
346 | +we adopt the convention originally suggested by Gary Vaughan, | |
347 | +in a <a rel="noopener noreferrer" target="_blank" | |
348 | + href="https://cygwin.com/pipermail/cygwin/2000-September/040213.html" | |
349 | +>posting to the Cygwin mailing‑list</a>, | |
350 | +to the effect that the effective shared library version should be | |
351 | +set equal to the version number of the <em>oldest ABI</em>  version | |
352 | +supported by the shared library; | |
353 | +this is equivalent to the result of the calculation | |
354 | +<em><code>current</code> <code>-</code> <code>age</code></em>, | |
355 | +taking the individual values of <em><code>current</code></em>, | |
356 | +and <em><code>age</code></em>  from the libtool triplet. | |
357 | +(Note that this does <em>not require</em>  use of libtool | |
358 | +for maintanence of the shared library; | |
359 | +it is sufficient to adopt the libtool numbering convention, | |
360 | +and to calculate | |
361 | +<em><code>current</code> <code>-</code> <code>age</code></em>  | |
362 | +manually). | |
363 | +</p> | |
364 | +</div><!-- implementation --> | |
365 | + | |
366 | +<div class="overlapped" id="explanation"> | |
367 | +<h3>Evolution of MinGW Shared Library Versions</h3> | |
368 | +<p>To further illustrate the evolution of MinGW shared library versions, | |
369 | +let us consider the development life‑cycle of | |
370 | +a hypothetical library, <code>libfoo.dll</code>, | |
371 | +for which the most recent release corresponds to a GNU libtool | |
372 | +<em><code>current:revision:age</code></em>  triplet | |
373 | +of <code>5:4:3</code>; | |
374 | +this indicates that the <em>current ABI</em>  version of | |
375 | +this hypothetical library is <code>5</code>, | |
376 | +and that this version is fully <em>backwardly compatible</em>  with | |
377 | +each of the <em>three</em>  preceding releases, | |
378 | +with <em>ABI</em>  version numbers <code>4</code>, | |
379 | +<code>3</code>, and <code>2</code>; | |
380 | +thus, the MinGW library version, | |
381 | +computed as <em><code>current</code> <code>-</code> <code>age</code></em>, | |
382 | +will be <code>2</code>, | |
383 | +yielding a versioned library name of <code>libfoo-2.dll</code>; | |
384 | +it may be observed that this version‑indicating name corresponds to | |
385 | +the <em>oldest ABI</em>  version which is fully compatible with | |
386 | +the <em>current ABI</em>  version <code>5</code> release. | |
387 | +</p> | |
388 | +<p>There are many evolutionary paths, | |
389 | +which <code>libfoo‑2.dll</code> may have followed, | |
390 | +to become the equivalent of a libtool‑managed <code>5:4:3</code> release; | |
391 | +the following example represents just one such possible path: | |
392 | +</p><ol> | |
393 | +<li>Regardless of the path followed, | |
394 | +the starting point is <em>always</em> equivalent to | |
395 | +libtool release <code>0:0:0</code>, yielding a computed | |
396 | +<em><code>current</code> <code>-</code> <code>age</code></em>  | |
397 | +value of <code>0</code> <code>-</code> <code>0</code>, | |
398 | +(or simply <code>0</code>); | |
399 | +thus, the MinGW designation for the <em>initial</em> release | |
400 | +will be <code>libfoo‑0.dll</code>. | |
401 | +</li> | |
402 | +<li>The library goes through several release cycles, | |
403 | +without any change in, addition to, | |
404 | +or removal from its public <em>interface</em> ; | |
405 | +the libtool <em><code>revision</code></em>  is incremented, | |
406 | +at each release, | |
407 | +through <code>0:1:0</code>, <code>0:2:0</code>, <code>...</code>, | |
408 | +but, since neither <em><code>current</code></em>, | |
409 | +nor <em><code>age</code></em>  is changed, | |
410 | +the MinGW release designation remains as <code>libfoo‑0.dll</code>. | |
411 | +<p>This is correct, | |
412 | +because the <em>interface</em>  remains unchanged from | |
413 | +the <em>initial</em>  release; | |
414 | +programs linked against the initial release may continue to use | |
415 | +this <code>libfoo‑0.dll</code>, | |
416 | +as a drop‑in replacement for the original, | |
417 | +while benefitting from any bug‑fixes | |
418 | +which may have been applied in the newer releases. | |
419 | +</p></li> | |
420 | +<li>Following the release of <code>libfoo‑0.dll</code>, | |
421 | +corresponding to (say) libtool release <code>0:4:0</code>, | |
422 | +a new function <em>entry point</em>  is added, | |
423 | +<em>without</em>  changing the established interface | |
424 | +<em>in any way</em>. | |
425 | +This introduces a <em>forwardly incompatible</em>  | |
426 | +change in the <em>API</em>,  (because any new application | |
427 | +which depends on the new <em>entry point</em>  will be | |
428 | +incompatible with any earlier release of <code>libfoo‑0.dll</code>); | |
429 | +however, the <em>API</em>  remains <em>backwardly compatible</em>  | |
430 | +with previous releases, (because <em>none</em>  of the | |
431 | +previously existing <em>entry points</em>  exhibit | |
432 | +any change in behaviour). | |
433 | +<p>To reflect this change in compatibility, | |
434 | +the libtool <em><code>current</code></em>  version number | |
435 | +is incremented, | |
436 | +while resetting the <em><code>revision</code></em>  | |
437 | +to <code>0</code>, | |
438 | +(to account for the addition of the new <em>entry point</em> ); | |
439 | +at the same time, <em><code>age</code></em>  | |
440 | +is incremented in lock‑step, | |
441 | +(because <em>backward</em>  compatibility, | |
442 | +with the preceding release, is preserved). | |
443 | +Consequently, the libtool release identification becomes <code>1:0:1</code>, | |
444 | +since the result of computing | |
445 | +<em><code>current</code> <code>-</code> <code>age</code></em>, | |
446 | +(which now becomes <code>1</code> <code>-</code> <code>1</code>), | |
447 | +remains equal to <code>0</code>, and thus, | |
448 | +the MinGW library designation remains as | |
449 | +<code>libfoo‑0.dll</code>. | |
450 | +Once again, this is correct; in spite of the change | |
451 | +in libtool <em><code>current</code></em>  release number, | |
452 | +the <em>oldest</em>  value of <em><code>current</code></em>  | |
453 | +release, with which this release remains <em>backwardly</em>  compatible, | |
454 | +is still <code>0</code>. | |
455 | +</p></li> | |
456 | +<li>After the release of <code>libfoo‑0.dll</code>, | |
457 | +at libtool release point <code>1:0:1</code>, | |
458 | +one of the publicly visible <em>entry point</em>  functions | |
459 | +is deemed to have become obsolete, and is removed. | |
460 | +This represents another change to the public <em>interface</em>, | |
461 | +so once again the libtool <em><code>current</code></em>  | |
462 | +release number must be incremented, | |
463 | +and the <em><code>revision</code></em>  reset; | |
464 | +however, this is <em>not</em>  a <em>backwardly | |
465 | +compatible</em>  change, so, for this release, | |
466 | +<em><code>age</code></em>  is reset to <code>0</code>, | |
467 | +rather than being incremented. | |
468 | +The effect of this is that the libtool release number advances | |
469 | +to <code>2:0:0</code>, and the MinGW release number, computed as | |
470 | +<em><code>current</code> <code>-</code> <code>age</code></em>, | |
471 | +advances to <code>2</code>, resulting in a new MinGW library designation | |
472 | +of <code>libfoo‑2.dll</code>. | |
473 | +<p>Note that this is, once again, correct: | |
474 | +the libtool <em><code>current</code></em>  release number has advanced, | |
475 | +to <code>2</code>; this release is no longer <em>backwardly</em>  | |
476 | +compatible with any other release, older than itself, | |
477 | +and the MinGW release number has also advanced accordingly; | |
478 | +this <code>libfoo‑2.dll</code> is <em>not</em>  suitable for | |
479 | +use as a drop‑in replacement for <code>libfoo‑0.dll</code>, | |
480 | +and the DLL file name has been changed, to prevent any such misuse. | |
481 | +</p></li> | |
482 | +<li>The next few release cycles, | |
483 | +following the preceding release of <code>libfoo‑2.dll</code>, | |
484 | +may proceed as described in (2), above, thus requiring only | |
485 | +the libtool <em><code>revision</code></em>  to be incremented, | |
486 | +<em>without</em>  affecting the MinGW release number, | |
487 | +<em>in any way</em>. | |
488 | +These may be interspersed with three further cycles, | |
489 | +similar to that described in (3), above, | |
490 | +in which any number of new <em>entry points</em>  are added, | |
491 | +but <em>none</em>  are removed or modified; | |
492 | +after the third such type (3) release, | |
493 | +the libtool release number will have advanced through | |
494 | +<code>3:0:1</code>, <code>4:0:2</code>, and finally <code>5:0:3</code>. | |
495 | +If this is then followed by by four further type (2) releases, | |
496 | +there will be four further increments in | |
497 | +the libtool <em><code>revision</code></em>, | |
498 | +ultimately advancing the libtool release number to <code>5:4:3</code>; | |
499 | +at this stage in the release cycle sequence, the | |
500 | +<em><code>current</code> <code>-</code> <code>age</code></em>  | |
501 | +computation will continue to yield a MinGW release number of <code>2</code>, | |
502 | +and the MinGW library will continue to be named <code>libfoo‑2.dll</code>. | |
503 | +</li></ol> | |
504 | +<p>It may be observed that, | |
505 | +following the preceding sequence of release cycles, | |
506 | +whereas the libtool release number is able to convey the information that | |
507 | +the current library version implements revision <code>4</code> of | |
508 | +the implementation of version <code>5</code> of the <em>interface</em>, | |
509 | +and that this implementation is fully <em>backwardly compatible</em>  | |
510 | +with version <code>2</code> of this interface, | |
511 | +the MinGW release number cannot adequately convey any more than | |
512 | +the last of these pieces of information. | |
513 | +Although this limitation may appear to be problematic, | |
514 | +in practice it isn’t, <em>provided</em>  the installed | |
515 | +version of <code>libfoo‑2.dll</code> is its most recently | |
516 | +released distribution; | |
517 | +unlike <em>ELF dynamic linkers</em>, | |
518 | +the <em>PE dynamic linker</em>  simply isn’t smart enough | |
519 | +to select a DLL on the basis of a <em>range</em>  of supported | |
520 | +<em>interface</em>  versions, | |
521 | +so the best we can hope for is that the selected library, | |
522 | +as named for its <em>oldest</em>  supported version, | |
523 | +covers the required range; | |
524 | +the most effective assurance that we can have for this | |
525 | +is that the selected library is the most recently released distribution, | |
526 | +with the specified name. | |
527 | +</p> | |
528 | +</div><!-- explanation --> | |
529 | + | |
530 | +<div class="overlapped" id="conclusion"> | |
531 | +<h3>Conclusion</h3> | |
532 | +<p>“DLL Hell” arises | |
533 | +when two identically named shared library files provide different | |
534 | +(incompatible) <em>APIs</em>  ... perhaps even incompatible versions | |
535 | +of fundamentally the same <em>API</em> ; | |
536 | +a common cause is that installation of some third‑party software | |
537 | +product has overwritten an installed DLL file with an obsolete version. | |
538 | +</p> | |
539 | +<p>Sometimes, | |
540 | +a particular software product requires a particular version of | |
541 | +a specific DLL, with which the most recent version of that DLL is | |
542 | +<em>not backwardly compatible</em>,  (because the developer | |
543 | +of that DLL may not have exercised good version control discipline). | |
544 | +To avoid this kind of issue, | |
545 | +MinGW has adopted a DLL version management discipline, | |
546 | +conforming to the following conventions: | |
547 | +</p><ul> | |
548 | +<li>Each installed MinGW DLL should include, within its file name, | |
549 | +a numerical indication of <em>oldest API</em>  implementation version, | |
550 | +(and corresponding <em>ABI</em>  version), | |
551 | +with which it remains <em>100% backwardly compatible</em>. | |
552 | +</li> | |
553 | +<li>Since the <em>API</em>  version number, | |
554 | +which is encoded within the DLL file name, | |
555 | +represents the <em>oldest API implementation</em>  | |
556 | +with which the DLL is 100% <em>backwardly</em>  compatible, | |
557 | +newer versions may add new functionality | |
558 | +<em>without</em>  requiring a change of name, | |
559 | +provided <em>all existing</em>  functionality remains unchanged. | |
560 | +</li> | |
561 | +<li>If <em>API</em>  functionality is changed, | |
562 | +in any way which causes a break in <em>backwards</em>  compatibility, | |
563 | +the <em>API version number</em>  indication, | |
564 | +which is embedded within the DLL file name, | |
565 | +<em>must</em>  be incremented, | |
566 | +(by at least one, but it may be by more), | |
567 | +resulting in a corresponding change in the DLL file name. | |
568 | +</li> | |
569 | +<li>In the event that any MinGW DLL is published, <em>without</em>  | |
570 | +embedding an <em>API version number</em>  in the file name, | |
571 | +then the most recent release of this DLL <em>must</em>  be | |
572 | +<em>backwardly compatible</em>  with <em>every</em>  | |
573 | +previous release of any MinGW DLL with the same name. | |
574 | +</li></ul> | |
575 | +<p>Adoption of these conventions ensures that, | |
576 | +if the most recent release of each, and every required MinGW DLL is installed, | |
577 | +at an appropriate location within the DLL directory search path, | |
578 | +then, on account of the promise of <em>backwards compatibility</em>,  | |
579 | +applications which are dependent on any releases of these DLLs | |
580 | +will continue to operate as intended. | |
581 | +Additionally, it allows releases of mutually incompatible, | |
582 | +similarly named (but for the version identifier) DLLs to co‑exist, | |
583 | +within the DLL search path, | |
584 | +thus ensuring that applications which may depend on older, | |
585 | +incompatible DLL versions, | |
586 | +may continue to operate correctly. | |
587 | +</p> | |
588 | +<p>Unfortunately, the conventions alone <em>cannot</em>  | |
589 | +prevent any user, or third‑party package installer, | |
590 | +from replacing the most recent MinGW release of any DLL with an older release, | |
591 | +(or with an incompatible third‑party DLL with the same name). | |
592 | +Since <em>forward compatibility</em>  is <em>never</em>  promised, | |
593 | +for an older MinGW DLL release used in conjunction with an application | |
594 | +which may be dependent on a more recent release, | |
595 | +(nor is there <em>any</em>  expectation of <em>any form of | |
596 | +compatibility</em>  from <em>any</em>  third‑party DLL), | |
597 | +it becomes incumbent upon the user, | |
598 | +to ensure that <em>only</em>  the most recent | |
599 | +releases of MinGW DLLs are (and remain) installed. | |
600 | +</p> | |
601 | +</div><!-- conclusion --> | |
602 | + | |
603 | +<!-- $RCSfile$: end of file --> |
@@ -86,6 +86,9 @@ HOWTO Interpret the Names of Packages Distributed by MinGW.OSDN | ||
86 | 86 | <dt><a target="_blank" href="index.html?page=pkgspec.html"> |
87 | 87 | HOWTO Write Specifications for Packages to be Distributed by MinGW.OSDN |
88 | 88 | </a></dt> |
89 | +<dt><a target="_blank" href="index.html?page=pkgspec.html"> | |
90 | +HOWTO Manage a Collection of Installed MinGW Dynamic Link Libraries | |
91 | +</a></dt> | |
89 | 92 | </dl><!-- setup --> |
90 | 93 | |
91 | 94 | <dl class="toc overlapped" id="build"> |