Name Date Size

.. 2016-11-29 09:43:18 34

abi 2012-09-23 01:47:23 6

auditd_plugins 2016-10-15 06:02:16 7

brand 2016-10-15 06:02:16 9

c_synonyms 2010-06-25 02:16:42 10

cfgadm_plugins 2016-02-27 17:52:10 14

common 2016-01-05 23:18:25 9

crypt_modules 2014-03-14 00:19:45 10

efcode 2013-08-16 17:31:32 18

extendedFILE 2010-06-25 02:16:42 7

fm 2016-02-27 17:52:10 19

getloginx 2013-10-08 22:41:54 9

gss_mechs 2015-10-26 15:17:47 6

hal 2012-05-08 12:52:36 6

hbaapi 2012-09-23 01:47:23 11

inc.flg 2005-06-14 09:00:00 1.3 KiB

krb5 2013-08-30 20:41:32 12

libadm 2012-09-23 01:47:23 10

libads 2015-10-26 15:17:47 9

libadt_jni 2010-06-25 02:16:42 11

libadutils 2015-10-26 15:17:47 9

libaio 2010-06-25 02:16:42 9

libast 2012-09-23 01:47:23 12

libavl 2015-08-14 00:17:03 12

libbc 2016-02-05 09:22:07 9

libbe 2016-09-22 20:43:41 9

libbrand 2016-06-10 16:13:55 10

libbsdmalloc 2010-06-25 02:16:42 11

libbsm 2016-10-15 06:02:16 17

libc 2016-11-17 16:12:22 20

libc_db 2015-10-27 01:00:53 9

libcfgadm 2012-09-23 01:47:23 10

libcmd 2012-09-23 01:47:23 12

libcmdutils 2016-05-19 16:45:52 10

libcommputil 2010-06-25 02:16:42 9

libcontract 2016-02-27 17:52:10 9

libcpc 2012-09-23 01:47:23 9

libcrypt 2013-07-29 22:18:07 10

libcryptoutil 2014-06-06 20:58:03 10

libctf 2014-02-25 06:53:36 9

libcurses 2015-09-19 16:07:23 9

libdevice 2012-09-23 01:47:23 12

libdevid 2010-06-25 02:16:42 13

libdevinfo 2012-09-23 01:47:23 26

libdhcpagent 2016-08-20 00:03:12 8

libdhcputil 2014-11-04 21:33:26 12

libdiagcode 2005-06-14 09:00:00 3

libdisasm 2015-11-09 22:56:32 10

libdiskmgt 2016-02-27 17:52:10 9

libdladm 2016-10-17 22:52:20 10

libdll 2012-09-23 01:47:23 12

libdlpi 2014-04-30 01:58:01 9

libdns_sd 2016-07-22 16:39:00 13

libdoor 2010-06-25 02:16:42 9

libds 2010-06-25 02:16:42 7

libdscfg 2012-09-23 01:47:23 7

libdscp 2010-06-25 02:16:42 10

libdtrace 2016-08-26 01:32:27 9

libdtrace_jni 2015-05-05 06:02:30 10

libefi 2015-10-31 01:11:09 9

libelfsign 2010-06-25 02:16:42 8

libeti 2012-09-23 01:47:23 7

libexacct 2012-09-23 01:47:23 11

libfakekernel 2015-11-06 06:22:30 9

libfcoe 2010-06-25 02:16:42 9

libfdisk 2012-12-10 22:18:44 8

libficl 2016-10-23 18:57:07 12

libfru 2016-10-28 01:30:25 19

libfruutils 2012-09-23 01:47:23 10

libfsmgt 2013-08-30 20:41:32 7

libfstyp 2012-12-10 22:18:44 9

libgen 2012-09-23 01:47:23 10

libgrubmgmt 2015-04-08 00:04:51 7

libgss 2013-08-13 06:01:49 52

libhotplug 2012-09-23 01:47:23 9

libidmap 2015-10-06 20:16:49 9

libilb 2010-06-28 17:19:17 9

libima 2013-07-25 22:29:05 11

libinetsvc 2012-09-23 01:47:23 7

libinetutil 2015-07-30 22:57:56 9

libinstzones 2012-12-10 22:18:44 10

libintl 2010-06-25 02:16:42 9

libipadm 2014-12-31 18:27:36 8

libipd 2013-11-06 17:09:36 9

libipmi 2012-04-26 17:49:44 9

libipmp 2010-06-25 02:16:42 7

libipp 2016-02-27 17:52:10 12

libipsecutil 2012-09-23 01:47:23 9

libiscsit 2015-11-03 02:56:54 9

libkmf 2016-03-03 19:58:54 10

libkrb5 2015-10-26 15:17:47 9

libkstat 2015-11-05 17:59:04 10

libkvm 2013-08-03 01:16:57 10

libldap5 2015-10-26 15:17:47 13

liblgrp 2010-06-25 02:16:42 9

liblm 2010-06-25 02:16:42 9

libm 2016-02-14 22:10:58 11

libm1 2014-10-18 00:00:52 9

libmail 2010-06-25 02:16:42 10

libmalloc 2014-07-20 01:07:30 9

libmapid 2012-09-23 01:47:23 7

libmapmalloc 2014-07-20 01:07:30 9

libmd 2015-10-07 06:07:36 12

libmd5 2010-06-25 02:16:42 9

libmp 2010-06-25 02:16:42 9

libmtmalloc 2014-07-20 01:07:30 10

libmvec 2015-02-08 23:01:02 14

libndmp 2015-01-08 19:05:15 9

libnisdb 2015-08-07 04:16:40 90

libnls 2012-09-23 01:47:23 9

libnsctl 2010-06-25 02:16:42 7

libnsl 2016-04-04 23:19:37 24

libnvpair 2015-11-18 00:19:53 15

libnwam 2016-02-27 17:52:10 9

libpam 2012-09-23 01:47:23 15

libpcidb 2013-04-12 00:35:10 9

libpcp 2012-09-23 01:47:23 6

libpctx 2010-06-25 02:16:42 9

