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