pkgbuild(1) General Commands Manual pkgbuild(1)
NAME
pkgbuild – Build a macOS Installer component package from on-disk files
SYNOPSIS
pkgbuild [options] --root root-path [--component-plist plist-path]
package-output-path
pkgbuild --analyze --root root-path plist-output-path
pkgbuild [options] {--component component-path} package-output-path
DESCRIPTION
A “component package” contains payload to be installed by the OS X
Installer. Although a component package can be installed on its own, it is
typically incorporated into a product archive, along with a “distribution”
and localized resources, using productbuild(1).
To create a product archive for submission to the Mac App Store, do not use
pkgbuild. Instead, use productbuild(1) directly.
pkgbuild has three different modes, as shown in the SYNOPSIS above:
1. Package a complete destination root. When you use xcodebuild(1) with
the install action, the result is a destination root, either under
/tmp, or in whatever location you specify with the Xcode DSTROOT
setting. Use the --root option to specify that destination root
directory to pkgbuild, and the entire contents of the directory tree
will be included in the output package.
2. Create a template component property list (analyze mode). You point
pkgbuild to a destination root as above, but instead of outputting a
package, pkgbuild outputs a component property list (see COMPONENT
PROPERTY LIST). By editing this property list and specifying it with
--component-plist when you subsequently build the package, you can
control bundle-specific Installer behavior.
3. Package one or more individual bundles. If you don't have a
destination root, you can use the --component option to specify one or
more bundles that should be incorporated into the package. Note that
only bundles can be specified with --component.
ARGUMENTS AND OPTIONS
--root root-path
Package the entire contents of the directory tree at root-path,
typically a destination root created by xcodebuild(1).
--component component-path
The bundle at component-path is added to the package. Valid only if
you don't use --root.
--component-plist plist-path
If you specify --root, you can use --component-plist to identity
the bundles within that destination root, and control how the OS X
Installer handles those bundles. See more at COMPONENT PROPERTY
LIST. If you add bundles and need to update your component
property list, you can specify the old version with
--component-plist when running pkgbuild with --analyze, and the old
settings will be propagated to the output for still-extant bundles.
--scripts scripts-path
Archive the entire contents of scripts-path as the package scripts.
If this directory contains scripts named preinstall and/or
postinstall, these will be run as the top-level scripts of the
package. If you want to run scripts for specific bundles, you must
specify those in a component property list; see more at COMPONENT
PROPERTY LIST. Any other files under scripts-path will be used
only if the top-level or component-specific scripts invoke them.
--nopayload
Indicates that the package will contain only scripts, with no
payload.
--identifier pkg-identifier
Specify a unique identifier for this package. The OS X Installer
recognizes a package as being an upgrade to an already-installed
package only if the package identifiers match, so it is advisable
to set a meaningful, consistent identifier when you build the
package. pkgbuild will infer an identifier when building a package
from a single component, but will fail otherwise if the identifier
has not been set.
--version pkg-version
Specify a version for the package. Packages with the same
identifier are compared using this version, to determine if the
package is an upgrade or downgrade. If you don't specify a version,
a default of zero is assumed, but this may prevent proper
upgrade/downgrade checking.
--install-location install-path
Specify the default install location for the contents of the
package. For example, if you specify a single application
component, you might specify an install-path of /Applications.
pkgbuild attempts to infer a sensible install path if this option
is not used, but it may not choose correctly. Note that whether or
not the default install location is actually used by the OS X
Installer depends on the distribution file you deploy with the
package.
--analyze
Instead of creating a package, create a template component property
list from the destination root given with --root. See COMPONENT
PROPERTY LIST.
--prior pkg-path
In addition to the options above, you can also set the package
identifier, version and install location by pointing to a prior
version of the same package. pkgbuild will read the package at
pkg-path and use the same package identifier and install location
contained therein. The version number in the prior package will be
converted to an integer and incremented, and the result used for
the new package. Note that pkgbuild makes no attempt to verify that
the prior package is in any way equivalent to the one being built,
so you must make sure you point it to a logically equivalent
package.
--filter filter-expression
By default, --root will include the entire contents of the given
root-path in the package payload, except for any .svn or CVS
directories, and any .DS_Store files. You can override these
default filters by specifying one or more --filter options. Each
filter-expression is an re_format(7) “extended” expression: any
path in the root which matches any of the given expressions will be
excluded from the package payload. (Note that specifying even one
--filter inhibits the default filters, so you must respecify the
default filters if you still want them to be used.)
--ownership (recommended | preserve | preserve-other)
By default, when the payload is archived into the package, the
recommended UID and GID will be applied to all files. (Generally,
this will be root:wheel, which ensures that files installed in the
system domain are root-owned, while files installed in the user
home directory will be owned by that user.) If you have special
ownership requirements, you should use chmod(1) to adjust the
ownership of the source files, and use --ownership preserve so that
pkgbuild archives the exact ownership of the on-disk files.
Alternatively, if you have just a few files to adjust, --ownership
preserve-other will apply the recommended UID and GID to those
files that are owned by the user running pkgbuild, but leave other
files unchanged. Note that pkgbuild never changes the ownership of
the actual on-disk files, only the ownership that is archived into
the package.
--large-payload
By default, packages that are created have a per-file size limit
associated with them. This method instructs pkgbuild to construct
a package where the included payload format supports large files.
A large file is defined as any file that is 8 GiB or larger.
Warning: The --large-payload option generates packages that are
only compatible with macOS 12.0 and above. Packages using this
feature will fail to install or extract on previous releases.
Specifying this option requires the user to pass [--min-os-version
12.0] or later to acknowledge this requirement.
--compression compression-mode
Allows control over the compression used for the package. This
option does not affect the compression used for plugins or scripts.
Not specifying this option will leave the chosen compression
algorithm up to the operating system. Two compression-mode
arguments are supported:
• legacy forces a 10.5-compatible compression algorithm for the
package.
• latest enables pkgbuild to automatically select newer, more
efficient compression algorithms based on what is provided to
[--min-os-version <version>].
--min-os-version os-version
Specifying a minimum OS version allows the system to create a
package with the latest supported features. Some features can have
major benefits such as a better compression ratio. However,
specifying a minimum version will make the package require that
version when presented to productbuild(1). Some of the options in
this tool require this argument to be provided.
--sign identity-name
Adds a digital signature to the resulting package. See SIGNED
PACKAGES
--keychain keychain-path
Specify a specific keychain to search for the signing identity. See
SIGNED PACKAGES
--cert certificate-name
Specify an intermediate certificate to be embedded in the package.
See SIGNED_PACKAGES
--timestamp
Include a trusted timestamp with the signature. See SIGNED_PACKAGES
--timestamp=none
Disable trusted timestamp, regardless of identity. See
SIGNED_PACKAGES
--quiet
Inhibits status messages on stdout. Any error messages are still
sent to stderr.
package-output-path
The path to which the package will be written.
plist-output-path
When --analyze is used, the path to which the template component
property list will be written.
COMPONENT PROPERTY LIST
When you package a destination root, you can use a component property list
to specify how bundles in that root should be handled by the OS X
Installer. This property list should be an array of dictionaries, where
each dictionary specifies a single bundle. The dictionary keys are as
follows:
Key Description
RootRelativeBundlePath Path to bundle relative to the destination root (string)
BundleIsRelocatable Install bundle over previous version if moved by user? (bool)
BundleIsVersionChecked Don't install bundle if newer version on disk? (bool)
BundleHasStrictIdentifier Require identical bundle identifiers at install path? (bool)
BundleOverwriteAction How to treat existing on-disk version of bundle (string)
BundlePreInstallScriptPath Relative path to bundle-specific preinstall script
BundlePostInstallScriptPath Relative path to bundle-specific postinstall script
ChildBundles Bundles under this bundle (array of dictionaries)
The easiest way to create a component property list is to use the --analyze
option and point pkgbuild at your current destination root. The output will
be a component property list with default attributes, which you can then
edit as needed. You can also specify a previous version of your component
property list when using --analyze, which will cause the attributes of
previously existing bundles to be propagated forward.
BundleOverwriteAction specifies how an existing version of the bundle on
disk should be handled when the version in the package is installed. If you
specify upgrade, the bundle in the package atomically replaces any version
on disk; this has the effect of deleting old paths that no longer exist in
the new version of the bundle. If you specify update, the bundle in the
package overwrites the version on disk, and any files not contained in the
package will be left intact; this is appropriate when you are delivering an
update-only package. Another effect of update is that the package bundle
will not be installed at all if there is not already a version on disk;
this allows a package to deliver an update for an app that the user might
have deleted.
BundlePreInstallScriptPath and BundlePostInstallScriptPath are meaningful
only if --scripts was used to specify a scripts directory. The paths given
by these keys must be relative to the scripts directory.
ChildBundles can be used to represent nesting of bundles, but it does not
change the meaning of RootRelativeBundlePath within lower-level
dictionaries (i.e. it is always relative to the destination root). If you
write a component property list manually, you do not need to use
ChildBundles at all; you can simply put all bundle dictionaries in the top-
level array.
SIGNED PACKAGES
When creating a package, you can optionally add a digital signature to the
package. You will need to have a certificate and corresponding private key
-- together called an “identity” -- in one of your accessible keychains. To
add a signature, specify the name of the identity using the --sign option.
The identity's name is the same as the “Common Name” of the certificate.
If you want to search for the identity in a specific keychain, specify the
path to the keychain file using the --keychain option. Otherwise, the
default keychain search path is used.
pkgbuild will embed the signing certificate in the product archive, as well
as any intermediate certificates that are found in the keychain. If you
need to embed additional certificates to form a chain of trust between the
signing certificate and a trusted root certificate on the system, use the
--cert option to give the Common Name of the intermediate certificate.
Multiple --cert options may be used to embed multiple intermediate
certificates.
The signature can optionally include a trusted timestamp. This is enabled
by default when signing with a Developer ID identity, but it can be enabled
explicitly using the --timestamp option. A timestamp server must be
contacted to embed a trusted timestamp. If you aren't connected to the
Internet, you can use --timestamp=none to disable timestamps, even for a
Developer ID identity.
Note that if you are going to create a signed product with the resulting
package, using productbuild(1), there is no reason to sign the individual
package.
EXAMPLES
pkgbuild --identifier com.sample.pkg.app --root /tmp/Sample.dst Sample.pkg
Build the package Sample.pkg using the entire contents of the
destination root /tmp/Sample.dst.
pkgbuild --analyze --root /tmp/Sample.dst components.plist
Analyze the destination root /tmp/Sample.dst, and write a template
component property list to components.plist.
pkgbuild --identifier com.sample.pkg.app --root /tmp/Sample.dst
--component-plist components-edited.plist Sample.pkg
Build the package Sample.pkg using the destination root
/tmp/Sample.dst, using the bundle-specific behaviors indicated in
components-edited.plist.
pkgbuild --identifier com.sample.pkg.app --root /tmp/Sample.dst --sign
sample-identity Sample.pkg
Build the package Sample.pkg using the destination root
/tmp/Sample.dst, and sign the resulting package using the identity
sample-identity. You will be prompted to allow pkgbuild to access
the keychain item, unless Always Allow was chosen previously.
SEE ALSO
productbuild(1), xcodebuild(1)
macOS July 1, 2021 macOS