libpicl 2010-06-25 02:16:42 13

libpicltree 2012-09-23 01:47:23 12

libpkg 2015-09-22 20:01:25 9

libpool 2016-02-27 17:52:10 10

libpp 2012-09-23 01:47:23 10

libpri 2010-06-25 02:16:42 7

libproc 2016-10-15 06:02:16 9

libproject 2014-01-14 17:55:45 9

libprtdiag 2012-09-23 01:47:23 7

libprtdiag_psr 2016-03-09 19:46:02 4

libpthread 2010-06-25 02:16:42 9

libraidcfg 2012-09-23 01:47:23 9

librcm 2016-02-27 17:52:10 15

librdc 2012-09-23 01:47:23 7

libreparse 2011-04-19 19:31:18 9

libresolv 2015-07-23 19:13:23 18

libresolv2 2015-10-26 15:17:47 15

librestart 2016-10-15 06:02:16 9

librpcsvc 2015-07-02 19:53:15 9

librsc 2009-10-08 01:55:54 5

librsm 2012-09-23 01:47:23 10

librstp 2012-02-18 19:52:02 7

librt 2010-06-25 02:16:42 9

libsasl 2013-07-29 22:18:07 14

libsaveargs 2013-03-17 23:53:58 8

libscf 2016-10-24 17:22:12 12

libsched 2010-06-25 02:16:42 9

libsctp 2010-06-25 02:16:42 9

libsec 2014-03-20 21:15:14 10

libsecdb 2016-10-15 06:02:16 17

libsendfile 2010-06-25 02:16:42 9

libshare 2016-11-18 20:15:55 13

libshell 2015-04-14 15:50:37 15

libsip 2010-06-25 02:16:42 9

libsldap 2013-08-30 20:41:32 10

libslp 2015-05-05 06:02:30 11

libsmbfs 2015-11-02 20:48:29 11

libsmbios 2016-10-21 00:34:17 9

libsmedia 2013-10-11 15:54:00 5

libsocket 2015-02-21 02:10:02 11

libsqlite 2016-10-03 14:55:14 14

libsrpt 2010-06-30 17:18:21 9

libstmf 2012-09-23 01:47:23 9

libstmfproxy 2010-06-25 02:16:42 9

libsum 2012-09-23 01:47:23 12

libsun_ima 2012-09-23 01:47:23 9

libsys 2010-06-25 02:16:42 8

libsysevent 2016-02-27 17:52:10 14

libtecla 2012-09-23 01:47:23 13

libtermcap 2011-07-15 16:20:38 9

libthread 2010-06-25 02:16:42 9

libtnf 2012-09-23 01:47:23 22

libtnfctl 2012-09-23 01:47:23 42

libtnfprobe 2012-09-23 01:47:23 27

libtsalarm 2010-06-25 02:16:42 6

libtsnet 2012-09-23 01:47:23 9

libtsol 2012-09-23 01:47:23 9

libumem 2016-08-20 00:01:59 10

libunistat 2012-09-23 01:47:23 7

libuuid 2015-04-13 01:04:38 9

libuutil 2016-01-06 22:11:32 11

libv12n 2012-09-23 01:47:23 7

libvolmgt 2012-09-23 01:47:23 10

libvrrpadm 2013-08-08 18:20:06 10

libvscan 2010-06-25 02:16:42 7

libw 2010-06-25 02:16:42 9

libwanboot 2015-05-05 06:02:29 11

libwanbootutil 2013-08-30 20:41:32 11

libwrap 2014-01-05 22:00:31 32

libxcurses 2015-11-02 20:48:29 10

libxcurses2 2015-11-02 20:48:29 11

libxnet 2011-11-19 00:32:51 9

libzfs 2016-11-29 09:43:18 10

libzfs_core 2016-11-29 09:43:18 9

libzfs_jni 2016-06-09 21:55:53 9

libzonecfg 2016-10-15 06:02:16 10

libzoneinfo 2012-12-10 22:18:44 9

libzonestat 2012-09-23 01:47:23 9

libzpool 2016-11-24 00:19:42 9

lvm 2016-03-05 16:42:06 8

madv 2013-08-30 20:41:32 9

Makefile 2016-09-22 20:43:38 14 KiB

Makefile.asthdr 2008-12-27 23:59:38 3.7 KiB

Makefile.astmsg 2008-12-27 23:59:38 3.1 KiB

Makefile.filter.com 2009-05-08 01:01:18 2.9 KiB

Makefile.filter.targ 2009-05-08 01:01:18 1.4 KiB

Makefile.lib 2015-11-02 20:48:29 8.5 KiB

Makefile.lib.64 2006-08-09 08:21:36 1.1 KiB

Makefile.mach 2005-06-14 09:00:00 1.7 KiB

Makefile.rootfs 2005-06-14 09:00:00 1.1 KiB

Makefile.targ 2010-06-29 00:32:48 2.8 KiB

mpapi 2012-09-23 01:47:23 5

mpss 2013-08-30 20:41:32 9

nametoaddr 2015-03-13 19:57:35 4

ncad_addr 2010-06-25 02:16:42 9

nsswitch 2015-10-26 15:17:47 13

pam_modules 2016-08-18 17:07:05 28

passwdutil 2012-09-23 01:47:23 27

pkcs11 2014-06-06 20:58:03 11

policykit 2013-08-16 17:31:32 6

print 2015-04-21 23:32:31 12

pylibbe 2016-09-30 04:49:32 9

pysolaris 2016-09-30 04:49:32 7

pyzfs 2016-09-30 04:49:32 7

raidcfg_plugins 2013-10-24 01:52:25 3

README.Makefiles 2006-08-09 08:21:36 21.9 KiB

README.mapfiles 2015-10-24 17:48:06 20.3 KiB

req.flg 2007-05-18 01:27:31 1.2 KiB

rpcsec_gss 2012-09-23 01:47:23 13

sasl_plugins 2013-07-29 22:18:07 11

scsi 2015-12-10 01:07:12 10

smbsrv 2016-04-04 23:19:37 13

