xref: /illumos-gate/usr/src/lib/README.mapfiles (revision 99ebb4ca412cb0a19d77a3899a87c055b9c30fa8)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21#
22# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25# ident	"%Z%%M%	%I%	%E% SMI"
26#
27
28Mapfiles and versioning in ON
29=============================
30
311.0 Objective of this README
32
33This README describes the engineering practices of creating and updating
34visible library interfaces.  It describes various kinds of actions that
35typically occur as libraries are evolved, and shows how interface
36specifications are affected or updated in accordance.  It tells you what
37you must do as a shared library developer if you:
38
39	1. Make interface additions to an existing library
40		- add a Public interface
41		- add a Private interface
42	2. Update an interface in an existing library
43		- remove an existing interface
44		- promote a Private interface to Public
45		- scope a Private interface to local
46		- move an interface from one library to another
47		- copy interfaces which are part of the standard to a new or
48		  existing library
49	3. Introduce a new library
50		- source directory hierarchy
51		- creation of the "mapfile-vers" file
52		- Makefiles
53	4. Make an entire library obsolete before end-of-life
54		- introduce SUNWobsolete to the "mapfile-vers" file
55
56-------------------------------------------------------------------------------
57
582.0 What's a mapfile?
59
60Mapfiles are used to tell the link editor ("ld") all sorts of things about
61how to generate an executable file or a shared object from a collection of
62relocatable objects, such as generated by a compiler.  For all the gory
63details, see the Solaris Linker and Libraries Guide, which can be found
64under http://docs.sun.com.
65
66Here, we are only concerned with specifying externally-visible interfaces
67for shared libraries (shared objects) and with specifying their versions
68for ABI (Application Binary Interface) purposes.  For these purposes, we
69only need to deal with a subset of the mapfile interfaces.
70
71There should be a "mapfile-vers" file associated with every shared library
72and it should reside in the common source directory for that library, most
73often in a "common" directory.  This is the usual layout of a library's
74top-level directory (usr/src/lib/libwombat):
75	Makefile       amd64/         i386/          sparcv9/
76	Makefile.com   common/        sparc/
77
78The "common" directory contains the source files and other common files
79for the library:
80	bat.c              libwombat_impl.h   mapfile-vers       wom.c
81	libwombat.h        llib-lwombat       util.c             wombat.c
82
83The mapfile's name is, by convention, "mapfile-vers" because it is used
84for only two purposes: to specify externally-visible interface names while
85suppressing visibility of all other names, and to specify their respective
86unique version names.
87
88-------------------------------------------------------------------------------
89
903.0 Contents of mapfile-vers
91
92The structure of mapfile-vers is best explained by an example
93(the license notification and copyright notice is omitted here
94for brevity):
95
96SUNW_1.2 {	# update to libwombat, Solaris 10
97    global:
98	wb_readv;
99	wb_stat;
100	wb_writev;
101} SUNW_1.1;
102
103SUNW_1.1 {	# first release of libwombat, Solaris 9
104    global:
105	wb_read;
106	wb_write;
107};
108
109SUNWprivate {	# private libwombat symbols
110    global:
111	wb_add;
112	wb_delete;
113	wb_search;
114    local:
115	*;
116};
117
118The SUNW_1.* names are the Public version names for the library.
119There should be at most one version name for each release of Solaris,
120with the minor number incremented by one over the previous version.
121
122If no update to the Public-visible names in the library is made
123in a given Solaris release, no new version name should be generated
124for that release.  If multiple updates are made to the library at
125different points in the development of a given release of Solaris,
126only one version should be used for the entire release.
127
128So, for example, if an update to libwombat is made in Solaris 11,
129you would add "SUNW_1.3" at the start of the mapfile:
130
131SUNW_1.3 {	# update to libwombat, Solaris 11
132    global:
133	wb_lseek;
134} SUNW_1.2;
135
136Each version must inherit all symbols from its preceding version,
137specified at the ending "}" for each version.  SUNW_1.1 does not
138inherit any symbols.  SUNWprivate, if present, stands alone.
139
140The two lines in SUNWprivate:
141    local:
142	*;
143ensure that no symbols other than those listed in the mapfile are
144visible to clients of the library.  If there is no SUNWprivate,
145these two lines should appear in SUNW_1.1.
146
147For maintainability, the list of names in each version block should
148be sorted in dictionary order (sort -d).  Please comply.
149
150In addition to the common mapfile:
151	common/mapfile-vers
152some libraries require ISA-specific supplemental mapfiles, one in each
153of the ISA directories:
154	amd64/mapfile-vers
155	i386/mapfile-vers
156	sparc/mapfile-vers
157	sparcv9/mapfile-vers
158This is necessary only if there are ISA-specific library interfaces not
159common to all instances of the library.  For example, see libproc, or,
160if you are masochistic, libc or libnsl.
161
162The ISA-specific mapfiles look like the common mapfile, except that only
163the ISA-specific names appear.  The version names are the same as those
164in the common mapfile, but only non-empty version instances are present
165and no inheritance specification is present.
166
167-------------------------------------------------------------------------------
168
1694.0 Making interface additions to an existing library
170
1714.1 Adding a Public interface
172
173The first engineer to update the existing mapfile-vers file in a release needs
174to identify the current highest version name and properly increment the minor
175version number by 1 to be the new version name.  If this is the first Public
176interface in the shared object, a new SUNW_1.1 version name must be introduced.
177
178The major revision number is incremented whenever an incompatible change is
179made to an interface.  This could be the case if an API changes so dramatically
180as to invalidate dependencies.  This rarely occurs in practice.  It also
181requires changing the suffix of the shared object from, say, .so.1 to .so.2
182and introducing code to continue to ship the .so.1 version of the library.
183
184The minor revision number is incremented whenever one or more new interfaces
185is added to a library.  Note that the minor number is not incremented on every
186putback that makes an interface addition to the library.  Rather, it is
187incremented at most once per (external to Sun) release of the library.
188
1894.2 Adding a Private interface
190
191Private interfaces are the non-ABI interfaces of the library.  Unlike
192introducing a Public interface, a new entry is simply added to the
193SUNWprivate version.  No minor number increment is necessary.
194
195If this interface happens to be the first Private interface introduced
196into the library, the SUNWprivate version must be created (no major.minor
197version numbers).  It inherits nothing and nothing inherits from it.
198
199If the library already has Private interfaces, they may have numbered version
200names like SUNWprivate_m.n (due to errors of the past).  If so, just use the
201highest numbered private version name to version the new interface.  There
202is no need to introduce a new private version name.  Be careful not to use
203a lower numbered private version name; doing so can cause runtime errors
204(as opposed to load time errors) when running an application with older
205versions of the library.
206
2074.3 Adding new public interfaces in an update release
208
209Adding new public interfaces in an update release requires careful
210coordination with the next marketing release currently under development.
211Multiple updates ship during the period before the next marketing release
212ships, and since it is generally impossible to know the full set of new
213interfaces in the next marketing release until late in its development
214(after multiple updates have shipped) it must be assumed that not all
215interfaces added to the next marketing release will be added to an update.
216
217Consequently, the new version number for an update cannot be a minor
218increment, but must be a micro increment.  For example, if Release N
219has version number SUNW_1.3 and Release N+1 will have SUNW_1.4, then
220interfaces added to an update of Release N must have micro numbers such
221as SUNW_1.3.1, SUNW_1.3.2, etc.  (note that the micro number is not
222directly tied to the update number: SUNW_1.3.1 may appear in Update 2).
223The micro versions form an inheritance chain that is inserted between
224two successive minor versions.  For example, the mapfile-vers file for
225minor release "N+1" to reflect its inclusion of micro releases will
226look like the following:
227
228SUNW_1.4 {		# release N+1
229    global:
230	...
231} SUNW_1.3.2;
232
233SUNW_1.3.2 {		# micro release 2 (e.g., release NU3)
234    global:
235	...
236} SUNW_1.3.1;
237
238SUNW_1.3.1 {		# micro release 1 (e.g., release NU2)
239    global:
240	...
241} SUNW_1.3;
242
243SUNW_1.3 {		# release N
244    global:
245	...
246} SUNW_1.2;
247
248SUNW_1.2 {		# release N-1
249    global:
250	...
251} SUNW_1.1;
252
253SUNW_1.1 {		# first release
254    global:
255	...
256};
257
258SUNW_private {		# same in all releases
259    global:
260	...
261    local:
262	*;
263};
264
265The corresponding update/patch mapfile-vers file will be identical
266except for the exclusion of SUNW_1.4.
267
268Those interfaces which are only present in Release N+1 are always put
269into the next minor version set, SUNW_1.4.
270
271Thus when adding a new public interface to an update, both the mapfiles
272of the update release and next marketing release must be modified to be
273consistent.  The update versions should not be added to the marketing
274release until the putback to the update release has occurred, to avoid
275timing problems with the update releases (it's all too easy for projects
276to slip out of updates, or to change ordering).
277
278-------------------------------------------------------------------------------
279
2805.0 How to update an interface in an existing library
281
2825.1 Removing an existing interface
283
2845.1.1 Moving a Public interface
285
286No Public interfaces should ever be removed from any mapfile.
287
288To move an interface from one library to (say) libc, the code has to be
289deleted from the library and added to libc, then the mapfile for the
290library has to have the interface's entry changed from:
291	getfoobar;
292to:
293	getfoobar = FUNCTION FILTER libc.so.1;
294See, for example, libnsl's common/mapfile-vers file.
295
296Follow the rules for adding a new interface for the necessary changes
297to libc's mapfile to accommodate the moved interface.  In particular,
298the new interface must be added to the current highest libc version.
299
300To move an entire library into libc, look at what has already been done
301for libthread, libaio, and librt.
302
3035.1.2 Removing a Private interface
304
305Deletion of Private interfaces is allowed, but caution should be taken;
306it should first be established that the interface is not being used.
307To remove a Private interface, simply delete the corresponding entry
308for that symbol from the mapfile's SUNWprivate section.
309
310Do not forget to delete these Public or Private interfaces from the library's
311header files as well as from the code that implements the interfaces.
312
3135.2 Promoting a Private interface to Public
314
315This is similar to what's done when adding a Public interface.  Promoting an
316existing Private interface to a Public one only requires a change to the
317existing interface definition.  Private interfaces have the symbol version name
318"SUNWprivate" associated with them.  To make the interface a Public one, the
319interface must be put into a set associated with the current Public release
320level of the library.
321
322As an example, if we were modifying libwombat.so.1 and its version in the
323last release of Solaris was SUNW_1.23, any new ABI introduced in the next
324release would be put into a version called SUNW_1.24.  Therefore, whether
325you wish to promote an existing Private interface to Public, or to introduce
326a new Public interface, this (next successive minor numbered version level)
327would be the version that it would be associated with.
328
3295.3 Scoping a Private interface local
330
331Any interfaces not present in the mapfile-vers file will automatically be
332scoped local (i.e., they will not be visible outside the library).  Simply
333remove the Private interface from the mapfile-vers file and the header file
334to prevent it from being exported.  This may require moving the Private
335interface into a library-private header file.  Scope reduction of Public
336interfaces is not allowed.
337
338For the interface to be used in more than one file within the library, it
339should be in a header file that can be included by each file in the library
340that uses the interface.  For example:
341
342	#include "libprivate.h"
343
3445.4 How to copy interfaces which are part of a standard to a new or existing
345    library
346
347SYSVABI and SISCD are reserved version names for interfaces listed in the
348System V Interface Definition and the Sparc Compliance Definition.  Avoid using
349these version names when copying the implementation of standard interfaces to
350another library.  Instead, use SUNW_1.1 for a new library, and SUNW_m.n for
351an existing library (where m.n is the next release version; i.e., if the
352last version was SUNW_1.18, then you should version the interfaces with
353SUNW_1.19).
354
355-------------------------------------------------------------------------------
356
3576.0 Introducing a new library
358
3596.1 Directories
360
361The normal discipline for introducing a new library in OS/Net is to create a
362new subdirectory of /usr/src/lib.  The interface definition discipline is to
363create a common/mapfile-vers file for the new library.  If we were introducing
364a new foo library, libfoo, we'd create /usr/src/lib/libfoo containing:
365	Makefile       amd64/         i386/          sparcv9/
366	Makefile.com   common/        sparc/
367The common subdirectory would contain the normal source files plus the
368mapfile-vers file.  See usr/src/lib/README.Makefiles for directions on
369how to organize the Makefiles.
370
3716.2 The mapfile
372
373The new common/mapfile-vers file would contain:
374
375SUNW_1.1 {	# first release of libfoo
376    global:
377	...
378};
379
380SUNWprivate {
381    global:
382	...
383    local:
384	*;
385};
386
387If there are no Public interfaces, the SUNW_1.1 section would be omitted.
388If there are no Private interfaces, the SUNWprivate section would be
389omitted and the two lines:
390    local:
391	*;
392would be moved into SUNW_1.1
393
394To decide which interfaces are Public (part of the ABI) and which are Private
395(unstable interfaces not intended to be used by third party applications or
396unbundled products), the heuristic which works to a first approximation is
397that if it has a man page then it's Public.  Also, it is really the ARC case
398for the new interfaces that prescribes which interfaces are Public and
399which are not (hence, which interfaces have man pages and which do not).
400
401For maintainability, the list of names in each version block should
402be sorted in dictionary order (sort -d).  Please comply.
403
404-------------------------------------------------------------------------------
405
4067.0 Make an entire library obsolete
407
4087.1 Introduce SUNWobsolete version
409
410Use this version name not for specific interfaces but for marking an entire
411library as obsolete.  The existing public/private version names are left
412unchanged, but a new SUNWobsolete version is created with no symbols in it.
413This becomes a tag by which the obsolescence of the library can be recognized.
414There is no numbering of this version name.
415
416SUNWobsolete {
417    global:
418	SUNWobsolete;	# This is the only way to do it.
419} SUNW_1.2;
420
421SUNW_1.2 {
422...
423
424-------------------------------------------------------------------------------
425
4268.0 Documentation
427
428For further information, please refer to the following documents:
429
430	"Solaris Linker and Libraries Guide", http://docs.sun.com
431	/shared/ON/general_docs/scoping-rules.fm.ps
432
433For information on the now-obsolete spec files, used in Solaris releases
4347 through 10, see:
435	/shared/ON/general_docs/README.spec
436	/shared/ON/general_docs/libspec-rules.ps
437	/shared/ON/general_docs/spectrans/*
438