All,

Laca has supplied the last need spec (see attached).  I have placed it
in the case directory as well.  I believe this covers the last issue for the
case.  I will close the case out today COB unless I hear otherwise.

Thanks,

John

On 05/12/10 05:46 AM, John Fischer wrote:
All,

I am extending the timer to Friday, May 14th, to allow Laca to complete his document on the spec files. I'll keep extending the timer until the document is done. He has shown me the document that he is producing and it will resolve this need spec. Therefore, when it is completed and available in the archives I will close the case as approved.

Thanks,

John

On 05/ 7/10 11:00 AM, John Fischer wrote:
Doug,

Does the attached document satisfy this request
for additional documentation?

Laca, if not please provide what Doug is requesting.
I will extend the timer for another few days to address
the request.

Thanks,

John


On 05/ 3/10 09:53 AM, Doug Leavitt wrote:
In addition to the missing definitions for the
Meta(*.*), SUNW*, and IPS* keys commonly deployed
in pkgbuils spec files today, I also noticed that neither
the proposal or the case materials make any reference to

%include Solaris.inc

or any of the include files Solaris.inc ifself includes and
that are generally expected as part of current pkgbuild
spec files,


I believe that this ARC case needs to at least document
and (hopefully) set some level of commitment to the
well defined tag list.

At a minimum this:
http://hub.opensolaris.org/bin/view/Community+Group+sw-porters/specdesc

needs to be included in the ARC materials.

But, I'm sure better documentation than above
should be provided.  Say perhaps a man page or two?

Doug.



On 05/ 1/10 02:16 AM, Brian Cameron wrote:
Albert:

The spec file syntax is also conceptually an exported interface, and it needs a stability level. It would be nice if the spec file syntax were part of the materials (I'm guessing it's documented somewhere anyway).
The basic syntax is the same as rpmbuild spec files, and pkgbuild includes
a set of predefined macros and supports some additional tags
(attributes/keywords): http://pkgbuild.sourceforge.net/man.php
True, although pkgbuild does support some Solaris/OpenSolaris specific
extensions, and it might be good to highlight those a bit more.

For example, one thing I notice is that the new "IPS_package_name"
and "Meta(info.classification)" keys cause syntax errors if you try
to use an older version of pkgbuild.  It would be nice if pkgbuild
had better backwards compatibility support and provided some mechanism
to allow people who just want to build SVR5 packages a way to tell
pkgbuild to ignore keys that provide features that are not going to be
used anyway.

Brian




The description of pkgbuild's spec files


1 Introduction

  pkgbuild uses build "recipes" called spec files to define what sources
  are used for building a component, how to set up the source tree, build
  the binaries and how to package them.

  The spec files used by pkgbuild are similar to RPM's spec files, but
  there are some differences.  Because the resulting package formats
  (SVr4 and/or IPS) have different characteristics from RPM packages,
  pkgbuild uses additional spec file elements not used by RPM and there
  are also many elements of RPM spec files that are ignored by pkgbuild.

  This document describes the pkgbuild's spec file format with an
  emphasis on the differences from RPM spec files.

  A good general introduction to RPM spec files can be found in
  Chapter 13 of Maximum RPM by Edward C. Bailey. The book's ISBN
  is 0672311054 and is available as a PDF at
  http://www.redhat.com/docs/books/max-rpm/max-rpm.pdf or as HTML
  at http://www.rpm.org/max-rpm-snapshot/ch-rpm-inside.html


2 Overview of the format

  Spec files are plain text files.  Lines starting with a # are comments.
  The percent character has a special meaning therefore it has to be
  escaped by another percent character, example:

  ./configure --default-zoom-level="50%%"

  Tags define various attributes of the package, for example the name,
  the locations of sources, build-time and runtime dependencies.

  Lines that define tags start with the name of the tag followed by a
  colon followed by the value of the tag, for example:

  Name: pkgbuild
  Version: 1.3.102

  The %package directive can be used to assign a name to a subset of
  files.  A package usually corresponds to a separate SVr4 and/or IPS
  package.

  A number of shell script fragments (scriptlets) control the build process:
  %prep sets up the source tree from tarballs and/or patches and/or other
  source files.  %build is used to create the binaries.  %install places
  the binaries in a temporary package prototype area in the same layout at
  they will appear in the binary package.  %check performs sanity testing.
  %clean is used to clean up the build directories after the build.  Each
  scriptlet is executed separately, which means that the environment
  variables set in one scriptlet do not affect other scriptlets.

  The binaries in the prototype area are used to create one or more
  packages (SVr4 and/or IPS).  The contents of these packages are
  defined in %files and optionally, in the case of IPS packages, %actions
  sections.  Macros and wildcards (globs) can be used in the package
  definitions.

  pkgbuild allows building hierarchical spec file structures by using
  information from other spec files or including them.  The %use directive
  assigns a label to another spec file.  The label can be used to refer
  to tags, macros and scriptlets in other spec files.  For example:

  %use glib2 = glib2.spec
  ...
  Version: %{glib2.version}

  The %include directive is similar to the #include C preprocessor
  directive.

  While spec files are best written as generic and platform-agnostic as
  possible, sometimes it's necessary to add conditional statements.
  These are similar to the #if / #ifdef C preprocessor directives.

  Spec files include a %changelog section that documents the changes
  made to the file, including the date, the name or email address of
  the person who made the change and the description of the change.


3 Macros

3.1 Macro definitions

  Macros are defined using the %define statement:

  %define project_name pkgbuild

  Macro names can include letters, numbers and underscores (_) and
  they are case-sensitive.

  The percent character is used for expanding macros or tags.  Macro
  or tag names can be enclosed in curly brackets when they would
  otherwise become ambiguous because of the characters that follow
  the macro name, e.g:

  %define _prefix /usr
  %define _lib  lib
  %define _libdir %_prefix/lib

  %_libdir    -->  /usr/lib
  %{_lib}dir  -->  libdir
  %_libfoo    -->  %_libfoo     (undefined macro)
  %{_lib}foo  -->  libfoo

  %project_name  or  %{project_name}
  
  In case of a conflict, tags mask macros:

  Version: 1.0
  %define version 2.0

  %{version} expands to 1.0


