NameDateSize

..24-Oct-201935

abi/06-Nov-20126

auditd_plugins/06-Nov-20127

brand/06-Nov-20129

c_synonyms/06-Nov-201210

cfgadm_plugins/15-Aug-201914

commpage/12-May-20197

crt/22-Aug-20199

crypt_modules/06-Nov-201210

efcode/16-Aug-201918

extendedFILE/06-Nov-20127

fm/06-Nov-201219

getloginx/08-Oct-20139

gss_mechs/06-Nov-20126

hal/06-Nov-20126

hbaapi/16-Aug-201911

iconv_modules/22-Aug-201919

inc.flg06-Nov-20121.3 KiB

json_nvlist/21-Jan-20194

krb5/06-Nov-201212

libadm/16-Aug-201910

libads/16-Aug-20199

libadt_jni/14-Jan-201911

libadutils/16-Aug-20199

libaio/06-Nov-20129

libast/16-Aug-201912

libavl/13-Feb-201911

libbc/06-Feb-20189

libbe/06-Feb-20189

libbrand/16-Aug-201310

libbsdmalloc/14-Jan-201911

libbsm/29-Oct-201917

libc/12-May-201920

libc_db/16-Aug-20199

libcfgadm/14-Jan-201910

libcmd/16-Aug-201912

libcmdutils/28-Aug-201810

libcommputil/06-Nov-20129

libcontract/06-Nov-20129

libcpc/16-Aug-20199

libcrypt/16-Aug-201910

libcryptoutil/16-Aug-201910

libctf/16-Aug-201911

libcurses/16-Aug-20199

libcustr/14-Jan-20199

libdemangle/05-Jul-201911

libdevice/13-Feb-201911

libdevid/13-Feb-201912

libdevinfo/16-Aug-201925

libdhcpagent/24-Oct-20199

libdhcputil/16-Aug-201912

libdiagcode/06-Nov-20123

libdisasm/16-Aug-201910

libdiskmgt/16-Aug-20199

libdladm/16-Aug-201910

libdll/16-Aug-201912

libdlpi/16-Aug-20199

libdns_sd/27-Feb-20199

libdoor/06-Nov-20129

libds/06-Nov-20127

libdscp/13-Feb-20199

libdtrace/16-Aug-20199

libdtrace_jni/16-Aug-201910

libdwarf/11-Feb-201911

libefi/14-Jan-20199

libelfsign/06-Nov-20128

libeti/06-Nov-20127

libexacct/16-Aug-201911

libfakekernel/23-May-20199

libfcoe/06-Feb-20189

libfdisk/16-Aug-20198

libficl/27-Sep-201911

libfru/12-Oct-201919

libfruutils/16-Aug-201910

libfsmgt/16-Aug-20197

libfstyp/16-Dec-20129

libgen/16-Aug-201910

libgrubmgmt/21-Apr-20157

libgss/16-Aug-201951

libhotplug/06-Nov-20129

libidmap/06-Feb-20189

libilb/06-Feb-20189

libima/14-Jan-201911

libinetsvc/16-Aug-20197

libinetutil/14-Jan-20199

libinstzones/14-Jan-201910

libintl/06-Nov-20129

libipadm/16-Aug-20198

libipd/06-Nov-20139

libipmi/08-Sep-20199

libipmp/11-Nov-20197

libipp/13-Feb-201911

libipsecutil/16-Aug-20199

libiscsit/30-Jul-20189

libjedec/07-Aug-20199

libkmf/06-Nov-201210

libkrb5/16-Jun-20199

libkstat/06-Nov-201210

libkvm/16-Aug-201910

libldap5/16-Aug-201913

liblgrp/06-Nov-20129

liblm/06-Nov-20129

libm/12-May-201911

libm1/18-Oct-20149

libmail/06-Nov-201210

libmalloc/06-Nov-20129

libmapid/16-Aug-20197

libmapmalloc/06-Nov-20129

libmd/06-Jun-201912

libmd5/06-Nov-20129

libmlrpc/04-Apr-20189

libmp/06-Nov-20129

libmtmalloc/16-Aug-201910

libmvec/12-May-201914

libndmp/16-Aug-20199

libnisdb/12-Oct-201990

libnls/06-Nov-20129

libnsl/16-Aug-201924

libnvpair/16-Aug-201914

libnwam/16-Aug-20199

libofmt/14-Jan-20199

libpam/16-Aug-201914

libpcidb/13-Apr-20139

libpcp/16-Aug-20196

libpctx/12-Aug-20199

libpicl/13-Feb-201912

libpicltree/16-Aug-201911

libpkg/16-Aug-20197

libpool/16-Aug-201910

libpp/16-Aug-201910

libpri/06-Nov-20127

libproc/16-Aug-20199

libproject/16-Aug-20199

libprtdiag/16-Aug-20197

libprtdiag_psr/06-Nov-20124

libpthread/06-Nov-20129

libraidcfg/14-Jan-20199

librcm/13-Feb-201914

libreparse/06-Nov-20129

libresolv/16-Aug-201918

libresolv2/14-Jan-201915

librestart/14-Jan-20199

librpcsvc/16-Aug-20199

librsc/13-Feb-20195

librsm/14-Jan-201910

librstp/14-Jan-20197

librt/06-Nov-20129

libsasl/14-Jan-201914

libsaveargs/01-Mar-20198

libscf/16-Aug-201912

libsched/06-Nov-20129

libsctp/06-Nov-20129

libsec/16-Aug-201910

libsecdb/20-Aug-201917

libsendfile/06-Nov-20129

libsff/31-Mar-20189

libshare/16-Aug-201913

libshell/16-Aug-201915

libsip/14-Jan-20199

libsldap/16-Aug-201910

libslp/16-Aug-201911

libsmbfs/16-Aug-201911

libsmbios/23-Feb-20179

libsmedia/06-Nov-20125

libsocket/16-Aug-201911

libsqlite/16-Aug-201913

libsrpt/06-Feb-20189

libstmf/14-Jan-20199

libstmfproxy/06-Feb-20189

libsum/14-Jan-201912

libsun_ima/14-Jan-20199

libsys/06-Jun-20198

libsysevent/03-Jul-201913

libtecla/14-Jan-201913

libtermcap/06-Nov-20129

libthread/06-Nov-20129

libtnf/06-Nov-201222

libtnfctl/16-Aug-201941