smhba 2012-10-02 20:07:55 11

storage 2012-09-23 01:47:23 6

sun_fc 2012-10-02 20:07:55 9

sun_sas 2015-01-24 04:24:44 9

udapl 2012-09-23 01:47:23 5

watchmalloc 2012-09-23 01:47:23 9

README.Makefiles

#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
Writing Library Makefiles in ON
===============================
Introduction
------------
This document guides you through the gnarly process of writing library
Makefiles for the ON consolidation. It assumes that you're comfortable with
make(1) and are somewhat familiar with the ON Makefile standards outlined in
/shared/ON/general_docs/make_std.txt.
Makefile Overview
-----------------
Your library should consist of a hierarchical collection of Makefiles:
lib/<library>/Makefile:
This is your library's top-level Makefile. It should contain rules
for building any ISA-independent targets, such as installing header
files and building message catalogs, but should defer all other
targets to ISA-specific Makefiles.
lib/<library>/Makefile.com
This is your library's common Makefile. It should contain rules
and macros which are common to all ISAs. This Makefile should never
be built explicitly, but instead should be included (using the make
include mechanism) by all of your ISA-specific Makefiles.
lib/<library>/<isa>/Makefile
These are your library's ISA-specific Makefiles, one per ISA
(usually sparc and i386, and often sparcv9 and amd64). These
Makefiles should include your common Makefile and then provide any
needed ISA-specific rules and definitions, perhaps overriding those
provided in your common Makefile.
To simplify their maintenance and construction, $(SRC)/lib has a handful of
provided Makefiles that yours must include; the examples provided throughout
the document will show how to use them. Please be sure to consult these
Makefiles before introducing your own custom build macros or rules.
lib/Makefile.lib:
This contains the bulk of the macros for building shared objects.
lib/Makefile.lib.64
This contains macros for building 64-bit objects, and should be
included in Makefiles for 64-bit native ISAs.
lib/Makefile.rootfs
This contains macro overrides for libraries that install into /lib
(rather than /usr/lib).
lib/Makefile.targ
This contains rules for building shared objects.
The remainder of this document discusses how to write each of your Makefiles
in detail, and provides examples from the libinetutil library.
The Library Top-level Makefile
------------------------------
As described above, your top-level library Makefile should contain
rules for building ISA-independent targets, but should defer the
building of all other targets to ISA-specific Makefiles. The
ISA-independent targets usually consist of:
install_h
Install all library header files into the proto area.
Can be omitted if your library has no header files.
check
Check all library header files for hdrchk compliance.
Can be omitted if your library has no header files.
_msg
Build and install a message catalog.
Can be omitted if your library has no message catalog.
Of course, other targets (such as `cstyle') are fine as well, as long as
they are ISA-independent.
The ROOTHDRS and CHECKHDRS targets are provided in lib/Makefile.lib to make
it easy for you to install and check your library's header files. To use
these targets, your Makefile must set the HDRS to the list of your library's
header files to install and HDRDIR to the their location in the source tree.
In addition, if your header files need to be installed in a location other
than $(ROOT)/usr/include, your Makefile must also set ROOTHDRDIR to the
appropriate location in the proto area. Once HDRS, HDRDIR and (optionally)
ROOTHDRDIR have been set, your Makefile need only contain
install_h: $(ROOTHDRS)
check: $(CHECKHDRS)
to bind the provided targets to the standard `install_h' and `check' rules.
Similar rules are provided (in $(SRC)/Makefile.msg.targ) to make it easy for
you to build and install message catalogs from your library's source files.
To install a catalog into the catalog directory in the proto area, define the
POFILE macro to be the name of your catalog, and specify that the _msg target
depends on $(MSGDOMAINPOFILE). The examples below should clarify this.
To build a message catalog from arbitrarily many message source files, use
the BUILDPO.msgfiles macro.
include ../Makefile.lib
POFILE = libfoo.po
MSGFILES = $(OBJECTS:%.o=%.i)
# ...
$(POFILE): $(MSGFILES)
$(BUILDPO.msgfiles)
_msg: $(MSGDOMAINPOFILE)
include $(SRC)/Makefile.msg.targ
Note that this example doesn't use grep to find message files, since that can
mask unreferenced files, and potentially lead to the inclusion of unwanted
messages or omission of intended messages in the catalogs. As such, MSGFILES
should be derived from a known list of objects or sources.
It is usually preferable to run the source through the C preprocessor prior
to extracting messages. To do this, use the ".i" suffix, as shown in the
above example. If you need to skip the C preprocessor, just use the native
(.[ch]) suffix.
The only time you shouldn't use BUILDPO.msgfiles as the preferred means of
extracting messages is when you're extracting them from shell scripts; in
that case, you can use the BUILDPO.pofiles macro as explained below.
To build a message catalog from other message catalogs, or from source files
that include shell scripts, use the BUILDPO.pofiles macro:
include ../Makefile.lib
SUBDIRS = $(MACH)
POFILE = libfoo.po
POFILES = $(SUBDIRS:%=%/_%.po)
_msg := TARGET = _msg
# ...
$(POFILE): $(POFILES)
$(BUILDPO.pofiles)
_msg: $(MSGDOMAINPOFILE)
include $(SRC)/Makefile.msg.targ
The Makefile above would work in conjunction with the following in its
subdirectories' Makefiles:
POFILE = _thissubdir.po
MSGFILES = $(OBJECTS:%.o=%.i)
$(POFILE): $(MSGFILES)
$(BUILDPO.msgfiles)
_msg: $(POFILE)
include $(SRC)/Makefile.msg.targ
Since this POFILE will be combined with those in other subdirectories by the
parent Makefile and that merged file will be installed into the proto area
via MSGDOMAINPOFILE, there is no need to use MSGDOMAINPOFILE in this Makefile
(in fact, using it would lead to duplicate messages in the catalog).
When using any of these targets, keep in mind that other macros, like
XGETFLAGS and TEXT_DOMAIN may also be set in your Makefile to override or
augment the defaults provided in higher-level Makefiles.
As previously mentioned, you should defer all ISA-specific targets to your
ISA-specific Makefiles. You can do this by:
1. Setting SUBDIRS to the list of directories to descend into:
SUBDIRS = $(MACH)
Note that if your library is also built 64-bit, then you should
also specify
$(BUILD64)SUBDIRS += $(MACH64)
so that SUBDIRS contains $(MACH64) if and only if you're compiling
on a 64-bit ISA.
2. Providing a common "descend into SUBDIRS" rule:
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
FRC:
3. Providing a collection of conditional assignments that set TARGET
appropriately:
all := TARGET= all
clean := TARGET= clean
clobber := TARGET= clobber
install := TARGET= install
lint := TARGET= lint
The order doesn't matter, but alphabetical is preferable.
4. Having the aforementioned targets depend on SUBDIRS:
all clean clobber install lint: $(SUBDIRS)
The `all' target must be listed first so that make uses it as the
default target; the others might as well be listed alphabetically.
As an example of how all of this goes together, here's libinetutil's
top-level library Makefile (license notice and copyright omitted):
include ../Makefile.lib
HDRS = libinetutil.h
HDRDIR = common
SUBDIRS = $(MACH)
$(BUILD64)SUBDIRS += $(MACH64)
all := TARGET = all
clean := TARGET = clean
clobber := TARGET = clobber
install := TARGET = install
lint := TARGET = lint
.KEEP_STATE:
all clean clobber install lint: $(SUBDIRS)
install_h: $(ROOTHDRS)
check: $(CHECKHDRS)
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
FRC:
include ../Makefile.targ
The Common Makefile
-------------------
In concept, your common Makefile should contain all of the rules and
definitions that are the same on all ISAs. However, for reasons of
maintainability and cleanliness, you're encouraged to place even
ISA-dependent rules and definitions, as long you express them in an
ISA-independent way (e.g., by using $(MACH), $(TARGETMACH), and their kin).
(TARGETMACH is the same as MACH for 32-bit targets, and the same as MACH64
for 64-bit targets).
The common Makefile can be conceptually split up into four sections:
1. A copyright and comments section. Please see the prototype
files in usr/src/prototypes for examples of how to format the
copyright message properly. For brevity and clarity, this
section has been omitted from the examples shown here.
2. A list of macros that must be defined prior to the inclusion of
Makefile.lib. This section is conceptually terminated by the
inclusion of Makefile.lib, followed, if necessary, by the
inclusion of Makefile.rootfs (only if the library is to be
installed in /lib rather than the default /usr/lib).
3. A list of macros that need not be defined prior to the inclusion
of Makefile.lib (or which must be defined following the inclusion
of Makefile.lib, to override or augment its definitions). This
section is conceptually terminated by the .KEEP_STATE directive.
4. A list of targets.
The first section is self-explanatory. The second typically consists of the
following macros:
LIBRARY
Set to the name of the static version of your library, such
as `libinetutil.a'. You should always specify the `.a' suffix,
since pattern-matching rules in higher-level Makefiles rely on it,
even though static libraries are not normally built in ON, and
are never installed in the proto area. Note that the LIBS macro
(described below) controls the types of libraries that are built
when building your library.
If you are building a loadable module (i.e., a shared object that
is only linked at runtime with dlopen(3dl)), specify the name of
the loadable module with a `.a' suffix, such as `devfsadm_mod.a'.
VERS
Set to the version of your shared library, such as `.1'. You
actually do not need to set this prior to the inclusion of
Makefile.lib, but it is good practice to do so since VERS and
LIBRARY are so closely related.
OBJECTS
Set to the list of object files contained in your library, such as
`a.o b.o'. Usually, this will be the same as your library's source
files (except with .o extensions), but if your library compiles
source files outside of the library directory itself, it will
differ. We'll see an example of this with libinetutil.
The third section typically consists of the following macros:
LIBS
Set to the list of the types of libraries to build when building
your library. For dynamic libraries, you should set this to
`$(DYNLIB) $(LINTLIB)' so that a dynamic library and lint library
are built. For loadable modules, you should just list DYNLIB,
since there's no point in building a lint library for libraries
that are never linked at compile-time.
If your library needs to be built as a static library (typically
to be used in other parts of the build), you should set LIBS to
`$(LIBRARY)'. However, you should do this only when absolutely
necessary, and you must *never* ship static libraries to customers.
ROOTLIBDIR (if your library installs to a nonstandard directory)
Set to the directory your 32-bit shared objects will install into
with the standard $(ROOTxxx) macros. Since this defaults to
$(ROOT)/usr/lib ($(ROOT)/lib if you included Makefile.rootfs),
you usually do not need to set this.
ROOTLIBDIR64 (if your library installs to a nonstandard directory)
Set to the directory your 64-bit shared objects will install into
with the standard $(ROOTxxx64) macros. Since this defaults to
$(ROOT)/usr/lib/$(MACH64) ($(ROOT)/lib/$(MACH64) if you included
Makefile.rootfs), you usually do not need to set this.
SRCDIR
Set to the directory containing your library's source files, such
as `../common'. Because this Makefile is actually included from
your ISA-specific Makefiles, make sure you specify the directory
relative to your library's <isa> directory.
SRCS (if necessary)
Set to the list of source files required to build your library.
This defaults to $(OBJECTS:%.o=$(SRCDIR)/%.c) in Makefile.lib, so
you only need to set this when source files from directories other
than SRCDIR are needed. Keep in mind that SRCS should be set to a
list of source file *pathnames*, not just a list of filenames.
LINTLIB-specific SRCS (required if building a lint library)
Set to a special "lint stubs" file to use when constructing your
library's lint library. The lint stubs file must be used to
guarantee that programs that link against your library will be able
to lint clean. To do this, you must conditionally set SRCS to use
your stubs file by specifying `LINTLIB := SRCS= $(SRCDIR)/$(LINTSRC)'
in your Makefile. Of course, you do not need to set this if your
library does not build a lint library.
LDLIBS
Appended with the list of libraries and library directories needed
to build your library; minimally "-lc". Note that this should
*never* be set, since that will inadvertently clear the library
search path, causing the linker to look in the wrong place for
the libraries.
Since lint targets also make use of LDLIBS, LDLIBS *must* only
contain -l and -L directives; all other link-related directives
should be put in DYNFLAGS (if they apply only to shared object
construction) or LDFLAGS (if they apply in general).
MAPFILES (if necessary)
Set to the list of mapfiles used to link each ISA-specific version
of your library. This defaults to `$(SRCDIR)/mapfile-vers' in
Makefile.lib, so you only need to change this if you have additional
mapfiles or your mapfile doesn't follow the standard naming
convention. If you have supplemental ISA-dependent mapfiles that
reside in the respective <isa> directories, you can augment
MAPFILES like this:
MAPFILES += mapfile-vers
CPPFLAGS (if necessary)
Appended with any flags that need to be passed to the C
preprocessor (typically -D and -I flags). Since lint macros use
CPPFLAGS, CPPFLAGS *must* only contain directives known to the C
preprocessor. When compiling MT-safe code, CPPFLAGS *must*
include -D_REENTRANT. When compiling large file aware code,
CPPFLAGS *must* include -D_FILE_OFFSET_BITS=64.
CFLAGS
Appended with any flags that need to be passed to the C compiler.
Minimally, append `$(CCVERBOSE)'. Keep in mind that you should
add any C preprocessor flags to CPPFLAGS, not CFLAGS.
CFLAGS64 (if necessary)
Appended with any flags that need to be passed to the C compiler
when compiling 64-bit code. Since all 64-bit code is compiled
$(CCVERBOSE), you usually do not need to modify CFLAGS64.
COPTFLAG (if necessary)
Set to control the optimization level used by the C compiler when
compiling 32-bit code. You should only set this if absolutely
necessary, and it should only contain optimization-related
settings (or -g).
COPTFLAG64 (if necessary)
Set to control the optimization level used by the C compiler when
compiling 64-bit code. You should only set this if absolutely
necessary, and it should only contain optimization-related
settings (or -g).
LINTFLAGS (if necessary)
Appended with any flags that need to be passed to lint when
linting 32-bit code. You should only modify LINTFLAGS in
rare instances where your code cannot (or should not) be fixed.
LINTFLAGS64 (if necessary)
Appended with any flags that need to be passed to lint when
linting 64-bit code. You should only modify LINTFLAGS64 in
rare instances where your code cannot (or should not) be fixed.
Of course, you may use other macros as necessary.
The fourth section typically consists of the following targets:
all
Build all of the types of the libraries named by LIBS. Must always
be the first real target in common Makefile. Since the
higher-level Makefiles already contain rules to build all of the
different types of libraries, you can usually just specify
all: $(LIBS)
though it should be listed as an empty target if LIBS is set by your
ISA-specific Makefiles (see above).
lint
Use the `lintcheck' rule provided by lib/Makefile.targ to lint the
actual library sources. Historically, this target has also been
used to build the lint library (using LINTLIB), but that usage is
now discouraged. Thus, this rule should be specified as
lint: lintcheck
Conspicuously absent from this section are the `clean' and `clobber' targets.
These targets are already provided by lib/Makefile.targ and thus should not
be provided by your common Makefile. Instead, your common Makefile should
list any additional files to remove during a `clean' and `clobber' by
appending to the CLEANFILES and CLOBBERFILES macros.
Once again, here's libinetutil's common Makefile, which shows how many of
these directives go together. Note that Makefile.rootfs is included to
cause libinetutil.so.1 to be installed in /lib rather than /usr/lib:
LIBRARY = libinetutil.a
VERS = .1
OBJECTS = octet.o inetutil4.o ifspec.o ifaddrlist.o eh.o tq.o
include ../../Makefile.lib
include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
SRCDIR = ../common
COMDIR = $(SRC)/common/net/dhcp
SRCS = $(COMDIR)/octet.c $(SRCDIR)/inetutil4.c \
$(SRCDIR)/ifspec.c $(SRCDIR)/eh.c $(SRCDIR)/tq.c \
$(SRCDIR)/ifaddrlist.c
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
LDLIBS += -lsocket -lc
CFLAGS += $(CCVERBOSE)
CPPFLAGS += -I$(SRCDIR)
.KEEP_STATE:
all: $(LIBS)
lint: lintcheck
pics/%.o: $(COMDIR)/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
include ../../Makefile.targ
The mapfile for libinetutil is named `mapfile-vers' and resides in $(SRCDIR),
so the MAPFILES definition is omitted, defaulting to $(SRCDIR)/mapfile-vers.
Note that for libinetutil, not all of the object files come from SRCDIR. To
support this, an alternate source file directory named COMDIR is defined, and
the source files listed in SRCS are specified using both COMDIR and SRCDIR.
Additionally, a special build rule is provided to build object files from the
sources in COMDIR; the rule uses COMPILE.c and POST_PROCESS_O so that any
changes to the compilation and object-post-processing phases will be
automatically picked up.
The ISA-Specific Makefiles
--------------------------
As the name implies, your ISA-specific Makefiles should contain macros and
rules that cannot be expressed in an ISA-independent way. Usually, the only
rule you will need to put here is `install', which has different dependencies
for 32-bit and 64-bit libraries. For instance, here are the ISA-specific
Makefiles for libinetutil:
sparc/Makefile:
include ../Makefile.com
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
sparcv9/Makefile:
include ../Makefile.com
include ../../Makefile.lib.64
install: all $(ROOTLIBS64) $(ROOTLINKS64)
i386/Makefile:
include ../Makefile.com
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
amd64/Makefile:
include ../Makefile.com
include ../../Makefile.lib.64
install: all $(ROOTLIBS64) $(ROOTLINKS64)
Observe that there is no .KEEP_STATE directive in these Makefiles, since all
of these Makefiles include libinetutil/Makefile.com, and it already has a
.KEEP_STATE directive. Also, note that the 64-bit Makefiles also include
Makefile.lib.64, which overrides some of the definitions contained in the
higher level Makefiles included by the common Makefile so that 64-bit
compiles work correctly.
CTF Data in Libraries
---------------------
By default, all position-independent objects are built with CTF data using
ctfconvert, which is then merged together using ctfmerge when the shared
object is built. All C-source objects processed via ctfmerge need to be
processed via ctfconvert or the build will fail. Objects built from non-C
sources (such as assembly or C++) are silently ignored for CTF processing.
Filter libraries that have no source files will need to explicitly disable
CTF by setting CTFMERGE_LIB to ":"; see libw/Makefile.com for an example.
More Information
----------------
Other issues and questions will undoubtedly arise while you work on your
library's Makefiles. To help in this regard, a number of libraries of
varying complexity have been updated to follow the guidelines and practices
outlined in this document:
lib/libdhcputil
Example of a simple 32-bit only library.
lib/libdhcpagent
Example of a simple 32-bit only library that obtains its sources
from multiple directories.
lib/ncad_addr
Example of a simple loadable module.
lib/libipmp
Example of a simple library that builds a message catalog.
lib/libdhcpsvc
Example of a Makefile hierarchy for a library and a collection
of related pluggable modules.
lib/lvm
Example of a Makefile hierarchy for a collection of related
libraries and pluggable modules.
Also an example of a Makefile hierarchy that supports the
_dc target for domain and category specific messages.
Of course, if you still have questions, please do not hesitate to send email
to the ON gatekeepers.

README.mapfiles

#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
#
Mapfiles and versioning in illumos
==================================
1.0 Objective of this README
This README describes the engineering practices of creating and updating
visible library interfaces. It describes various kinds of actions that
typically occur as libraries are evolved, and shows how interface
specifications are affected or updated in accordance. It tells you what
you must do as a shared library developer if you:
1. Make interface additions to an existing library
- add a Public interface
- add a Private interface
2. Update an interface in an existing library
- remove an existing interface
- promote a Private interface to Public
- scope a Private interface to local
- move an interface from one library to another
- copy interfaces which are part of the standard to a new or
existing library
3. Introduce a new library
- source directory hierarchy
- creation of the "mapfile-vers" file
- Makefiles
4. Make an entire library obsolete before end-of-life
- introduce SUNWobsolete to the "mapfile-vers" file
-------------------------------------------------------------------------------
2.0 What's a mapfile?
Mapfiles are used to tell the link-editor ("ld") all sorts of things about
how to generate an executable file or a shared object from a collection of
relocatable objects, such as generated by a compiler. For all the gory
details, see the Solaris Linker and Libraries Guide.
There are two versions of the mapfile language accepted by the link-editor.
Version 1 derives from AT&T System V Release 4 Unix. Version 2 is a newer
syntax specific to Solaris and derivatives. All mapfiles in illumos are
required to use version 2 syntax. Note that every mapfile using version 2
syntax must start with the line:
$mapfile_version 2
Here, we are only concerned with specifying externally-visible interfaces
for shared libraries (shared objects) and with specifying their versions
for ABI (Application Binary Interface) purposes. For these purposes, we
only need to deal with a subset of the mapfile language.
There should be a "mapfile-vers" file associated with every shared library
and it should reside in the common source directory for that library, most
often in a "common" directory. This is the usual layout of a library's
top-level directory (usr/src/lib/libwombat):
Makefile amd64/ i386/ sparcv9/
Makefile.com common/ sparc/
The "common" directory contains the source files and other common files
for the library:
bat.c libwombat_impl.h mapfile-vers wom.c
libwombat.h llib-lwombat util.c wombat.c
The mapfile's name is, by convention, "mapfile-vers" because it is used
for only two purposes: to specify externally-visible interface names while
suppressing visibility of all other names, and to specify their respective
unique version names.
-------------------------------------------------------------------------------
3.0 Contents of mapfile-vers
The structure of mapfile-vers is best explained by an example
(the license notification and copyright notice is omitted here
for brevity):
$mapfile_version 2
SYMBOL_VERSION ILLUMOS_0.2 { # Second interface change in illumos
global:
wb_notify;
} ILLUMOS_0.1;
SYMBOL_VERSION ILLUMOS_0.1 { # First interface change in illumos
global:
wb_poll;
} SUNW_1.2;
SYMBOL_VERSION SUNW_1.2 { # update to libwombat, Solaris 10
global:
wb_readv;
wb_stat;
wb_writev;
} SUNW_1.1;
SYMBOL_VERSION SUNW_1.1 { # first release of libwombat, Solaris 9
global:
wb_read;
wb_write;
};
SYMBOL_VERSION SUNWprivate { # private libwombat symbols
global:
wb_add;
wb_delete;
wb_search;
local:
*;
};
Each of these sections is a version declaration describing an ABI version of
the library containing the set of symbols exposed by the library to
external callers.
ABI versions must be constant, that is version ILLUMOS_0.2 in a given
library must always describe the same interface such that applications may
safely state their dependencies in terms of these versions and have a
constant and predictable ABI be exposed. This in effect means that once a
version is publicly visible, it may never be removed or have symbols added
to or removed from it.
ABI versions with the same major number should be upward compatible, that is
ILLUMOS_0.3 of a given library must contain all the interfaces in
ILLUMOS_0.2, and they must be compatible.
The private version, however, is special, and describes any private yet
exposed symbols within a library, and may change at any time (and without
notice). It exists purely to allow certain symbols to be of global scope
but not Public. Similarly, any symbols scoped local are private and may
change safely, even if the local statement happens to be within a public
version.
Interface changes made in illumos should be done with ILLUMOS_0.* versions,
introducing one version per interface change. In illumos, unlike Solaris,
symbol versions are not release-specific because of the requirement that
each be constant. No change should be made to add or remove symbols from
any pre-existing Public version.
The SUNW_*.* names were the Public version names of the library in Solaris.
There should be at most one version name for each release of Solaris, with
the minor number incremented by one over the previous version. No changes
should ever be made to SUNW_1.* versions.
So, for example, to add a new interface to libwombat in illumos one would add:
SYMBOL_VERSION ILLUMOS_0.3 { # Third update to libwombat in illumos
global:
wb_lseek;
} ILLUMOS_0.2;
Each version must inherit all symbols from its preceding version, specified at
the ending "}" for each version. The initial public version does not inherit
any symbols. The private version named either "SUNWprivate" for libraries
with private symbols pre-existing illumos, or "ILLUMOSprivate" otherwise
stands alone, inheriting nothing and being inherited by nothing.
The two lines in SUNWprivate:
local:
*;
ensure that no symbols other than those listed in the mapfile are visible to
clients of the library. If there is no private version, these two lines should
appear in the first public version.
For maintainability, the list of names in each version block should
be sorted in dictionary order (sort -d). Please comply.
The version 2 mapfile language supports a simple mechanism for conditional
input, in which lines in the mapfile apply only to a specific platform or
ELFCLASS (32/64-bit). This mechanism works very much like the #if/#endif
feature of the C preprocessor. For instance, the following mapfile declares
a version SUNW_1.1 that always exports a symbol foo, and also exports
the symbol bar on 32-bit sparc platforms:
$mapfile_version 2
SYMBOL_VERSION SUNW_1.1 {
foo;
$if _sparc && _ELF32
bar;
$endif
};
Conditional input can be used if there are ISA-specific library interfaces
not common to all instances of the library. It is the preferred method for
expressing platform specific items, as long as the differences are simple
(which is almost always the case). For example, see libproc, or, if you
are masochistic, libc or libnsl. In general, use of this feature should be
minimal.
In addition to conditional input, there is a second heavier weight mechanism
for expressing ISA-specific differences. In addition to the common mapfile:
common/mapfile-vers
some libraries may have ISA-specific supplemental mapfiles, one in each
of the ISA directories:
amd64/mapfile-vers
i386/mapfile-vers
sparc/mapfile-vers
sparcv9/mapfile-vers
The ISA-specific mapfiles look like the common mapfile, except that only
the ISA-specific names appear. The version names are the same as those
in the common mapfile, but only non-empty version instances are present
and no inheritance specification is present. The link-editor reads the
information from the common and ISA-specific mapfiles and merges them
in memory into a single description used to create the resulting object.
ISA-specific mapfiles were used with the version 1 mapfile language, which
lacked conditional input. Their use is rare now, as conditional input is
generally preferred. However, it is important to use conditional input
carefully, or the resulting mapfile can be extremly difficult to read.
-------------------------------------------------------------------------------
4.0 Making interface additions to an existing library
4.1 Adding a Public interface
Public interfaces should be added to a new ILLUMOS_ symbol version, with the
minor number incremented by one from the current highest version name. If
this is the first Public interface in the shared object, a new ILLUMOS_0.1
version name must be introduced.
The major revision number is incremented whenever an incompatible change is
made to an interface. This could be the case if an API changes so
dramatically as to invalidate dependencies. This should almost never occur
in practice. It also requires changing the suffix of the shared object
from, say, .so.1 to .so.2 and introducing code to continue to ship the .so.1
version of the library.
The minor revision number is incremented whenever one or more new interfaces
is added to a library. Once a version comes to exist in illumos, it is from
that point onward considered to be immutable.
4.2 Adding a Private interface
Private interfaces are the non-ABI interfaces of the library. Unlike
introducing a Public interface, a new entry is simply added to the
private version. No minor number increment is necessary.
If this interface happens to be the first Private interface introduced into
the library, the private version must be created (with no major.minor
version numbers). It inherits nothing, nothing inherits from it and it
should be named ILLUMOSprivate.
If the library already has Private interfaces in a SUNWprivate version, you
should use that. They may have numbered version names like SUNWprivate_m.n
(due to errors of the past). If so, just use the highest numbered private
version name to version the new interface. There is no need to introduce a
new private version name. Be careful not to use a lower numbered private
version name; doing so can cause runtime errors (as opposed to load time
errors) when running an application with older versions of the library.
There are also libraries in illumos that contain only private interfaces. In
such libraries, the private versions maybe legitimately be versioned and
they may be incremented to ensure that the programs that depend on them are
built and delivered as a integrated unit. A notable example of this is
libld.so (usr/src/cmd/sgs/libld), which contains the implementation of the
link-editor, the public interface to which is provided by the ld
command. When making a modification to the interface of such a library, you
should follow the convention already in place.
4.3 Historical handling of Solaris update releases.
To aid the understanding of our existing mapfiles, it is useful to note how
interface versions were handled as they interacted with update releases of
Solaris. Solaris update releases required careful coordination with the full
release currently under development to keep symbol versions constant between
releases.
Multiple update releases were generally shipped during the development of the
next full release of Solaris. It was impossible to know in advance the full
set of new interfaces in the next full release until it was complete. Some,
though not all, new interfaces were included in the intervening update
releases between full releases.
Consequently, the new version number for an update cannot be a minor
increment, but must be a micro increment to ensure that was a distinct
version between the two releases. For example, if Release N had version
number SUNW_1.3 and Release N+1 had SUNW_1.4, then interfaces added to
an update of Release N must have micro numbers such as SUNW_1.3.1,
SUNW_1.3.2, etc. (note that the micro number is not directly tied to the
update number: SUNW_1.3.1 may have appeared in Update 2). The micro versions form
an inheritance chain that is inserted between two successive minor versions.
For example, the mapfile-vers file for minor release "N+1" to reflect its
inclusion of micro releases will look like the following:
$mapfile_version 2
SYMBOL_VERSION SUNW_1.4 { # release N+1
global:
...
} SUNW_1.3.2;
SYMBOL_VERSION SUNW_1.3.2 { # micro release 2 (e.g., release NU3)
global:
...
} SUNW_1.3.1;
SYMBOL_VERSION SUNW_1.3.1 { # micro release 1 (e.g., release NU2)
global:
...
} SUNW_1.3;
SYMBOL_VERSION SUNW_1.3 { # release N
global:
...
} SUNW_1.2;
SYMBOL_VERSION SUNW_1.2 { # release N-1
global:
...
} SUNW_1.1;
SYMBOL_VERSION SUNW_1.1 { # first release
global:
...
};
SYMBOL_VERSION SUNW_private { # same in all releases
global:
...
local:
*;
};
The corresponding update/patch mapfile-vers file will be identical
except for the exclusion of SUNW_1.4.
Those interfaces which are only present in Release N+1 are always put
into the next minor version set, SUNW_1.4.
Thus when adding a new Public interface to an update release, both the mapfiles
of the update release and next full release should have been modified to be
consistent.
There have been several cases of accidental deviation from this scheme, and
existing mapfiles sometimes reflect this unfortunate state of affairs.
-------------------------------------------------------------------------------
5.0 How to update an interface in an existing library
5.1 Removing an existing interface
5.1.1 Moving a Public interface
No Public interfaces should ever be removed from any mapfile, as this will
break all existing consumers of that interface.
To move an interface from one library to (say) libc, the code has to be
deleted from the library and added to libc, then the mapfile for the
library has to have the interface's entry changed from:
getfoobar;
to:
getfoobar { TYPE = FUNCTION; FILTER = libc.so.1 };
This is an exception to the immutability of public symbol versions. See,
for example, libnsl's common/mapfile-vers file.
Follow the rules for adding a new interface for the necessary changes
to libc's mapfile to accommodate the moved interface, including creating a
new version in libc for the symbol.
When merging an entire library into libc, the mapfile is changed to specify
the type of each public symbol similarly to the above:
getfoobar;
to:
getfoobar { TYPE = FUNCTION };
But rather than specifying the library on which we filter for each symbol,
the link-editor is invoked with '-F libc.so.1' to specify that our entire
symbol table is a filter on libc. For examples, see libaio and librt.
5.1.2 Removing a Private interface
Deletion of Private interfaces is allowed, but caution should be taken;
it should first be established that the interface is not being used.
To remove a Private interface, simply delete the corresponding entry
for that symbol from the mapfile's private version section.
Do not forget to delete these Public or Private interfaces from the library's
header files as well as from the code that implements the interfaces.
5.2 Promoting a Private interface to Public
This is similar to what's done when adding a Public interface. Promoting an
existing Private interface to a Public one only requires a change to the
existing interface definition. Private interfaces have the symbol version
name "ILLUMOSprivate" or "SUNWprivate" associated with them. To make the
interface a Public one, the interface must be added as if it were a new
public symbol, following those same rules and removed from the private
version.
As an example, if we were modifying libwombat.so.1 and its existing latest
version were ILLUMOS_0.3, any new ABI would be put into a version called
ILLUMOS_0.4. Therefore, whether you wish to promote an existing Private
interface to Public, or to introduce a new Public interface, this (next
successive minor numbered version level) would be the version that it would
be associated with.
5.3 Scoping a Private interface local
Any interfaces not present in the mapfile-vers file will be scoped local
due to the presence of the
local:
*;
lines discussed earlier. This ensures that such interfaces will not be visible
outside the library. To move an interface from Private to local scope, simply
remove the Private interface from the mapfile-vers file and the header file
to prevent it from being exported. This may require moving the Private
interface into a library-private header file. Scope reduction of Public
interfaces is forbidden.
For the interface to be used in more than one file within the library, it
should be in a header file that can be included by each file in the library
that uses the interface. For example:
#include "libprivate.h"
5.4 How to copy interfaces which are part of a standard to a new or existing
library
SYSVABI and SISCD are reserved version names for interfaces listed in the
System V Interface Definition and the Sparc Compliance Definition. Avoid using
these version names when copying the implementation of standard interfaces to
another library. Instead, use ILLUMOS_0.1 for a new library, and ILLUMOS_m.n for
an existing library (where m.n is the next version; i.e., if the
last version was ILLUMOS_0.8, then you should version the interfaces with
ILLUMOS_0.9).
-------------------------------------------------------------------------------
6.0 Introducing a new library
6.1 Directories
The normal discipline for introducing a new library in illumos is to create a
new subdirectory of usr/src/lib. The interface definition discipline is to
create a common/mapfile-vers file for the new library. If we were introducing
a new foo library, libfoo, we'd create usr/src/lib/libfoo containing:
Makefile amd64/ i386/ sparcv9/
Makefile.com common/ sparc/
The common subdirectory would contain the normal source files plus the
mapfile-vers file. See usr/src/lib/README.Makefiles for directions on
how to organize the Makefiles.
6.2 The mapfile
The new common/mapfile-vers file would contain:
$mapfile_version 2
SYMBOL_VERSION ILLUMOS_0.1 { # first release of libfoo
global:
...
};
SYMBOL_VERSION ILLUMOSprivate {
global:
...
local:
*;
};
If there are no Public interfaces, the ILLUMOS_0.1 section would be omitted.
If there are no Private interfaces, the ILLUMOSprivate section would be
omitted and the two lines:
local:
*;
would be moved into ILLUMOS_0.1.
To decide which interfaces are Public (part of the ABI) and which are
Private (unstable interfaces not intended to be used by third parties), the
heuristic which works to a first approximation is that if it has a man page
then it's Public.
For maintainability, the list of names in each version block should
be sorted in dictionary order (sort -d). Please comply.
-------------------------------------------------------------------------------
7.0 Make an entire library obsolete
7.1 Introduce SUNWobsolete version
Use this version name not for specific interfaces but for marking an entire
library as obsolete. The existing public/private version names are left
unchanged, but a new SUNWobsolete version is created with no symbols in it.
This becomes a tag by which the obsolescence of the library can be recognized.
There is no numbering of this version name.
$mapfile_version 2
SYMBOL_VERSION SUNWobsolete {
global:
SUNWobsolete; # This is the only way to do it.
} SUNW_1.2;
SYMBOL_VERSION ILLUMOS_0.2 {
...
You should continue to use the name SUNWobsolete even in illumos.
-------------------------------------------------------------------------------
8.0 Documentation
For further information, please refer to the following documents:
"Solaris Linker and Libraries Guide"