3.2 Conditional macro expansion

  Undefined macros do not get expanded.  In most cases this is not
  desirable so conditional macro expansions can be used to deal with
  undefined macros.  The following table summarizes the expansion of
  conditional macros when the "foo" macro is defined and the value
  is "bar" or not defined:

                    |               Expansion when %foo is
  Macro             |    defined as bar        |    undefined
  ------------------+--------------------------+-------------------------
  %foo              |    bar                   |    %foo
  %{?foo}           |    bar                   |    <empty string>
  %{?foo:fred}      |    fred                  |    <empty string>
  %{?!foo:fred}     |    <empty string>        |    fred
  %{!?foo:fred}     |    <empty string>        |    fred

  Macro expansions can be nested:

  %define fred %{?foo}%{!?foo:%{bar}}


3.3 Using the output of external commands

  The %(command) expression can be used to colled the output of
  an external command, just like $(command) or `command` in shell
  scripts:

  %define os_release %(uname -r)


3.4 Predefined macros

  A number of commonly used macros are predefined in the
  macros file under $(libdir)/pkgbuild-$(version).  The most
  useful ones are summarized below:

  Macro name         |      Default value
  -------------------+------------------------------
  %_pkgbuild         | pkgbuild
  %_is_pkgbuild      | 1
  %_pkgbuild_version | <the version of pkgbuild>
  %buildroot         | /var/tmp/<package name>-<version>-build
                     | (this is the location of the proto area)
  %__install         | /usr/bin/ginstall
  %__make            | /usr/bin/make
  %__patch           | /usr/bin/gpatch
  %__perl            | /usr/perl5/bin/perl
  %__python          | /usr/bin/python
  %__strip           | /usr/ccs/bin/strip
  %_topdir           | %{__homedir}/packages
  %_buildshell       | /bin/bash
  %_builddir         | %{_topdir}/BUILD
  %_pkgdir           | %{_topdir}/PKGS
  %_sourcedir        | %{_topdir}/SOURCES
  %_specdir          | %{_topdir}/SPECS
  %_srcpkgdir        | %{_topdir}/SPKGS
  %_pkgmapdir        | %{_topdir}/PKGMAPS
  %_tmppath          | %{_var}/tmp/pkgbuild-%__logname
  %_prefix           | /usr
  %_exec_prefix      | %{_prefix}
  %_bindir           | %{_exec_prefix}/bin
  %_sbindir          | %{_exec_prefix}/sbin
  %_libexecdir       | %{_exec_prefix}/libexec
  %_datadir          | %{_prefix}/share
  %_sysconfdir       | %{_prefix}/etc
  %_sharedstatedir   | %{_prefix}/com
  %_localstatedir    | %{_prefix}/var
  %_lib              | lib
  %_libdir           | %{_exec_prefix}/%{_lib}
  %_includedir       | %{_prefix}/include
  %_oldincludedir    | /usr/include
  %_infodir          | %{_datadir}/info
  %_mandir           | %{_datadir}/man
  %_docdir           | %{_datadir}/doc
  %_pkg_docdir       | %{_docdir}/%{name}

  The following macros can be used to control pkgbuild's behavior:

  %_unpackaged_files_terminate_build      1

    When set to 1, this requires all files in the proto area to be
    included in a binary package.

  %_missing_doc_files_terminate_build     1

    This means that all documentation files flagged with the %doc
    modified in the %files list must exist.

  %_invalid_patches_terminate_build       1

    When set to 0, patches that cannot be applied to the sources
    are skipped and the build continues without them.  The default
    is that all patches must apply.

  %_use_ips_autotag                       1

    When set to 1, automatically add actuators to some well known
    file types (e.g. GNOME .desktop files, desktop icons, gconf schemas)


4 Tags

  Spec files contains lots of information about the component they
  belong to.  Some of this information is used during the build
  process others are directly or indirectly used for in the
  binary packages to describe the package.  Since spec files were
  invented for building RPM packages, not all tags make sense when
  building SVr4 or IPS packages and similarly, there are aspects of
  SVr4 and IPS packages that cannot be described by RPM's tags.

  Most tags are not required and either have a default value or
  can be omitted from the corresponding package's pkginfo or manifest
  file.

  The required tags are Name and Version.  Note that RPM also requires
  Release, License, Summary and Group to be defined.