libtnfprobe/16-Aug-201927

libtsalarm/06-Nov-20126

libtsnet/16-Aug-20199

libtsol/16-Aug-20199

libumem/12-Aug-201910

libuuid/06-Nov-20129

libuutil/14-Jan-201911

libv12n/16-Aug-20197

libvolmgt/06-Nov-201210

libvrrpadm/06-Feb-201810

libvscan/14-Jan-20197

libw/06-Nov-20129

libwrap/16-Aug-201931

libxcurses/16-Aug-201910

libxcurses2/16-Aug-201911

libxnet/06-Nov-20129

libzfs/29-Aug-201910

libzfs_core/06-Feb-20189

libzfs_jni/14-Jan-20199

libzonecfg/16-Aug-201910

libzoneinfo/16-Dec-20129

libzonestat/16-Aug-20199

libzpool/27-Sep-20199

madv/16-Aug-20199

Makefile07-Aug-201914.3 KiB

Makefile.asthdr06-Nov-20123.7 KiB

Makefile.astmsg06-Nov-20123.1 KiB

Makefile.filter.com06-Nov-20122.9 KiB

Makefile.filter.targ06-Nov-20121.4 KiB

Makefile.lib28-Sep-20198.5 KiB

Makefile.lib.6406-Nov-20121.1 KiB

Makefile.mach06-Nov-20121.7 KiB

Makefile.rootfs06-Nov-20121.1 KiB

Makefile.targ12-May-20192.9 KiB

mergeq/11-Feb-20196

mpapi/06-Nov-20125

mpss/16-Aug-20199

nametoaddr/06-Nov-20124

ncad_addr/30-Jul-20189

nsswitch/16-Aug-201913

pam_modules/09-Oct-201428

passwdutil/16-Aug-201926

pkcs11/06-Nov-201211

policykit/15-Jul-20186

print/25-Mar-201711

pylibbe/18-Dec-201810

pysolaris/18-Dec-20189

pyzfs/01-Feb-20199

raidcfg_plugins/24-Oct-20133

README.Makefiles24-Oct-201921.9 KiB

README.mapfiles24-Oct-201520.3 KiB

req.flg03-Oct-20171.2 KiB

rpcsec_gss/16-Aug-201913

sasl_plugins/16-Aug-201911

scsi/06-Nov-201210

smbclnt/14-Mar-20199

smbsrv/17-May-201912

smhba/16-Aug-201911

storage/06-Nov-20126

sun_fc/12-Oct-20199

sun_sas/30-Oct-20199

udapl/06-Nov-20125

watchmalloc/14-Jan-20199