4.1  pkgbuild-specific tags

  This section describes the tags specific to pkgbuild's spec files
  and explains their use.


  Tags used for Solaris SVr4 packaging are prefixed with SUNW:

  SUNW_BaseDir:
    corresponds to BASEDIR in the pkginfo(4) file, default: /

  SUNW_Pkg:
    the package abbreviation (PKG parameter) in the pkginfo(4),
    defaults to %{name}

  SUNW_ProdName:
    SUNW_PRODNAME in pkginfo(4), omitted from pkginfo if not defined.

  SUNW_ProdVers:
    SUNW_PRODVERS in pkginfo(4), omitted from pkginfo if not defined.

  SUNW_Category:
    CATEGORY in pkginfo(4), default: application

  SUNW_Hotline:
    HOTLINE in pkginfo(4), omitted from pkginfo if not defined.

  SUNW_MaxInst:
    MAXINST in pkginfo(4), omitted from pkginfo if not defined.

  SUNW_Rev:
    REV part of the SVr4 version string.  Defaults to
    $(date +%Y.%m.%d.%H.%M.%S)
    The full SVr4 version string is %{version},REV=%{sunw_rev}

  SUNW_Copyright:
    Name of the copyright file to be included in the prototype(4) file.
    Omitted, if not defined.  The copyright file with the given name
    is expected to be in %_sourcedir (the SOURCES directory in the
    build area).  Copyright files are passed through pkgbuild's parser
    for expanding macros.  This is useful for repeating information
    from the spec file in the copyright file, for example the download
    URL:

    ... the source code was downloaded from %{SOURCE.url} ...

  SUNW_PkgList:
    SUNW_PKGLIST parameter in pkginfo(4), omitted if missing.

  SUNW_Loc:
    SUNW_LOC parameter in pkginfo(4), omitted if missing.

  SUNW_PkgType:
    SUNW_PKGTYPE parameter in pkginfo(4), defaults to "usr" if
    SUNW_BaseDir is /usr, "root, if SUNW_BaseDir is /, omitted
    otherwise.

  SUNW_Desc:
    DESC parameter in pkginfo(4), defaults to %{summary}

  SUNW_Pkg_AllZones:
    SUNW_PKG_ALLZONES in pkginfo(4), omitted from pkginfo if missing.

  SUNW_Pkg_Hollow:
    SUNW_PKG_HOLLOW in pkginfo(4), omitted from pkginfo if missing.

  SUNW_Pkg_ThisZone:
    SUNW_PKG_THISZONE in pkginfo(4), omitted from pkginfo if missing.


  Tags used for building IPS packages are prefixed with "IPS_":

  IPS_Package_Name:
    Defines the name of the IPS package.  Default: %name

  IPS_SourcePackage:
    Defines the name IPS source package.  Default: %{name}/src

  IPS_Component_Version:
    Sets the component version portion of the IPS package version string,
    as described in pkg(5).  For example 2.20 in the case of this package:

    [email protected],5.11-0.133:<timestamp>

  IPS_Build_Version:
    Sets the build version portion of the IPS version string.  5.11 in the
    above example.  See pkg(5).
  
  IPS_Vendor_Version:
    Sets the vendor-specific branch version portion of the IPS version
    string, 0.133 in the above example.  See pkg(5).

  Meta is a special tag introduced for adding arbitrary metadata to
  IPS packages (using the 'set' action).  The syntax is:

  Meta(attribute_name): value

  Example:

  Meta(info.classification): org.opensolaris.category.2008:Applications/Games

  Other commonly used Meta tags are:

  Meta(info.upstream):          [name email of open source project leader]
  Meta(info.maintainer):        [name email of ips pkg porter/maintainer]
  Meta(info.repository_url):    [open source code repository]

  Spec file tags translate to IPS package attributes as follows:

  Name            pkg.name
  Summary         description
  Summary         pkg.summary
  Url             info.upstream_url
                  (defaults to http://pkgbuild.sf.net/)
  Group           info.classification
                  (freedesktop.org:: is prepended to the value of Group)
  Meta(<name>)    <name>
  SUNW_Copyright  payload of the license action
  License         the description of the license in the license action
  Requires        depend action

  A "legacy" action is also added to the manifest.  It uses the package
  data defined for SVr4 packaging, for example SUNW_Pkg and SUNW_Category.


4.2  Source and Patch tags

  The names (and locations) of source files and patches (source diffs)
  are added as tags.  The Source<n> tag defines the nth source file
  name or URL and similarly, Patch<N> defines the Nth patch file name
  or URL.  Special macros exist for unpacking sources and applying
  patches in the %prep section, see 7.1 for details.  The %SOURCE<n>
  and %PATCH<N> macros can be used to refer to the full local path to
  a copy of the given source or patch.  They can also be written as
  %{S:<n>} and %{P:<N>}.  A Source or Patch tag without a number is
  equivalent with Source0 or Patch0 respectively.

  To refer to the source URL, use %{SOURCE<n>.url}.


4.3  Other tags

  The following tags are also implemented by pkgbuild:

  Name: name of the component (upstream package)
  Version: version of the component
  License: identification of the license, e.g. GPLv2
  Copyright: (Obsolete) same as License
  BuildRoot: location of the prototype directory
  Group: classification of the package according to the freedesktop.org
         classification scheme
  NoSource: list of Source numbers not to be included in the source package,
         e.g. NoSource: 1 2
  NoPatch: list of Patch numbers not to be included in the source package
  Vendor: name of package vendor
  Summary: one-line description of the package
  BuildRequires: build-time dependency
  Requires: runtime dependency
  BuildConflicts: package with a build-time conflict
  BuildPrereq: same as BuildRequires
  

  These tags are accepted by the parser but currently ignored by pkgbuild:

  Release, Epoch, Distribution, Icon, URL, Packager, AutoReqProv, Serial,
  BuildArchitectures, BuildArch, ExcludeArch, ExclusiveArch, ExcludeOS,
  ExclusiveOS, Prefix, Obsoletes, Provides, Conflicts, Prereq


5 Preamble

  Spec files start with a list of tag definitions that describe the
  entire component.  This is called the Preamble in RPM's terminology.
  The information conveyed by the tags in the Preamble is generally
  stored as metadata in the generated package.

  Although only Name and Version are required, the following tags are
  usually present in the preamble:

  Name: the name of the component, preferably the upstream name, if the
        module comes from an external community

  Summary: a one-line description of the component

  Version: this tag defines the version of the binary package(s) built
        from the module therefore it has to meet the requirements of
        the packaging systems: a sequence of numbers separated by dots,
        no leading zeros.  While it's a good idea to keep the Version
        the same as the upstream version, sometimes changes need to be
        made in order to meet the above requirement.  In these cases a
        common practice is to define a macro called tarball_version and
        use it throughout the spec file whenever the upstream version
        number is needed.  Examples:

        Name: jpeg
        %define tarball_version 6b
        Version: 6.2

        Name: foo
        %define tarball_version 2.06
        Version: 2.0.6

  License: identification of the main license(s) in the package, for example

        License: GPLv3

  Vendor: the name of the organization that builds the package.  This tag
        is often found in an include file that is shared across a build
        environment, such as the OpenSolaris Desktop consolidations's
        Solaris.inc file.

  BuildRoot: location of the proto area where the binaries are laid out
        for packaging.  Example:

        BuildRoot: %{_tmppath}/%{name}-%{version}-build

  SUNW_Copyright: OpenSolaris-compliant packages require a license file
        that describes the license of the component.  This file is
        usually called %{name}.copyright:

        SUNW_Copyright: %{name}.copyright

  SUNW_BaseDir: the BASEDIR of the SVr4 package, if it's not "/".

        SUNW_BaseDir: %{_prefix}

  SUNW_Pkg: the SVr4 package abbreviation, if different from Name

  IPS_package_name: the IPS package name, if different from Name

  URL: a pointer to a web site with more information about the component

        Name: gtk2
        URL: http://www.gtk.org/

  Source, Source1, Source2, ...: list of sources, with full upstream
        URLs.  Use the %{version} macro in the URLs instead of repeating
        it.

  Patch, Patch1, Patch2, ...: list of source patches (diffs) that will
        be applied to the sources.  The naming convention used by
        the Desktop Consolidation and Source Juicer is:

        %{name}-<nn>-<description>.diff

        <nn> is a 2-digit number that specifies the order in which
        patches should be applied and <description> is a short
        description of what the patch does.  Example:

        Patch5:       gtk+-05-sun-pgdn-pgup-keybindings.diff

        The Desktop Consolidation uses -p1 unified diffs (See the -p
        option in patch(1) and -u in diff(1))

  BuildRequires: This tag declares one or more build-time dependencies of
        the component.  Multiple dependencies can by separated by commas,
        but it is generally more readable to use multiple BuildRequires
        declarations instead.  It is syntactically correct to specify
        required versions of dependencies, but pkgbuild does not
        currently enforce the version constraints.  Example:

        BuildRequires: SUNWgtk2 > 2.10.0, SUNWglib2 >= 2.5.0

        this is equivalent with:

        BuildRequires: SUNWgtk2 > 2.10.0
        BuildRequires: SUNWglib2 >= 2.5.0

        and in pkgbuild's current implementation the version is ignored:

        BuildRequires: SUNWgtk2
        BuildRequires: SUNWglib2

        The dependency can be a SVr4 package name, an IPS package name
        or a file name (full path):

        BuildRequires: SUNWbash
        BuildRequires: shell/bash
        BuildRequires: /usr/bin/bash

  Requires: similar to BuildRequires, but defines the runtime dependencies
        of the package.  pkgbuild attempts to translate dependency
        specifications to package names native to the format of the package
        being created.  File name dependencies are also translated to
        package names based on which package contains the file.

  BuildConflicts: opposite of BuildRequires.  Declares that the presence
        of the given package(s) or file(s) is incompatible with the build
        process of this component.

  Conflicts: declares a conflicting binary package.  Not currently
        implemented.

  A multi-line package description can be added at the end of the
  preamble, preceeded by the %description directive:

  %description
  Lorem ipsum dolor sit amet, consectetur adipisicing elit,
  sed do eiusmod tempor incididunt ut labore et dolore magna
  aliqua. Ut enim ad minim veniam, quis nostrud exercitation
  ullamco laboris nisi ut aliquip ex ea commodo consequat.

  Duis aute irure dolor in reprehenderit in voluptate velit
  esse cillum dolore eu fugiat nulla pariatur.

  The text of the description ends when it reaches a line that starts
  with a keyword (e.g. %package, %build, %define).

  It is a common mistake to add more tags after the %description.
  They will not be recognized as tags and will become part of the
  description text.

  The current version of pkgbuild does not use the description, but
  it is still a good practice to add it.


6 Packages

  A spec file can define one or more SVr4 and one or more IPS packages.
  While the files in these packages are the same, the package boundaries
  need not be.  The %package directive defines a group of files for
  the purpose of packaging and assigns a name that may or may not match
  either the IPS package name or the SVr4 package name of the given
  group of files.  The %packages tag is followed by a number of tag
  definitions that apply to the package.  By default, all tags inherit
  the value assigned in the main package.  Dependencies, however, are
  not inherited, the package must declare its own dependencies using
  Requires tags.

  The %package directive has 2 forms:

  %package -n <package_name>

  In the this form, the default behavior is that a separate SVr4 package
  called <package_name> is created and also a separate IPS package
  with the same name.

  %package <suffix>

  In this form, by default a separate SVr4 package called %{name}-<suffix>
  is created but for the purpose of IPS packaging, the files are merged
  in the main package.

  In both cases the SUNW_Pkg and IPS_Package_Name tags can be used to
  change the default behavior.  Setting SUNW_Pkg or IPS_Package_Name
  to a package name previously assigned to another package or the
  main package causes the files to be merged into that package.
  Otherwise a new package by that name will be created.

  Example 1:

  Name: foo
  ...
  %package devel

  Result:
    - SVr4: foo and foo-devel
    - IPS:  foo (devel files merged into foo)

  Example 2:

  Name: foo
  ...
  %package -n foo-devel

  Result:
    - SVr4: foo and foo-devel
    - IPS: foo and foo-devel

  Example 3:

  Name: foo
  ...
  %package -n bar
  IPS_Package_Name: foo

  Result:
    - SVr4: foo and bar
    - IPS: foo

  Example 4:

  Name: foo
  ...
  %package bar
  IPS_Package_Name: bar
  SUNW_Pkg: foo

  Result:
    - SVr4: foo (bar merged into foo)
    - IPS: foo and bar

  After the last tag, a %description specific to the package can be
  added.  The %description directive should use the same arguments
  as the corresponding %package directive:

  %package devel
  Requires: %name

  %description devel
  Development files for %{name}


7 Scriptlets

  Scriptlets are shell script fragments that interact with the component's
  native build system, for example GNU make and GNU autotools or ant or
  Python setuptools.  They are responsible for performing all the steps
  necessary to produce the binaries that make up the packages and lay
  them out in the proto area.  Each scriptlet is executed as a separate
  shell script.

  The interpreter used by the shell scripts is defined by the _buildshell
  macro, the default is /bin/bash.  When using bash, pkgbuild sets the
  following environment variables before the scriptlet itself:

  RPM_SOURCE_DIR=%{_sourcedir}
  RPM_BUILD_DIR=%{_builddir}
  RPM_OPT_FLAGS=%{optflags}
  RPM_ARCH=<the current architecture>
  RPM_OS=<the current OS>
  RPM_OS_REL=<the current OS release>
  RPM_DOC_DIR=/usr/share/doc/packages/%{name}
  RPM_PACKAGE_NAME=%{name}
  RPM_PACKAGE_VERSION=%version
  RPM_PACKAGE_RELEASE=%release
  RPM_BUILD_ROOT=%buildroot

  It also sets the "-x" (print commands as they are executed) and
  "-e" (exit when a command fails) flags.  See "set" in the
  "SHELL BUILTIN COMMANDS" section of bash(1) for more details.
  In the case of other interpreters the scriptlets are expected to
  return and exit status of 0 for success and non-0 in case of an
  error.

  pkgbuild executes the scriptlets in the following order:
   1 prep
   2 build
   3 install
   4 check
   5 clean

  None of the scriptlets are required parts of a spec file.  When missing,
  the build simply advances to the next stage.

  The -b<s> option can be used to stop the build after a certain stage:
    p  =  %prep
    c  =  %prep and %build (c for compile)
    i  =  %prep, %build, %install and %check
    b  =  all of the above and build binary package(s) and run %clean
    a  =  all of the above and build a source package as well

  To execute only 1 stage, use the --short-circuit option, e.g.

  pkgbuild --short-circuit -bi foo.spec


7.1  %prep

  This section is responsible for preparing the source code.  This
  includes unpacking tarballs, applying source patches, making
  other changes to the source files.  In most cases unpacking the
  sources and applying patches is all that is needed, so pkgbuild
  (like rpmbuild) has high level macros for performing these steps:

  %setup

  Without any arguments %setup simply unpacks Source0, using whatever
  compression and unpacking methods necessary, based on the file name
  suffix.  %setup has several flags that change its behavior (among
  others, they allow unpacking multiple tarballs).  These are documented
  in detail in max-rpm:
  http://www.rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html

  The most commonly used options are:

  -q      = quiet unpacking
  -n foo  = declares that unpacking the source bundle creates a
            directory called foo.  Use this macro, if foo is
            different from the default %name-%version
  -c      = create a directory before unpacking the source bundle.
            Useful when the bundle does not create a top-level directory.
            The default is %name-%version.  Use the -n option to change it.

  %patch<N>

  The %patch<N> macro is used to apply the Nth source patch to the source
  tree (using the GNU patch command).  Use the -p<n> option is passed to
  gpatch to remove <n> levels of directories from the beginning of each
  file path.  See gpatch(1).  Other options are described in
  http://www.rpm.org/max-rpm-snapshot/s1-rpm-inside-macros.html

  Example:

  %prep
  %setup -q -n glib-%{version}
  %patch1 -p1
  %patch2 -p1
  %patch3 -p1


7.2  %build

  The build section creates the binaries.  What exactly it does depends
  on the native build system of the component.  In the case of a component
  that uses GNU autotools, it typically sets some environment variables
  (for example compiler flags), runs configure with some options (like
  --prefix and options the select/unselect features) and the runs make:

  %build
  export CFLAGS="%optflags"
  export PYTHON=/usr/bin/python2.6
  ./configure --prefix=%{_prefix} \
            --mandir=%{_mandir} \
            --datadir=%{_datadir} \
            --disable-fam
  make


7.3  %install

  The install scriptlet copies the files that will become part of the
  binary package(s) to a prototype area.  The location of this directory
  is identified by the %{buildroot} macro and the $RPM_BUILD_ROOT
  environment variable (in the case of bash scripts).
  Components that use GNU autotools for their native build system
  typically use "make install DESTDIR=$RPM_BUILD_ROOT".  Since pkgbuild
  requires that all files under $RPM_BUILD_ROOT are included in a package,
  files that the package developer does not want to include in packages
  (for example libtool's .la or Python's .pyo files) must be deleted.

  It is a good idea to clear $RPM_BUILD_ROOT at the beginning of the
  %install section to make sure that no files are left behind from a
  previous (possibly failed) build.

  Example:

  %install
  rm -rf $RPM_BUILD_ROOT
  make install DESTDIR=$RPM_BUILD_ROOT
  # delete libtool .la files
  rm $RPM_BUILD_ROOT%{_libdir}/lib*.la


7.4  %check

  This section is executed immediately after %install and the purpose
  is to verify the integrity of the build by performing tests on the
  newly built binaries.  Many components provide a "make check" target
  for this purpose.

  You can also use this section to verify that all required parts of
  the package were built (missing dependencies can cause features to
  be disabled at build-time):

  %check
  # sanity check: verify that some tricky modules were successfully built:
  for f in _ctypes.so _curses.so _curses_panel.so _elementtree.so \
    _multiprocessing.so _sqlite3.so _ssl.so _tkinter.so crypt.so \
    pyexpat.so sunaudiodev.so zlib.so dlpi.so ucred.so bz2.so; do
    test -f $RPM_BUILD_ROOT%{_libdir}/python%{majmin}/lib-dynload/$f || {
        echo ERROR: required module $f missing
        exit 1
    }
  done


7.5  %clean

  This section (if present in the spec file) is run after the binary
  packages are created and it is used to clean up after the build.
  The most common command in this section is

  rm -rf $RPM_BUILD_ROOT

  which deletes the prototype area.


8 Installation scripts

  SVr4 package developers can "enhance" the functionality of their
  packages using installation scripts.  Installation scripts are generally
  used to change the state of the system during installation or
  uninstallation.  Given the number of different installation
  scenarios, it is difficult to get these scripts right and therefore
  the use of such scripts is discouraged.  Although SVr4 packaging
  allows other kinds of packages as well, pkgbuild only implements
  scripts that are acceptable for integration into the Solaris OS.
  These scripts are described below in more detail.


8.1  Procedure scripts (pre-/post-install/uninstall)

  Below is the list of procedure scripts and the corresponding spec
  file sections:
    - preinstall           = %pre
    - postinstall          = %post
    - preremove            = %preun
    - postremove           = %postun

  Be default, the scripts are added to the main package.  To add a
  procedure script to another package, use the same arguments as
  the corresponding %package directive:

  %package -n foo-devel
  ...
  %post -n foo-devel

  Short scripts can be inlined in the spec file:

  %pre
  echo Hello world

  The inline script can use spec file macros.  They end at a line
  that starts with a spec file keyword (e.g. %post, %files, %changelog).

  Longer scripts are best kept in separate files and referenced
  using the -f option:

  %post devel -f %{name}-devel.postinstall


8.2  Class Action Scripts

  Class Action Scripts (CAS) are responsible to performing installation
  or removal actions on a set of files, typically by editing an existing
  (editable) file that is shared by multiple packages.

  Files that belong to a specific class must be flagged in the %files
  list using the %class(class_name) modifier (see Section 9.1 for more
  detail).

  To define a new class, you need to provide either an installation script
  (%iclass directive) or a removal script (%rclass directive) or both.
  Just like in the case of procedure scripts, CASs can also be inlined or
  referenced using the -f file_name option:

  %iclass myclass -f i.myclass

  System default CASs (those located in /usr/sadm/install/scripts) do not
  need to be defined in the spec file, they can be used in the %files
  lists with the %class modifier.


8.3  Installation scripts in IPS (or the lack of)

  The Image Packaging System does not allow any kind of scripting.
  The reasons are detailed here: 
  http://blogs.sun.com/sch/entry/pkg_1_a_no_scripting

  In the real world, however, some configuration is often necessary.
  The recommended solution is using transient SMF services to perform the
  configuration steps.  Transient services are executed at system boot
  and IPS can also restart the services at the end of installation when
  any affected actions are tagged with "restart_fmri=svc://some/service".


9 Files and actions

  The contents of the package prototype area created in the %install
  section need to be sorted into binary packages.  Most item are
  directories, files or symlinks.  In the case of SVr4 packages, some
  of them may have special attributes like being volatile or having
  a class action script associated with them.  In the case of IPS,
  there are all kinds of other actions as well, for example adding
  a new group or user.  IPS actions that are not files, directories
  or symlinks can be defined in the %actions section.  %actions
  sections are ignored when building SVr4 packages.


9.1  %files

  The %files section lists that files included in the main package
  and in the packages defined using %package directives.  As explained
  in Section 6, these groups of files make up the SVr4 package and the
  IPS packages, but they do not necessarily include the same groups
  of files and the number of SVr4 packages created in the spec file
  may be different from the number of IPS packages.

  Without arguments, %files belongs to the main package.  %files
  lists for other packages must use the same arguments as the
  corresponding %package directive:

  %package devel
  ...
  %files devel

  The %files list usually starts with the definition of the default
  file attributes:

  %defattr (file_mode, user, group[, dirmode])

  file_mode is the default mode (permissions) of files in the package,
  specified as an octal number. 
  user and group are the default owners of the files and directories.
  dirmode is the default mode of the directories.  If omitted, it
  matches file_mode.  Either of these parameters can be replaced
  with a dash, which means pkgbuild should use the attribute of the
  file/directory, as found in the prototype area.  Since pkgbuild
  requires building as a non-privileged user, it is not a good idea
  to leave the user and group unspecified because pkgbuild will
  then use the build user's user name and group name in the package.
  A typical %files list start with:

  %defattr(-, root, root)

  A files list can contain multiple %defattr definitions, in which
  case they apply to the files listed after them.  Automatically
  added parent directories use the attributes of the last %defattr
  statement in the %files list.

  All other lines in %files consist of a path name or path name
  pattern (shell-style glob) optionally prefixed by some modifiers.
  If path name is a directory, all contents of the directory are
  added recursively (unless the %doc modifier is used, see below).

  For portability, path names are usually written using macros:

  %{_bindir}/foo

  Patterns should be used with care: using too restrictive patterns
  require more work to maintain (more lines need to be updated when
  upgrading the component to a newer version), while too inclusive
  patterns may hide build errors that cause some files not to be
  present.  Examples:

  Too restrictive:

  %{_datadir}/foo-doc/file1.html
  %{_datadir}/foo-doc/file1_a.html
  %{_datadir}/foo-doc/file1_b.html
  %{_datadir}/foo-doc/file2.html
  %{_datadir}/foo-doc/images/foo1.png
  ...

  Too inclusive:

  %{_libdir}/foo-plugins/*

  The following modifiers are implemented in pkgbuild:

  %attr - same as %defattr, but applies to the given line only

  %dir - when applied to a directory name, specifies that only the
         directory itself should be added, not the contents recursively.
         Useful when the permissions of the directory are different from
         its contents:

         %attr(0755, root, other) %{_datadir}/applications
         %{_datadir}/applications/foo.desktop

  %config - SVr4: when used in conjunction with %class(foo), it
         marks the file editable (type 'e')
         - IPS: it tags the file with preserve=\"renamenew\"

  %ghost - SVr4: marks the file volatile (type 'v')

  %class(class_name) - SVr4: declares that that file is part of
         class class_name.

  %ips_tag(foo=bar) - IPS: adds "foo=bar" as a tag on the given file
         example:

         %ips_tag(restart_fmri="svc:/foo/bar") %{_libdir}/fred

  %hard - when applied to a symlink, it becomes a hard link in the
         prototype / manifest.

  %doc - flags documentation files, see Section 9.1.2
  
  %verify - ignored

  %docdir - ignored


9.1.1  Dynamically generated %files lists

  Sometimes sorting files into packages is inconvenient to do manually,
  for example if you need to separate a large number of files based on
  some pattern.  pkgbuild (like rpmbuild) allows package developers to
  create a list of files during the build and use that in %files.
  Use the -f file_name flag to associate file_name with the %files list.
  pkgbuild will look for file_name in the top level build directory of
  the component (e.g. ~/packages/BUILD/foo-1.0/).
  The %files file (metafile) can list some or all files in the package:

  %files devel -f api_docs.lst
  %defattr (-, root, bin)
  %{_includedir}/foo.h

  The metafile is usually generated in the %install section:

  %install
  rm -rf $RPM_BUILD_ROOT
  make install DESTDIR=$RPM_BUILD_ROOT
  find $RPM_BUILD_ROOT%{_datadir}/foo -name 'foo_API_*.html' -print \
     | sed -e 's,$RPM_BUILD_ROOT,,' > api_docs.lst


9.1.2  %doc files

  pkgbuild (like rpmbuild) can help create "package documentation files".
  These files are part of the source tree and they are saved in a
  package-specific directory in the binary package for users to review.
  It can include README files, instructions, licensing information,
  examples, etc.

  Package documentation files are prefixed with the %doc modifier and
  are specified with a relative path.  A whitespace-separated list of
  files can be specified in a single line.  pkgbuild will look for the
  relative path under the top level source directory of the component.  

  pkgbuild's implementation of the %doc modifier is slightly differs
  from rpmbuild's:

   - pkgbuild supports %doc(compress|gzip|bzip2) tag, this
     causes the files to be compressed with the chosen compression
     utility
   - the %{_pkg_docdir} macro can be used to refer to or to change the
     doc directory of a package
   - files in subdirectories of the top level source directory can be
     tagged with %doc:

     %doc po/ChangeLog

     The file will be placed in a subdirectory of the same
     name under %{_pkg_docdir}

   - %doc -d <subdir> changes the directory to <subdir> before
     looking for a documentation file.  As a result, "subdir"
     will not be created in %{_pkg_docdir}.  This is useful
     for example in the this source directory structure:

     ~/packages/BUILD/foo-1.0/
           i386/foo-1.0/README, etc...
           amd64/foo-1.0/README, etc...

     in the package, we want the README file to be under
     /usr/share/doc/foo/README, and not under
     /usr/share/doc/foo/i386/foo-1.0/README, 

     So in %files, use this:

     %doc -d %{base_arch}/foo-%{version} README


9.2  %actions

  The actions section is used to add arbitrary actions to the IPS
  manifest.  Macros are expanded the in items of the %actions sections
  but no other processing or verification is performed.  Like %files,
  %actions must also be linked to the corresponding %package:

  %actions
  group groupname="testpkg"
  user username="testuser" group="testpkg"

  %actions -n foo-driver
  driver name=foo perms="dump 0660 root sys"


9.3  autotag

  As mentioned in section 8.3, some files need additional processing
  after installation/update.  This is usually done in SMF services and 
  the restart_fmri IPS tag can be used to tell IPS to restart the
  services.

  "autotag" is a feature that automatically adds restart_fmri tags for
  some known types of files, for example SMF manifests, .desktop files,
  GConf schemas.  Autotag also adds dependencies on the packages that
  include the SMF services to be restarted.  Package developers can
  add their own tags using the IPS_tag modifier.

  To disable autotag, the spec file can set _use_ips_autotag to 0:

  %define _use_ips_autotag 0

  or the user can set it on the pkgbuild or pkgtool command line:

  pkgbuild --define '_use_ips_autotag 0' -ba foo.spec

  and finally, it can also be disabled in ~/.pkgbuildmacros:

  %_use_ips_autotag 0

  The current version of pkgbuild includes the following autotag rules:

  Path name regexp
            SMF service to restart
                        Additional dependencies
  /etc/gconf/schemas/.*\.(schemas|entries)$/
            svc:/applications/desktop-cache/gconf-cache:default
                        SUNWdesktop-cache
  usr/share/icons/.*
            svc:/applications/desktop-cache/icon-cache:default
                        SUNWdesktop-cache
  usr/lib/.*gtk-2.0/.*/immodule/.*\.so
            svc:/application/desktop-cache/input-method-cache:default
                        SUNWdesktop-cache
  usr/share/mime/packages/.*
            svc:/application/desktop-cache/mime-types-cache:default
                        SUNWdesktop-cache
  usr/lib/.*gtk-2.0/.*loaders/.*\.so
            svc:/application/desktop-cache/pixbuf-loaders-installer:default
                        SUNWdesktop-cache
  usr/share/applications/.*
            svc:/application/desktop-cache/desktop-mime-cache:default
                        SUNWdesktop-cache
  usr/X11/lib/X11/fonts/.*\.(ttf|pcf|pcf\.gz)
            svc:/application/font/fc-cache:default
                        SUNWfontconfig
  var/svc/manifest/.*\.xml
            svc:/system/manifest-import:default


10 Multi-level spec file structures

  This section discusses some features intended to make it easier to
  create a consistent set of packages from a spec file repository.
  These features are incompatible with rpmbuild.

10.1  %include

  The %include directive works just like #include in the C preprocessor:
  it reads the contents of the include file as if it was included in
  the parent file where the %include line occurs.

  %include exists in rpmbuild as well, but the usage is slightly
  different.  In rpmbuild, files to be included must listed with
  an absolute path and they do not get included in the source package
  unless they are also declared using a Source tag:

  Source5: foo.inc
  ...
  %include %SOURCE5

  This above example works with both pkgbuild and rpmbuild.  The
  include file (since it's a source) is expected to be in %_sourcedir,
  just like the rest of the sources.

  In pkgbuild's implementation, a relative path after %include is
  considered a part of the spec file therefore it is expected to
  be in %_specdir and is automatically included in the source package:

  %include Solaris.inc


10.2  %use                               

  The %use directive is more sophisticated.  It allows referencing
  parts of another spec file through macro expansion.  First, we
  need to assign a name or label to a spec file:

  %use glib2 = glib2.spec

  After this line, the parent spec file can refer to tags, macros
  and scriptlets of glib2.spec, for example:

  Version: %{glib2.version}

  and even:

  %setup
  %glib2.prep

  Macros in the referenced spec file (glib2.spec in the above example)
  are evaluated where the %use directive appears.  For example, if
  glib2.spec define CFLAGS like this:

  CFLAGS="%{?optflags}"

  then defining (or redefining) %optflags before the %use statement
  affects what the above line is expanded into:

  %define optflags -xO2
  %use glib2 = glib2.spec           --->       CFLAGS="-xO2"

  Leveraging this behavior, it's easy to build the same component
  multiple times, with different parameters, and include them in
  the same package, for example 32-bit and 64-bit variants:

  %define optflags -fast -m64
  %define _libdir %{_prefix}/lib/64
  %use glib2_64 = glib2.spec
  %define optflags -fast
  %define _libdir %{_prefix}/lib
  %use glib2 = glib2.spec

  We now have 2 labels assigned to the same spec file.  One has its
  macros expanded for a 64-bit build, the other for a 32-bit build.

  We can now write a %prep section that calls the %prep sections
  of each spec file, running them in separate subdirectories to
  avoid conflicts:

  %prep
  rm -rf %name-%version
  mkdir -p %name-%version/32
  %glib2.prep -d %name-%version/32
  mkdir -p %name-%version/64
  %glib2_64.prep -d %name-%version/64

  As we can see in the above example, when calling scriptlets of
  a %use'd spec file, the -d dir argument causes the scriptlet to
  be executed in dir.  The working directory of the calling scriptlet
  does not change as a result of using the -d dir argument.

  Similarly, the %build and %install scriptlets can also call glib2's
  and glib2_64's corresponding scriptlets, using the -d dir argument:

  %build
  %{glib2.build} %name-%version/32
  %{glib2_64.build} %name-%version/64

  Rarely used, but it is also possible to reference tags in subpackages
  (defined with %package) in the child spec.  For example, if
  glib2.spec has a devel subpackage:

  %package devel
  Summary: glib2 development files

  We can reference the Summary tag in glib2.spec's devel subpackage
  using %{glib2.devel.summary}.

  The %use directive is also useful when building the same spec file
  on Linux and Solaris/OpenSolaris is a goal.  The Linux spec file
  can be left as it is and a Solaris spec file written that wraps
  the Linux spec file through a %use directive and macro expansions,
  adding the necessary Solaris-specific information like tags and
  packaging.


11 Conditionals


  While, ideally, spec files should be written as generic and
  architecture-agnostic as possible, sometimes different commands,
  options or settings are needed on different platforms.

  To process spec file lines on specific architectures only use
  the %ifarch conditional:

  %ifarch amd64
  %define _libdir %{_prefix}/lib/amd64
  %endif
  %ifarch sparcv9
  %define _libdir %{_prefix}/lib/sparcv9
  %endif

  It is also possible to list multiple acceptable architectures:

  %ifarch amd64 sparcv9
  ...
  %endif

  The architectures that pkgbuild well accept as matches are those
  printed by the isainfo command.  The %ifnarch conditional is the
  logical complement to %ifarch, it matches whose architectures that
  are not printed by isainfo:

  %ifnarch amd64
  <lines to process on non-amd64 systems only>
  %endif

  The %ifos / %ifnos conditionals can be used to separate
  Solaris-specific parts of a spec file that may be built on
  other OSs as well:

  %ifos SunOS
  
  %endif

  The logical complement is %ifnos:

  %ifnos Linux
  ...
  %endif

  A generic %if statement is also available.  In the current version
  of pkgbuild, it only accepts 1 for logical true 0 for logical false
  as its argument.  Expression evaluation can be done in a subshell
  macro:

  %if %(test %foo = "fred" && echo 1 || echo 0)
  ...
  %endif

  The %else conditional can be used with any of the conditionals described
  above.

12 Changelog

   Spec files usually end with a %changelog section.
   While it's not required in pkgbuild, it is recommended to document
   all non-trivial changes in the spec file's %changelog section.
   The format of the %changelog is as follows:

   %changelog
   * <date> - <user>
   - <change1>
   - <change2>
   * <date> - <user>
   - <change3>

   where <date> is in date(1) +"%a %b %e %Y" format, <user> is a person's
   email address and/or name and <changeN> is a short description of the
   change.  Example:

   %changelog
   * Tue Jan 26 2010 - [email protected]
   - bump version to 2.24.0
   * Tue Mar 31 2009 - [email protected]
   - initial version

   rpmbuild also requires that changelog entries are in descending
   chronological order.

13 Further reading

   SVr4 packaging: Solaris Application Packaging Developer's Guide:
   http://docs.sun.com/app/docs/doc/806-7008

   IPS packaging:
   http://hub.opensolaris.org/bin/view/Project+pkg/documents
  
   RPM documentation:
   http://www.rpm.org/max-rpm-snapshot/
   http://docs.fedoraproject.org/drafts/rpm-guide-en/

   rpmbuild tutorial:
   Part 1: http://www-106.ibm.com/developerworks/library/l-rpm1/
   Part 2: http://www-106.ibm.com/developerworks/library/l-rpm2/
   Part 3: 
http://www-128.ibm.com/developerworks/linux/library/l-rpm3.html?dwzone=linux

   pkgbuild mailing list:
   http://lists.sourceforge.net/mailman/listinfo/pkgbuild-sfe-devel

   OpenSolaris software porters:
   http://hub.opensolaris.org/bin/view/Community+Group+sw-porters/
   http://mail.opensolaris.org/mailman/listinfo/sw-porters-discuss

   IRC: irc://freenode:net/#pkgbuild
_______________________________________________
opensolaris-arc mailing list
[email protected]

Reply via email to