README.Makefiles

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
25Writing Library Makefiles in ON
26===============================
27
28Introduction
29------------
30
31This document guides you through the gnarly process of writing library
32Makefiles for the ON consolidation.  It assumes that you're comfortable with
33make(1) and are somewhat familiar with the ON Makefile standards outlined in
34/shared/ON/general_docs/make_std.txt.
35
36Makefile Overview
37-----------------
38
39Your library should consist of a hierarchical collection of Makefiles:
40
41	lib/<library>/Makefile:
42
43	  This is your library's top-level Makefile.  It should contain rules
44	  for building any ISA-independent targets, such as installing header
45	  files and building message catalogs, but should defer all other
46	  targets to ISA-specific Makefiles.
47
48	lib/<library>/Makefile.com
49
50	  This is your library's common Makefile.  It should contain rules
51	  and macros which are common to all ISAs. This Makefile should never
52	  be built explicitly, but instead should be included (using the make
53	  include mechanism) by all of your ISA-specific Makefiles.
54
55	lib/<library>/<isa>/Makefile
56
57	  These are your library's ISA-specific Makefiles, one per ISA
58	  (usually sparc and i386, and often sparcv9 and amd64).  These
59	  Makefiles should include your common Makefile and then provide any
60	  needed ISA-specific rules and definitions, perhaps overriding those
61	  provided in your common Makefile.
62
63To simplify their maintenance and construction, $(SRC)/lib has a handful of
64provided Makefiles that yours must include; the examples provided throughout
65the document will show how to use them.  Please be sure to consult these
66Makefiles before introducing your own custom build macros or rules.
67
68	lib/Makefile.lib:
69
70	  This contains the bulk of the macros for building shared objects.
71
72	lib/Makefile.lib.64
73
74	  This contains macros for building 64-bit objects, and should be
75	  included in Makefiles for 64-bit native ISAs.
76
77	lib/Makefile.rootfs
78
79	  This contains macro overrides for libraries that install into /lib
80	  (rather than /usr/lib).
81
82	lib/Makefile.targ
83
84	  This contains rules for building shared objects.
85
86The remainder of this document discusses how to write each of your Makefiles
87in detail, and provides examples from the libinetutil library.
88
89The Library Top-level Makefile
90------------------------------
91
92As described above, your top-level library Makefile should contain
93rules for building ISA-independent targets, but should defer the
94building of all other targets to ISA-specific Makefiles.  The
95ISA-independent targets usually consist of:
96
97	install_h
98
99	  Install all library header files into the proto area.
100	  Can be omitted if your library has no header files.
101
102	check
103
104	  Check all library header files for hdrchk compliance.
105	  Can be omitted if your library has no header files.
106
107	_msg
108
109	  Build and install a message catalog.
110	  Can be omitted if your library has no message catalog.
111
112Of course, other targets (such as `cstyle') are fine as well, as long as
113they are ISA-independent.
114
115The ROOTHDRS and CHECKHDRS targets are provided in lib/Makefile.lib to make
116it easy for you to install and check your library's header files.  To use
117these targets, your Makefile must set the HDRS to the list of your library's
118header files to install and HDRDIR to the their location in the source tree.
119In addition, if your header files need to be installed in a location other
120than $(ROOT)/usr/include, your Makefile must also set ROOTHDRDIR to the
121appropriate location in the proto area.  Once HDRS, HDRDIR and (optionally)
122ROOTHDRDIR have been set, your Makefile need only contain
123
124	  install_h: $(ROOTHDRS)
125
126	  check: $(CHECKHDRS)
127
128to bind the provided targets to the standard `install_h' and `check' rules.
129
130Similar rules are provided (in $(SRC)/Makefile.msg.targ) to make it easy for
131you to build and install message catalogs from your library's source files.
132
133To install a catalog into the catalog directory in the proto area, define the
134POFILE macro to be the name of your catalog, and specify that the _msg target
135depends on $(MSGDOMAINPOFILE).  The examples below should clarify this.
136
137To build a message catalog from arbitrarily many message source files, use
138the BUILDPO.msgfiles macro.
139
140	  include ../Makefile.lib
141
142	  POFILE =	  libfoo.po
143	  MSGFILES =	  $(OBJECTS:%.o=%.i)
144
145	  # ...
146
147	  $(POFILE): $(MSGFILES)
148		$(BUILDPO.msgfiles)
149
150	  _msg: $(MSGDOMAINPOFILE)
151
152	  include $(SRC)/Makefile.msg.targ
153
154Note that this example doesn't use grep to find message files, since that can
155mask unreferenced files, and potentially lead to the inclusion of unwanted
156messages or omission of intended messages in the catalogs.  As such, MSGFILES
157should be derived from a known list of objects or sources.
158
159It is usually preferable to run the source through the C preprocessor prior
160to extracting messages.  To do this, use the ".i" suffix, as shown in the
161above example.  If you need to skip the C preprocessor, just use the native
162(.[ch]) suffix.
163
164The only time you shouldn't use BUILDPO.msgfiles as the preferred means of
165extracting messages is when you're extracting them from shell scripts; in
166that case, you can use the BUILDPO.pofiles macro as explained below.
167
168To build a message catalog from other message catalogs, or from source files
169that include shell scripts, use the BUILDPO.pofiles macro:
170
171	  include ../Makefile.lib
172
173	  SUBDIRS =	  $(MACH)
174
175	  POFILE =	  libfoo.po
176	  POFILES =	  $(SUBDIRS:%=%/_%.po)
177
178	  _msg :=	  TARGET = _msg
179
180	  # ...
181
182	  $(POFILE): $(POFILES)
183		$(BUILDPO.pofiles)
184
185	  _msg: $(MSGDOMAINPOFILE)
186
187	  include $(SRC)/Makefile.msg.targ
188
189The Makefile above would work in conjunction with the following in its
190subdirectories' Makefiles:
191
192	  POFILE =	  _thissubdir.po
193	  MSGFILES =	  $(OBJECTS:%.o=%.i)
194
195	  $(POFILE):	  $(MSGFILES)
196		  $(BUILDPO.msgfiles)
197
198	  _msg:		  $(POFILE)
199
200	  include $(SRC)/Makefile.msg.targ
201
202Since this POFILE will be combined with those in other subdirectories by the
203parent Makefile and that merged file will be installed into the proto area
204via MSGDOMAINPOFILE, there is no need to use MSGDOMAINPOFILE in this Makefile
205(in fact, using it would lead to duplicate messages in the catalog).
206
207When using any of these targets, keep in mind that other macros, like
208XGETFLAGS and TEXT_DOMAIN may also be set in your Makefile to override or
209augment the defaults provided in higher-level Makefiles.
210
211As previously mentioned, you should defer all ISA-specific targets to your
212ISA-specific Makefiles.  You can do this by:
213
214	1. Setting SUBDIRS to the list of directories to descend into:
215
216		SUBDIRS = $(MACH)
217
218	   Note that if your library is also built 64-bit, then you should
219	   also specify
220
221		$(BUILD64)SUBDIRS += $(MACH64)
222
223	   so that SUBDIRS contains $(MACH64) if and only if you're compiling
224	   on a 64-bit ISA.
225
226	2. Providing a common "descend into SUBDIRS" rule:
227
228		$(SUBDIRS): FRC
229			@cd $@; pwd; $(MAKE) $(TARGET)
230
231		FRC:
232
233	3. Providing a collection of conditional assignments that set TARGET
234	   appropriately:
235
236		all	:= TARGET= all
237		clean	:= TARGET= clean
238		clobber := TARGET= clobber
239		install := TARGET= install
240		lint	:= TARGET= lint
241
242	   The order doesn't matter, but alphabetical is preferable.
243
244	4. Having the aforementioned targets depend on SUBDIRS:
245
246		all clean clobber install lint: $(SUBDIRS)
247
248	   The `all' target must be listed first so that make uses it as the
249	   default target; the others might as well be listed alphabetically.
250
251As an example of how all of this goes together, here's libinetutil's
252top-level library Makefile (license notice and copyright omitted):
253
254	include ../Makefile.lib
255
256	HDRS =		libinetutil.h
257	HDRDIR =	common
258	SUBDIRS =	$(MACH)
259	$(BUILD64)SUBDIRS += $(MACH64)
260
261	all :=		TARGET = all
262	clean :=	TARGET = clean
263	clobber :=	TARGET = clobber
264	install :=	TARGET = install
265	lint :=		TARGET = lint
266
267	.KEEP_STATE:
268
269	all clean clobber install lint: $(SUBDIRS)
270
271	install_h:	$(ROOTHDRS)
272
273	check:		$(CHECKHDRS)
274
275	$(SUBDIRS): FRC
276		@cd $@; pwd; $(MAKE) $(TARGET)
277
278	FRC:
279
280	include ../Makefile.targ
281
282The Common Makefile
283-------------------
284
285In concept, your common Makefile should contain all of the rules and
286definitions that are the same on all ISAs.  However, for reasons of
287maintainability and cleanliness, you're encouraged to place even
288ISA-dependent rules and definitions, as long you express them in an
289ISA-independent way (e.g., by using $(MACH), $(TARGETMACH), and their kin).
290(TARGETMACH is the same as MACH for 32-bit targets, and the same as MACH64
291for 64-bit targets).
292
293The common Makefile can be conceptually split up into four sections:
294
295	1. A copyright and comments section.  Please see the prototype
296	   files in usr/src/prototypes for examples of how to format the
297	   copyright message properly.  For brevity and clarity, this
298	   section has been omitted from the examples shown here.
299
300	2. A list of macros that must be defined prior to the inclusion of
301	   Makefile.lib.  This section is conceptually terminated by the
302	   inclusion of Makefile.lib, followed, if necessary, by the
303	   inclusion of Makefile.rootfs (only if the library is to be
304	   installed in /lib rather than the default /usr/lib).
305
306	3. A list of macros that need not be defined prior to the inclusion
307	   of Makefile.lib (or which must be defined following the inclusion
308	   of Makefile.lib, to override or augment its definitions).  This
309	   section is conceptually terminated by the .KEEP_STATE directive.
310
311	4. A list of targets.
312
313The first section is self-explanatory.  The second typically consists of the
314following macros:
315
316	LIBRARY
317
318	  Set to the name of the static version of your library, such
319	  as `libinetutil.a'.  You should always specify the `.a' suffix,
320	  since pattern-matching rules in higher-level Makefiles rely on it,
321	  even though static libraries are not normally built in ON, and
322	  are never installed in the proto area.  Note that the LIBS macro
323	  (described below) controls the types of libraries that are built
324	  when building your library.
325
326	  If you are building a loadable module (i.e., a shared object that
327	  is only linked at runtime with dlopen(3dl)), specify the name of
328	  the loadable module with a `.a' suffix, such as `devfsadm_mod.a'.
329
330	VERS
331
332	  Set to the version of your shared library, such as `.1'.  You
333	  actually do not need to set this prior to the inclusion of
334	  Makefile.lib, but it is good practice to do so since VERS and
335	  LIBRARY are so closely related.
336
337	OBJECTS
338
339	  Set to the list of object files contained in your library, such as
340	  `a.o b.o'.  Usually, this will be the same as your library's source
341	  files (except with .o extensions), but if your library compiles
342	  source files outside of the library directory itself, it will
343	  differ.  We'll see an example of this with libinetutil.
344
345The third section typically consists of the following macros:
346
347	LIBS
348
349	  Set to the list of the types of libraries to build when building
350	  your library.  For dynamic libraries, you should set this to
351	  `$(DYNLIB) $(LINTLIB)' so that a dynamic library and lint library
352	  are built.  For loadable modules, you should just list DYNLIB,
353	  since there's no point in building a lint library for libraries
354	  that are never linked at compile-time.
355
356	  If your library needs to be built as a static library (typically
357	  to be used in other parts of the build), you should set LIBS to
358	  `$(LIBRARY)'.  However, you should do this only when absolutely
359	  necessary, and you must *never* ship static libraries to customers.
360
361	ROOTLIBDIR (if your library installs to a nonstandard directory)
362
363	  Set to the directory your 32-bit shared objects will install into
364	  with the standard $(ROOTxxx) macros.  Since this defaults to
365	  $(ROOT)/usr/lib ($(ROOT)/lib if you included Makefile.rootfs),
366	  you usually do not need to set this.
367
368	ROOTLIBDIR64 (if your library installs to a nonstandard directory)
369
370	  Set to the directory your 64-bit shared objects will install into
371	  with the standard $(ROOTxxx64) macros.  Since this defaults to
372	  $(ROOT)/usr/lib/$(MACH64) ($(ROOT)/lib/$(MACH64) if you included
373	  Makefile.rootfs), you usually do not need to set this.
374
375	SRCDIR
376
377	  Set to the directory containing your library's source files, such
378	  as `../common'.  Because this Makefile is actually included from
379	  your ISA-specific Makefiles, make sure you specify the directory
380	  relative to your library's <isa> directory.
381
382	SRCS (if necessary)
383
384	  Set to the list of source files required to build your library.
385	  This defaults to $(OBJECTS:%.o=$(SRCDIR)/%.c) in Makefile.lib, so
386	  you only need to set this when source files from directories other
387	  than SRCDIR are needed.  Keep in mind that SRCS should be set to a
388	  list of source file *pathnames*, not just a list of filenames.
389
390	LINTLIB-specific SRCS (required if building a lint library)
391
392	  Set to a special "lint stubs" file to use when constructing your
393	  library's lint library.  The lint stubs file must be used to
394	  guarantee that programs that link against your library will be able
395	  to lint clean.  To do this, you must conditionally set SRCS to use
396	  your stubs file by specifying `LINTLIB := SRCS= $(SRCDIR)/$(LINTSRC)'
397	  in your Makefile.  Of course, you do not need to set this if your
398	  library does not build a lint library.
399
400	LDLIBS
401
402	  Appended with the list of libraries and library directories needed
403	  to build your library; minimally "-lc".  Note that this should
404	  *never* be set, since that will inadvertently clear the library
405	  search path, causing the linker to look in the wrong place for
406	  the libraries.
407
408	  Since lint targets also make use of LDLIBS, LDLIBS *must* only
409	  contain -l and -L directives; all other link-related directives
410	  should be put in DYNFLAGS (if they apply only to shared object
411	  construction) or LDFLAGS (if they apply in general).
412
413	MAPFILES (if necessary)
414
415	  Set to the list of mapfiles used to link each ISA-specific version
416	  of your library.  This defaults to `$(SRCDIR)/mapfile-vers' in
417	  Makefile.lib, so you only need to change this if you have additional
418	  mapfiles or your mapfile doesn't follow the standard naming
419	  convention.  If you have supplemental ISA-dependent mapfiles that
420	  reside in the respective <isa> directories, you can augment
421	  MAPFILES like this:
422
423		MAPFILES += mapfile-vers
424
425	CPPFLAGS (if necessary)
426
427	   Appended with any flags that need to be passed to the C
428	   preprocessor (typically -D and -I flags).  Since lint macros use
429	   CPPFLAGS, CPPFLAGS *must* only contain directives known to the C
430	   preprocessor.  When compiling MT-safe code, CPPFLAGS *must*
431	   include -D_REENTRANT.  When compiling large file aware code,
432	   CPPFLAGS *must* include -D_FILE_OFFSET_BITS=64.
433
434	CFLAGS
435
436	   Appended with any flags that need to be passed to the C compiler.
437	   Minimally, append `$(CCVERBOSE)'.  Keep in mind that you should
438	   add any C preprocessor flags to CPPFLAGS, not CFLAGS.
439
440	CFLAGS64 (if necessary)
441
442	   Appended with any flags that need to be passed to the C compiler
443	   when compiling 64-bit code.  Since all 64-bit code is compiled
444	   $(CCVERBOSE), you usually do not need to modify CFLAGS64.
445
446	COPTFLAG (if necessary)
447
448	   Set to control the optimization level used by the C compiler when
449	   compiling 32-bit code.  You should only set this if absolutely
450	   necessary, and it should only contain optimization-related
451	   settings (or -g).
452
453	COPTFLAG64 (if necessary)
454
455	   Set to control the optimization level used by the C compiler when
456	   compiling 64-bit code.  You should only set this if absolutely
457	   necessary, and it should only contain optimization-related
458	   settings (or -g).
459
460	LINTFLAGS (if necessary)
461
462	   Appended with any flags that need to be passed to lint when
463	   linting 32-bit code.  You should only modify LINTFLAGS in
464	   rare instances where your code cannot (or should not) be fixed.
465
466	LINTFLAGS64 (if necessary)
467
468	   Appended with any flags that need to be passed to lint when
469	   linting 64-bit code.  You should only modify LINTFLAGS64 in
470	   rare instances where your code cannot (or should not) be fixed.
471
472Of course, you may use other macros as necessary.
473
474The fourth section typically consists of the following targets:
475
476	all
477
478	  Build all of the types of the libraries named by LIBS.  Must always
479	  be the first real target in common Makefile.  Since the
480	  higher-level Makefiles already contain rules to build all of the
481	  different types of libraries, you can usually just specify
482
483		all: $(LIBS)
484
485	  though it should be listed as an empty target if LIBS is set by your
486	  ISA-specific Makefiles (see above).
487
488	lint
489
490	  Use the `lintcheck' rule provided by lib/Makefile.targ to lint the
491	  actual library sources.  Historically, this target has also been
492	  used to build the lint library (using LINTLIB), but that usage is
493	  now discouraged.  Thus, this rule should be specified as
494
495		lint: lintcheck
496
497Conspicuously absent from this section are the `clean' and `clobber' targets.
498These targets are already provided by lib/Makefile.targ and thus should not
499be provided by your common Makefile.  Instead, your common Makefile should
500list any additional files to remove during a `clean' and `clobber' by
501appending to the CLEANFILES and CLOBBERFILES macros.
502
503Once again, here's libinetutil's common Makefile, which shows how many of
504these directives go together.  Note that Makefile.rootfs is included to
505cause libinetutil.so.1 to be installed in /lib rather than /usr/lib:
506
507	LIBRARY =	libinetutil.a
508	VERS =		.1
509	OBJECTS =	octet.o inetutil4.o ifspec.o ifaddrlist.o eh.o tq.o
510
511	include ../../Makefile.lib
512	include ../../Makefile.rootfs
513
514	LIBS =		$(DYNLIB) $(LINTLIB)
515
516	SRCDIR =	../common
517	COMDIR =	$(SRC)/common/net/dhcp
518	SRCS =		$(COMDIR)/octet.c $(SRCDIR)/inetutil4.c \
519			$(SRCDIR)/ifspec.c $(SRCDIR)/eh.c $(SRCDIR)/tq.c \
520			$(SRCDIR)/ifaddrlist.c
521
522	$(LINTLIB):=	SRCS = $(SRCDIR)/$(LINTSRC)
523	LDLIBS +=	-lsocket -lc
524
525	CFLAGS +=	$(CCVERBOSE)
526	CPPFLAGS +=	-I$(SRCDIR)
527
528	.KEEP_STATE:
529
530	all: $(LIBS)
531
532	lint: lintcheck
533
534	pics/%.o: $(COMDIR)/%.c
535		$(COMPILE.c) -o $@ $<
536		$(POST_PROCESS_O)
537
538	include ../../Makefile.targ
539
540The mapfile for libinetutil is named `mapfile-vers' and resides in $(SRCDIR),
541so the MAPFILES definition is omitted, defaulting to $(SRCDIR)/mapfile-vers.
542
543Note that for libinetutil, not all of the object files come from SRCDIR.  To
544support this, an alternate source file directory named COMDIR is defined, and
545the source files listed in SRCS are specified using both COMDIR and SRCDIR.
546Additionally, a special build rule is provided to build object files from the
547sources in COMDIR; the rule uses COMPILE.c and POST_PROCESS_O so that any
548changes to the compilation and object-post-processing phases will be
549automatically picked up.
550
551The ISA-Specific Makefiles
552--------------------------
553
554As the name implies, your ISA-specific Makefiles should contain macros and
555rules that cannot be expressed in an ISA-independent way.  Usually, the only
556rule you will need to put here is `install', which has different dependencies
557for 32-bit and 64-bit libraries.  For instance, here are the ISA-specific
558Makefiles for libinetutil:
559
560	sparc/Makefile:
561
562		include ../Makefile.com
563
564		install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
565
566	sparcv9/Makefile:
567
568		include ../Makefile.com
569		include ../../Makefile.lib.64
570
571		install: all $(ROOTLIBS64) $(ROOTLINKS64)
572
573	i386/Makefile:
574
575		include ../Makefile.com
576
577		install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
578
579	amd64/Makefile:
580
581		include ../Makefile.com
582		include ../../Makefile.lib.64
583
584		install: all $(ROOTLIBS64) $(ROOTLINKS64)
585
586Observe that there is no .KEEP_STATE directive in these Makefiles, since all
587of these Makefiles include libinetutil/Makefile.com, and it already has a
588.KEEP_STATE directive.  Also, note that the 64-bit Makefiles also include
589Makefile.lib.64, which overrides some of the definitions contained in the
590higher level Makefiles included by the common Makefile so that 64-bit
591compiles work correctly.
592
593CTF Data in Libraries
594---------------------
595
596By default, all position-independent objects are built with CTF data using
597ctfconvert, which is then merged together using ctfmerge when the shared
598object is built.  All C-source objects processed via ctfmerge need to be
599processed via ctfconvert or the build will fail.  Objects built from non-C
600sources (such as assembly or C++) are silently ignored for CTF processing.
601
602Filter libraries that have no source files will need to explicitly disable
603CTF by setting CTFMERGE_LIB to ":"; see libw/Makefile.com for an example.
604
605More Information
606----------------
607
608Other issues and questions will undoubtedly arise while you work on your
609library's Makefiles.  To help in this regard, a number of libraries of
610varying complexity have been updated to follow the guidelines and practices
611outlined in this document:
612
613	lib/libdhcputil
614
615	  Example of a simple 32-bit only library.
616
617	lib/libdhcpagent
618
619	  Example of a simple 32/64-bit library that obtains its sources
620	  from multiple directories.
621
622	lib/ncad_addr
623
624	  Example of a simple loadable module.
625
626	lib/libipmp
627
628	  Example of a simple library that builds a message catalog.
629
630	lib/libdhcpsvc
631
632	  Example of a Makefile hierarchy for a library and a collection
633	  of related pluggable modules.
634
635	lib/lvm
636
637	  Example of a Makefile hierarchy for a collection of related
638	  libraries and pluggable modules.
639
640	  Also an example of a Makefile hierarchy that supports the
641	  _dc target for domain and category specific messages.
642
643Of course, if you still have questions, please do not hesitate to send email
644to the ON gatekeepers.
645

README.mapfiles

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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23#
24
25Mapfiles and versioning in illumos
26==================================
27
281.0 Objective of this README
29
30This README describes the engineering practices of creating and updating
31visible library interfaces.  It describes various kinds of actions that
32typically occur as libraries are evolved, and shows how interface
33specifications are affected or updated in accordance.  It tells you what
34you must do as a shared library developer if you:
35
36	1. Make interface additions to an existing library
37		- add a Public interface
38		- add a Private interface
39	2. Update an interface in an existing library
40		- remove an existing interface
41		- promote a Private interface to Public
42		- scope a Private interface to local
43		- move an interface from one library to another
44		- copy interfaces which are part of the standard to a new or
45		  existing library
46	3. Introduce a new library
47		- source directory hierarchy
48		- creation of the "mapfile-vers" file
49		- Makefiles
50	4. Make an entire library obsolete before end-of-life
51		- introduce SUNWobsolete to the "mapfile-vers" file
52
53-------------------------------------------------------------------------------
54
552.0 What's a mapfile?
56
57Mapfiles are used to tell the link-editor ("ld") all sorts of things about
58how to generate an executable file or a shared object from a collection of
59relocatable objects, such as generated by a compiler.  For all the gory
60details, see the Solaris Linker and Libraries Guide.
61
62There are two versions of the mapfile language accepted by the link-editor.
63Version 1 derives from AT&T System V Release 4 Unix. Version 2 is a newer
64syntax specific to Solaris and derivatives.  All mapfiles in illumos are
65required to use version 2 syntax. Note that every mapfile using version 2
66syntax must start with the line:
67
68        $mapfile_version 2
69
70Here, we are only concerned with specifying externally-visible interfaces
71for shared libraries (shared objects) and with specifying their versions
72for ABI (Application Binary Interface) purposes.  For these purposes, we
73only need to deal with a subset of the mapfile language.
74
75There should be a "mapfile-vers" file associated with every shared library
76and it should reside in the common source directory for that library, most
77often in a "common" directory.  This is the usual layout of a library's
78top-level directory (usr/src/lib/libwombat):
79	Makefile       amd64/         i386/          sparcv9/
80	Makefile.com   common/        sparc/
81
82The "common" directory contains the source files and other common files
83for the library:
84	bat.c              libwombat_impl.h   mapfile-vers       wom.c
85	libwombat.h        llib-lwombat       util.c             wombat.c
86
87The mapfile's name is, by convention, "mapfile-vers" because it is used
88for only two purposes: to specify externally-visible interface names while
89suppressing visibility of all other names, and to specify their respective
90unique version names.
91
92-------------------------------------------------------------------------------
93
943.0 Contents of mapfile-vers
95
96The structure of mapfile-vers is best explained by an example
97(the license notification and copyright notice is omitted here
98for brevity):
99
100$mapfile_version 2
101
102SYMBOL_VERSION ILLUMOS_0.2 {	# Second interface change in illumos
103    global:
104	wb_notify;
105} ILLUMOS_0.1;
106
107SYMBOL_VERSION ILLUMOS_0.1 {	# First interface change in illumos
108    global:
109	wb_poll;
110} SUNW_1.2;    
111
112SYMBOL_VERSION SUNW_1.2 {	# update to libwombat, Solaris 10
113    global:
114	wb_readv;
115	wb_stat;
116	wb_writev;
117} SUNW_1.1;
118
119SYMBOL_VERSION SUNW_1.1 {	# first release of libwombat, Solaris 9
120    global:
121	wb_read;
122	wb_write;
123};
124
125SYMBOL_VERSION SUNWprivate {	# private libwombat symbols
126    global:
127	wb_add;
128	wb_delete;
129	wb_search;
130    local:
131	*;
132};
133
134Each of these sections is a version declaration describing an ABI version of
135the library containing the set of symbols exposed by the library to
136external callers.
137
138ABI versions must be constant, that is version ILLUMOS_0.2 in a given
139library must always describe the same interface such that applications may
140safely state their dependencies in terms of these versions and have a
141constant and predictable ABI be exposed.  This in effect means that once a
142version is publicly visible, it may never be removed or have symbols added
143to or removed from it.
144
145ABI versions with the same major number should be upward compatible, that is
146ILLUMOS_0.3 of a given library must contain all the interfaces in
147ILLUMOS_0.2, and they must be compatible.
148
149The private version, however, is special, and describes any private yet
150exposed symbols within a library, and may change at any time (and without
151notice).  It exists purely to allow certain symbols to be of global scope
152but not Public.  Similarly, any symbols scoped local are private and may
153change safely, even if the local statement happens to be within a public
154version.
155
156Interface changes made in illumos should be done with ILLUMOS_0.* versions,
157introducing one version per interface change.  In illumos, unlike Solaris,
158symbol versions are not release-specific because of the requirement that
159each be constant.  No change should be made to add or remove symbols from
160any pre-existing Public version.
161
162The SUNW_*.* names were the Public version names of the library in Solaris.
163There should be at most one version name for each release of Solaris, with
164the minor number incremented by one over the previous version.  No changes
165should ever be made to SUNW_1.* versions.
166
167So, for example, to add a new interface to libwombat in illumos one would add:
168
169SYMBOL_VERSION ILLUMOS_0.3 {	# Third update to libwombat in illumos
170    global:
171	wb_lseek;
172} ILLUMOS_0.2;
173
174Each version must inherit all symbols from its preceding version, specified at
175the ending "}" for each version. The initial public version does not inherit
176any symbols.  The private version named either "SUNWprivate" for libraries
177with private symbols pre-existing illumos, or "ILLUMOSprivate" otherwise
178stands alone, inheriting nothing and being inherited by nothing.
179
180The two lines in SUNWprivate:
181    local:
182	*;
183ensure that no symbols other than those listed in the mapfile are visible to
184clients of the library.  If there is no private version, these two lines should
185appear in the first public version.
186
187For maintainability, the list of names in each version block should
188be sorted in dictionary order (sort -d).  Please comply.
189
190The version 2 mapfile language supports a simple mechanism for conditional
191input, in which lines in the mapfile apply only to a specific platform or
192ELFCLASS (32/64-bit). This mechanism works very much like the #if/#endif
193feature of the C preprocessor. For instance, the following mapfile declares
194a version SUNW_1.1 that always exports a symbol foo, and also exports
195the symbol bar on 32-bit sparc platforms:
196
197$mapfile_version 2
198SYMBOL_VERSION SUNW_1.1 {
199        foo;
200$if _sparc && _ELF32
201	bar;
202$endif
203};
204
205Conditional input can be used if there are ISA-specific library interfaces
206not common to all instances of the library. It is the preferred method for
207expressing platform specific items, as long as the differences are simple
208(which is almost always the case).  For example, see libproc, or, if you
209are masochistic, libc or libnsl.  In general, use of this feature should be
210minimal.
211
212In addition to conditional input, there is a second heavier weight mechanism
213for expressing ISA-specific differences. In addition to the common mapfile:
214	common/mapfile-vers
215some libraries may have ISA-specific supplemental mapfiles, one in each
216of the ISA directories:
217	amd64/mapfile-vers
218	i386/mapfile-vers
219	sparc/mapfile-vers
220	sparcv9/mapfile-vers
221The ISA-specific mapfiles look like the common mapfile, except that only
222the ISA-specific names appear.  The version names are the same as those
223in the common mapfile, but only non-empty version instances are present
224and no inheritance specification is present. The link-editor reads the
225information from the common and ISA-specific mapfiles and merges them
226in memory into a single description used to create the resulting object.
227
228ISA-specific mapfiles were used with the version 1 mapfile language, which
229lacked conditional input. Their use is rare now, as conditional input is
230generally preferred. However, it is important to use conditional input
231carefully, or the resulting mapfile can be extremly difficult to read.
232
233-------------------------------------------------------------------------------
234
2354.0 Making interface additions to an existing library
236
2374.1 Adding a Public interface
238
239Public interfaces should be added to a new ILLUMOS_ symbol version, with the
240minor number incremented by one from the current highest version name. If
241this is the first Public interface in the shared object, a new ILLUMOS_0.1
242version name must be introduced.
243
244The major revision number is incremented whenever an incompatible change is
245made to an interface.  This could be the case if an API changes so
246dramatically as to invalidate dependencies.  This should almost never occur
247in practice.  It also requires changing the suffix of the shared object
248from, say, .so.1 to .so.2 and introducing code to continue to ship the .so.1
249version of the library.
250
251The minor revision number is incremented whenever one or more new interfaces
252is added to a library.  Once a version comes to exist in illumos, it is from
253that point onward considered to be immutable.
254
2554.2 Adding a Private interface
256
257Private interfaces are the non-ABI interfaces of the library.  Unlike
258introducing a Public interface, a new entry is simply added to the
259private version.  No minor number increment is necessary.
260
261If this interface happens to be the first Private interface introduced into
262the library, the private version must be created (with no major.minor
263version numbers).  It inherits nothing, nothing inherits from it and it
264should be named ILLUMOSprivate.
265
266If the library already has Private interfaces in a SUNWprivate version, you
267should use that.  They may have numbered version names like SUNWprivate_m.n
268(due to errors of the past).  If so, just use the highest numbered private
269version name to version the new interface.  There is no need to introduce a
270new private version name.  Be careful not to use a lower numbered private
271version name; doing so can cause runtime errors (as opposed to load time
272errors) when running an application with older versions of the library.
273
274There are also libraries in illumos that contain only private interfaces. In
275such libraries, the private versions maybe legitimately be versioned and
276they may be incremented to ensure that the programs that depend on them are
277built and delivered as a integrated unit. A notable example of this is
278libld.so (usr/src/cmd/sgs/libld), which contains the implementation of the
279link-editor, the public interface to which is provided by the ld
280command. When making a modification to the interface of such a library, you
281should follow the convention already in place.
282
2834.3 Historical handling of Solaris update releases.
284
285To aid the understanding of our existing mapfiles, it is useful to note how
286interface versions were handled as they interacted with update releases of
287Solaris.  Solaris update releases required careful coordination with the full
288release currently under development to keep symbol versions constant between
289releases.
290
291Multiple update releases were generally shipped during the development of the
292next full release of Solaris.  It was impossible to know in advance the full
293set of new interfaces in the next full release until it was complete.  Some,
294though not all, new interfaces were included in the intervening update
295releases between full releases.
296
297Consequently, the new version number for an update cannot be a minor
298increment, but must be a micro increment to ensure that was a distinct
299version between the two releases.  For example, if Release N had version
300number SUNW_1.3 and Release N+1 had SUNW_1.4, then interfaces added to
301an update of Release N must have micro numbers such as SUNW_1.3.1,
302SUNW_1.3.2, etc.  (note that the micro number is not directly tied to the
303update number: SUNW_1.3.1 may have appeared in Update 2).  The micro versions form
304an inheritance chain that is inserted between two successive minor versions.
305For example, the mapfile-vers file for minor release "N+1" to reflect its
306inclusion of micro releases will look like the following:
307
308$mapfile_version 2
309
310SYMBOL_VERSION SUNW_1.4 {	# release N+1
311    global:
312	...
313} SUNW_1.3.2;
314
315SYMBOL_VERSION SUNW_1.3.2 {	# micro release 2 (e.g., release NU3)
316    global:
317	...
318} SUNW_1.3.1;
319
320SYMBOL_VERSION SUNW_1.3.1 {	# micro release 1 (e.g., release NU2)
321    global:
322	...
323} SUNW_1.3;
324
325SYMBOL_VERSION SUNW_1.3 {	# release N
326    global:
327	...
328} SUNW_1.2;
329
330SYMBOL_VERSION SUNW_1.2 {	# release N-1
331    global:
332	...
333} SUNW_1.1;
334
335SYMBOL_VERSION SUNW_1.1 {	# first release
336    global:
337	...
338};
339
340SYMBOL_VERSION SUNW_private {	# same in all releases
341    global:
342	...
343    local:
344	*;
345};
346
347The corresponding update/patch mapfile-vers file will be identical
348except for the exclusion of SUNW_1.4.
349
350Those interfaces which are only present in Release N+1 are always put
351into the next minor version set, SUNW_1.4.
352
353Thus when adding a new Public interface to an update release, both the mapfiles
354of the update release and next full release should have been modified to be
355consistent.
356
357There have been several cases of accidental deviation from this scheme, and
358existing mapfiles sometimes reflect this unfortunate state of affairs.
359
360-------------------------------------------------------------------------------
361
3625.0 How to update an interface in an existing library
363
3645.1 Removing an existing interface
365
3665.1.1 Moving a Public interface
367
368No Public interfaces should ever be removed from any mapfile, as this will
369break all existing consumers of that interface.
370
371To move an interface from one library to (say) libc, the code has to be
372deleted from the library and added to libc, then the mapfile for the
373library has to have the interface's entry changed from:
374	getfoobar;
375to:
376	getfoobar       { TYPE = FUNCTION; FILTER = libc.so.1 };
377This is an exception to the immutability of public symbol versions.  See,
378for example, libnsl's common/mapfile-vers file.
379
380Follow the rules for adding a new interface for the necessary changes
381to libc's mapfile to accommodate the moved interface, including creating a
382new version in libc for the symbol.
383
384When merging an entire library into libc, the mapfile is changed to specify
385the type of each public symbol similarly to the above:
386	getfoobar;
387to:
388	getfoobar       { TYPE = FUNCTION };
389
390But rather than specifying the library on which we filter for each symbol,
391the link-editor is invoked with '-F libc.so.1' to specify that our entire
392symbol table is a filter on libc.  For examples, see libaio and librt.
393
3945.1.2 Removing a Private interface
395
396Deletion of Private interfaces is allowed, but caution should be taken;
397it should first be established that the interface is not being used.
398To remove a Private interface, simply delete the corresponding entry
399for that symbol from the mapfile's private version section.
400
401Do not forget to delete these Public or Private interfaces from the library's
402header files as well as from the code that implements the interfaces.
403
4045.2 Promoting a Private interface to Public
405
406This is similar to what's done when adding a Public interface.  Promoting an
407existing Private interface to a Public one only requires a change to the
408existing interface definition.  Private interfaces have the symbol version
409name "ILLUMOSprivate" or "SUNWprivate" associated with them.  To make the
410interface a Public one, the interface must be added as if it were a new
411public symbol, following those same rules and removed from the private
412version.
413
414As an example, if we were modifying libwombat.so.1 and its existing latest
415version were ILLUMOS_0.3, any new ABI would be put into a version called
416ILLUMOS_0.4.  Therefore, whether you wish to promote an existing Private
417interface to Public, or to introduce a new Public interface, this (next
418successive minor numbered version level) would be the version that it would
419be associated with.
420
4215.3 Scoping a Private interface local
422
423Any interfaces not present in the mapfile-vers file will be scoped local
424due to the presence of the
425    local:
426	*;
427lines discussed earlier. This ensures that such interfaces will not be visible
428outside the library.  To move an interface from Private to local scope, simply
429remove the Private interface from the mapfile-vers file and the header file
430to prevent it from being exported.  This may require moving the Private
431interface into a library-private header file.  Scope reduction of Public
432interfaces is forbidden.
433
434For the interface to be used in more than one file within the library, it
435should be in a header file that can be included by each file in the library
436that uses the interface.  For example:
437
438	#include "libprivate.h"
439
4405.4 How to copy interfaces which are part of a standard to a new or existing
441    library
442
443SYSVABI and SISCD are reserved version names for interfaces listed in the
444System V Interface Definition and the Sparc Compliance Definition.  Avoid using
445these version names when copying the implementation of standard interfaces to
446another library.  Instead, use ILLUMOS_0.1 for a new library, and ILLUMOS_m.n for
447an existing library (where m.n is the next version; i.e., if the
448last version was ILLUMOS_0.8, then you should version the interfaces with
449ILLUMOS_0.9).
450
451-------------------------------------------------------------------------------
452
4536.0 Introducing a new library
454
4556.1 Directories
456
457The normal discipline for introducing a new library in illumos is to create a
458new subdirectory of usr/src/lib.  The interface definition discipline is to
459create a common/mapfile-vers file for the new library.  If we were introducing
460a new foo library, libfoo, we'd create usr/src/lib/libfoo containing:
461	Makefile       amd64/         i386/          sparcv9/
462	Makefile.com   common/        sparc/
463The common subdirectory would contain the normal source files plus the
464mapfile-vers file.  See usr/src/lib/README.Makefiles for directions on
465how to organize the Makefiles.
466
4676.2 The mapfile
468
469The new common/mapfile-vers file would contain:
470
471$mapfile_version 2
472
473SYMBOL_VERSION ILLUMOS_0.1 {	# first release of libfoo
474    global:
475	...
476};
477
478SYMBOL_VERSION ILLUMOSprivate {
479    global:
480	...
481    local:
482	*;
483};
484
485If there are no Public interfaces, the ILLUMOS_0.1 section would be omitted.
486If there are no Private interfaces, the ILLUMOSprivate section would be
487omitted and the two lines:
488    local:
489	*;
490would be moved into ILLUMOS_0.1.
491
492To decide which interfaces are Public (part of the ABI) and which are
493Private (unstable interfaces not intended to be used by third parties), the
494heuristic which works to a first approximation is that if it has a man page
495then it's Public.
496
497For maintainability, the list of names in each version block should
498be sorted in dictionary order (sort -d).  Please comply.
499
500-------------------------------------------------------------------------------
501
5027.0 Make an entire library obsolete
503
5047.1 Introduce SUNWobsolete version
505
506Use this version name not for specific interfaces but for marking an entire
507library as obsolete.  The existing public/private version names are left
508unchanged, but a new SUNWobsolete version is created with no symbols in it.
509This becomes a tag by which the obsolescence of the library can be recognized.
510There is no numbering of this version name.
511
512$mapfile_version 2
513
514SYMBOL_VERSION SUNWobsolete {
515    global:
516	SUNWobsolete;	# This is the only way to do it.
517} SUNW_1.2;
518
519SYMBOL_VERSION ILLUMOS_0.2 {
520...
521
522You should continue to use the name SUNWobsolete even in illumos.
523
524-------------------------------------------------------------------------------
525
5268.0 Documentation
527
528For further information, please refer to the following documents:
529
530	"Solaris Linker and Libraries Guide"
531