Sun Feb 12 10:48:55 2017 UTC ()
Move pkgtools/pkg_comp to pkgtools/pkg_comp1.

This is to make room for pkg_comp 2.0, which is coming soon.  The new release
is significantly different from the 1.x series in features (supports multiple
platforms, bootstrap, and pbulk) but also comes with a different configuration
syntax.


(jmmv)
diff -r1.699 -r1.700 pkgsrc/doc/CHANGES-2017
diff -r1.114 -r1.115 pkgsrc/pkgtools/Makefile
diff -r1.2 -r0 pkgsrc/pkgtools/pkg_comp/DESCR
diff -r1.55 -r0 pkgsrc/pkgtools/pkg_comp/Makefile
diff -r1.1.1.1 -r0 pkgsrc/pkgtools/pkg_comp/PLIST
diff -r1.41 -r0 pkgsrc/pkgtools/pkg_comp/files/pkg_comp.8
diff -r1.43 -r0 pkgsrc/pkgtools/pkg_comp/files/pkg_comp.sh
diff -r0 -r1.1 pkgsrc/pkgtools/pkg_comp1/DESCR
diff -r0 -r1.1 pkgsrc/pkgtools/pkg_comp1/Makefile
diff -r0 -r1.1 pkgsrc/pkgtools/pkg_comp1/PLIST
diff -r0 -r1.1 pkgsrc/pkgtools/pkg_comp1/files/pkg_comp.8
diff -r0 -r1.1 pkgsrc/pkgtools/pkg_comp1/files/pkg_comp.sh

cvs diff -r1.699 -r1.700 pkgsrc/doc/CHANGES-2017 (expand / switch to unified diff)

--- pkgsrc/doc/CHANGES-2017 2017/02/12 10:29:04 1.699
+++ pkgsrc/doc/CHANGES-2017 2017/02/12 10:48:55 1.700
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1$NetBSD: CHANGES-2017,v 1.699 2017/02/12 10:29:04 adam Exp $ 1$NetBSD: CHANGES-2017,v 1.700 2017/02/12 10:48:55 jmmv Exp $
2 2
3Changes to the packages collection and infrastructure in 2017: 3Changes to the packages collection and infrastructure in 2017:
4 4
5 Updated ham/fldigi to 3.23.19 [mef 2017-01-01] 5 Updated ham/fldigi to 3.23.19 [mef 2017-01-01]
6 Updated cad/gtkwave to 3.3.79 [mef 2017-01-01] 6 Updated cad/gtkwave to 3.3.79 [mef 2017-01-01]
7 Updated devel/py-requests to 2.12.4nb1 [ryoon 2017-01-01] 7 Updated devel/py-requests to 2.12.4nb1 [ryoon 2017-01-01]
8 Updated archivers/xz to 5.2.3 [mef 2017-01-01] 8 Updated archivers/xz to 5.2.3 [mef 2017-01-01]
9 Updated sysutils/py-psutil to 5.0.1 [ryoon 2017-01-01] 9 Updated sysutils/py-psutil to 5.0.1 [ryoon 2017-01-01]
10 Updated net/aria2 to 1.30.0 [ryoon 2017-01-01] 10 Updated net/aria2 to 1.30.0 [ryoon 2017-01-01]
11 Updated audio/chromaprint to 1.4.2 [mef 2017-01-01] 11 Updated audio/chromaprint to 1.4.2 [mef 2017-01-01]
12 Updated cad/klayout to 0.24.9 [mef 2017-01-01] 12 Updated cad/klayout to 0.24.9 [mef 2017-01-01]
13 Updated textproc/xapian to 1.4.2 [schmonz 2017-01-01] 13 Updated textproc/xapian to 1.4.2 [schmonz 2017-01-01]
14 Updated textproc/xapian-omega to 1.4.2 [schmonz 2017-01-01] 14 Updated textproc/xapian-omega to 1.4.2 [schmonz 2017-01-01]
@@ -856,13 +856,14 @@ Changes to the packages collection and i @@ -856,13 +856,14 @@ Changes to the packages collection and i
856 Updated sysutils/lsof to 4.89 [rodent 2017-02-11] 856 Updated sysutils/lsof to 4.89 [rodent 2017-02-11]
857 Updated www/lighttpd to 1.4.45nb1 [he 2017-02-11] 857 Updated www/lighttpd to 1.4.45nb1 [he 2017-02-11]
858 Updated print/podofo to 0.9.5 [adam 2017-02-11] 858 Updated print/podofo to 0.9.5 [adam 2017-02-11]
859 Updated net/gst-rtsp-server to 1.10.3 [prlw1 2017-02-11] 859 Updated net/gst-rtsp-server to 1.10.3 [prlw1 2017-02-11]
860 Updated net/dante to 1.4.2 [mef 2017-02-12] 860 Updated net/dante to 1.4.2 [mef 2017-02-12]
861 Updated fonts/harfbuzz to 1.4.2nb1 [ryoon 2017-02-12] 861 Updated fonts/harfbuzz to 1.4.2nb1 [ryoon 2017-02-12]
862 Added mail/courier-unicode version 1.4 [mef 2017-02-12] 862 Added mail/courier-unicode version 1.4 [mef 2017-02-12]
863 Updated www/p5-Mojolicious to 7.25 [wen 2017-02-12] 863 Updated www/p5-Mojolicious to 7.25 [wen 2017-02-12]
864 Updated devel/p5-MooseX-Types to 0.50 [wen 2017-02-12] 864 Updated devel/p5-MooseX-Types to 0.50 [wen 2017-02-12]
865 Updated www/py-beautifulsoup4 to 4.5.3 [wen 2017-02-12] 865 Updated www/py-beautifulsoup4 to 4.5.3 [wen 2017-02-12]
866 Updated misc/ruby-ohai to 8.23.0 [mef 2017-02-12] 866 Updated misc/ruby-ohai to 8.23.0 [mef 2017-02-12]
867 Updated misc/libreoffice to 5.3.0.3nb4 [ryoon 2017-02-12] 867 Updated misc/libreoffice to 5.3.0.3nb4 [ryoon 2017-02-12]
868 Updated www/awstats to 7.6 [adam 2017-02-12] 868 Updated www/awstats to 7.6 [adam 2017-02-12]
 869 Moved pkgtools/pkg_comp to pkgtools/pkg_comp1 [2017-02-12]

cvs diff -r1.114 -r1.115 pkgsrc/pkgtools/Makefile (expand / switch to unified diff)

--- pkgsrc/pkgtools/Makefile 2016/10/01 18:42:53 1.114
+++ pkgsrc/pkgtools/Makefile 2017/02/12 10:48:55 1.115
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: Makefile,v 1.114 2016/10/01 18:42:53 kamil Exp $ 1# $NetBSD: Makefile,v 1.115 2017/02/12 10:48:55 jmmv Exp $
2# 2#
3 3
4COMMENT= Tools for use in the packages collection 4COMMENT= Tools for use in the packages collection
5 5
6SUBDIR+= R2pkg 6SUBDIR+= R2pkg
7SUBDIR+= autoswc 7SUBDIR+= autoswc
8SUBDIR+= binpatch 8SUBDIR+= binpatch
9SUBDIR+= bootstrap-extras 9SUBDIR+= bootstrap-extras
10SUBDIR+= bootstrap-mk-files 10SUBDIR+= bootstrap-mk-files
11SUBDIR+= cdpack 11SUBDIR+= cdpack
12SUBDIR+= compat_headers 12SUBDIR+= compat_headers
13SUBDIR+= createbuildlink 13SUBDIR+= createbuildlink
14SUBDIR+= cwrappers 14SUBDIR+= cwrappers
@@ -24,27 +24,27 @@ SUBDIR+= libkver @@ -24,27 +24,27 @@ SUBDIR+= libkver
24SUBDIR+= libnbcompat 24SUBDIR+= libnbcompat
25SUBDIR+= lintpkgsrc 25SUBDIR+= lintpkgsrc
26SUBDIR+= mksandbox 26SUBDIR+= mksandbox
27SUBDIR+= mtree 27SUBDIR+= mtree
28SUBDIR+= nih 28SUBDIR+= nih
29SUBDIR+= osabi 29SUBDIR+= osabi
30SUBDIR+= p5-pkgsrc-Dewey 30SUBDIR+= p5-pkgsrc-Dewey
31SUBDIR+= packagekit 31SUBDIR+= packagekit
32SUBDIR+= pbulk 32SUBDIR+= pbulk
33SUBDIR+= pbulk-base 33SUBDIR+= pbulk-base
34SUBDIR+= pkg 34SUBDIR+= pkg
35SUBDIR+= pkg_alternatives 35SUBDIR+= pkg_alternatives
36SUBDIR+= pkg_chk 36SUBDIR+= pkg_chk
37SUBDIR+= pkg_comp 37SUBDIR+= pkg_comp1
38SUBDIR+= pkg_distinst 38SUBDIR+= pkg_distinst
39SUBDIR+= pkg_filecheck 39SUBDIR+= pkg_filecheck
40SUBDIR+= pkg_install 40SUBDIR+= pkg_install
41SUBDIR+= pkg_install-info 41SUBDIR+= pkg_install-info
42SUBDIR+= pkg_leaves 42SUBDIR+= pkg_leaves
43SUBDIR+= pkg_notify 43SUBDIR+= pkg_notify
44SUBDIR+= pkg_online-client 44SUBDIR+= pkg_online-client
45SUBDIR+= pkg_online-server 45SUBDIR+= pkg_online-server
46SUBDIR+= pkg_p5up2date 46SUBDIR+= pkg_p5up2date
47SUBDIR+= pkg_regress 47SUBDIR+= pkg_regress
48SUBDIR+= pkg_rolling-replace 48SUBDIR+= pkg_rolling-replace
49SUBDIR+= pkg_select 49SUBDIR+= pkg_select
50SUBDIR+= pkg_summary-utils 50SUBDIR+= pkg_summary-utils

File Deleted: pkgsrc/pkgtools/pkg_comp/DESCR

File Deleted: pkgsrc/pkgtools/pkg_comp/Makefile

File Deleted: pkgsrc/pkgtools/pkg_comp/PLIST

File Deleted: pkgsrc/pkgtools/pkg_comp/files/Attic/pkg_comp.8

File Deleted: pkgsrc/pkgtools/pkg_comp/files/Attic/pkg_comp.sh

File Added: pkgsrc/pkgtools/pkg_comp1/DESCR
pkg_comp is a small utility designed to build packages inside a
clean chroot tree.

Some ideas about what to use it for (taken from manpage):
* Build packages for other system versions. For example, build
  packages for NetBSD 1.5 while you are running NetBSD current.
* Build packages using different options than your current system
  like changing the threading library, COPTS, placement of
  configuration files, etc.
* Debug the build process of a package, checking if buildlinks
  work properly.
* Avoid autoconf's side effects by keeping a separate chroot for
  each project, like one for GNOME2 and another one for KDE3.
* Schedule builds of package sets for several different machines.

File Added: pkgsrc/pkgtools/pkg_comp1/Makefile
# $NetBSD: Makefile,v 1.1 2017/02/12 10:48:55 jmmv Exp $

PKGNAME=	pkg_comp1-1.38
PKGREVISION=	1
CATEGORIES=	pkgtools

MAINTAINER=	pkgsrc-users@NetBSD.org
COMMENT=	Build packages inside a chroot jail
LICENSE=	modified-bsd

CONFLICTS=	pkg_comp-[0-9]*

ONLY_FOR_PLATFORM=	NetBSD-*-*

WRKSRC=		${WRKDIR}
NO_CONFIGURE=	YES
NO_BUILD=	YES

INSTALLATION_DIRS=	${PKGMANDIR}/man8 sbin

do-install:
	${INSTALL_SCRIPT} ${FILESDIR}/pkg_comp.sh ${DESTDIR}${PREFIX}/sbin/pkg_comp
	${INSTALL_MAN} ${FILESDIR}/pkg_comp.8 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man8/pkg_comp.8

.include "../../mk/bsd.pkg.mk"

File Added: pkgsrc/pkgtools/pkg_comp1/PLIST
@comment $NetBSD: PLIST,v 1.1 2017/02/12 10:48:55 jmmv Exp $
sbin/pkg_comp
man/man8/pkg_comp.8

File Added: pkgsrc/pkgtools/pkg_comp1/files/pkg_comp.8
.\" $NetBSD: pkg_comp.8,v 1.1 2017/02/12 10:48:55 jmmv Exp $
.\"
.\" pkg_comp - Build packages inside a clean chroot environment
.\" Copyright (c) 2002, 2003, 2004, 2005 Julio M. Merino Vidal <jmmv@NetBSD.org>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Neither the name of The NetBSD Foundation nor the names of its
.\"    contributors may be used to endorse or promote products derived
.\"    from this software without specific prior written permission.
.\" 3. Neither the name of author nor the names of its contributors may
.\"    be used to endorse or promote products derived from this software
.\"    without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd August 17, 2015
.Dt PKG_COMP 8
.Os
.Sh NAME
.Nm pkg_comp
.Nd build packages inside a sandbox
.Sh SYNOPSIS
.Nm
.Oo Fl Po
.Cm c Ns \&| Ns Cm C
.Pc
.Ar conf_file
.Oc
.Op Fl Nn
.Ar target
.Op Ar pkg_name ...
.Sh DESCRIPTION
.Nm ,
or
.Em Package Compiler
in its full name,
is a tool that makes easy the compilation of packages inside a clean
sandbox.
This allows an easy tracking of exact dependencies
and the correct behavior of a package in a fresh system installation.
.Pp
The behavior of
.Nm
is controlled through a small configuration file and a target (keep
reading to learn more).
The configuration file tells
.Nm
how to configure the new chroot environment, and the target specifies
which action to take.
.Pp
The following options are recognized:
.Bl -tag -width XcXconf_file
.It Fl C Ar conf_file
Use
.Ar conf_file
as configuration file (full path expected).
.It Fl c Ar conf_file
Use
.Ar conf_file
as configuration file (only base name expected).
.It Fl N
With the exception of
.Pa pkgtools/libkver
(see
.Va NETBSD_RELEASE )
avoid installation of default packages as well as
.Va INSTALL_PACKAGES
and
.Va BUILD_PACKAGES
during the creation of the chroot.
.It Fl n
Avoid installation of
.Va INSTALL_PACKAGES
and
.Va BUILD_PACKAGES
during the creation of the chroot.
.El
.Ss What to use it for?
You can use
.Nm
to achieve many goals when building packages.
Here are some ideas:
.Bl -bullet
.It
Build packages for other system versions.
For example, build packages for
.Nx 4.0
while you are running
.Nx 5.0 .
.It
Build packages using different
.Pa mk.conf
options than your current system, like changing the threading library,
.Sy COPTS ,
placement of configuration files, etc.
.It
Debug the build process of a package, checking if buildlinks work
properly.
.It
Avoid autoconf's side effects by keeping a separate chroot for each
project, like one for GNOME2 and another one for KDE3.
.It
Schedule builds of package sets for several different machines.
.El
.Sh CONTROL DIRECTORY
.Nm
needs to store several pieces of information when it is running.
Instead of using normal system trees, it uses a special directory inside the
chroot to avoid polluting the system.
It stores there scripts, object files, built packages, etc.
This directory is
.Pa $DESTDIR/pkg_comp ;
the symbolic link
.Pa $DESTDIR/p
is automatically created to ease pathnames when working inside the chroot.
.Sh CONFIGURATION
With
.Nm
you can maintain several configuration files so you can work with
different chroot jails easily.
To make this easy, configuration files are stored inside
.Pa $HOME/pkg_comp ,
followed by the configuration file name and the .conf suffix.
The default configuration file is
.Pa $HOME/pkg_comp/default.conf ,
and is always used if you do not specify another one.
The configuration file name is specified by the argument of the
.Fl c
option.
Alternatively you can specify any pathname as a configuration file
with the argument of the
.Fl C
option.
.Pp
Configuration files are simple shell scripts that define
variables.
The default values shown here are those written in the template when
issuing a maketemplate.
.Bl -tag -width indent
.It AUTO_PACKAGES
A list of packages to automatically build during the
.Sy auto
target.
A package is in the form
.Sq section/name ,
like
.Sq misc/colorls ,
or a plain name like
.Sq colorls .
Defaults to nothing.
.It AUTO_TARGET
The pkgsrc target to use when building packages in an automated fashion
(using the
.Ql auto
target).
Should be set to
.Ql package
or
.Ql bin-install ,
as other values are useless.
Defaults to
.Ql package .
.It BUILD_PACKAGES
A list of packages to automatically build after the
.Sy makeroot
target.
A package is in the form
.Sq section/name ,
like
.Sq misc/colorls ,
or a plain name like
.Sq colorls .
Defaults to nothing.
.It BUILD_PKG_COMP_TARGET
The pkgsrc target to use when building packages.
It can contain any target supported by the pkgsrc system, but
reasonable values are:
.Ql install ,
.Ql package
and
.Ql bin-install .
Defaults to
.Ql package .
.It COPYROOTCFG
If set to
.Ql yes ,
all configuration files (not directories) that reside inside
.Pa /root
are copied to
.Sy $DESTDIR/root .
Defaults to
.Ql no .
.It DESTDIR
The chroot jail directory.
Defaults to
.Pa /var/chroot/pkg_comp/default .
.It DISTRIBDIR
This is the directory which holds
.Nb
binary sets and X sets.
Its structure is the same as official release
distributions, that is, tgz files must reside inside
.Pa $DISTRIBDIR/binary/sets .
Defaults to
.Pa /var/pub/NetBSD .
.It EXTRAMK
Specifies a whitespace-separated list of files that must be appended to
.Pa $DESTDIR/etc/mk.conf .
This is useful to add special items to this configuration file.
Defaults to nothing.
.It INSTALL_PACKAGES
A list of packages to automatically install after the
.Sy makeroot
and before installing
.Sy BUILD_PACKAGES .
These are also installed within the sandbox created by the
.Sy auto
target, but before anything is built.
Each name must be the full package name, including the tgz suffix.
Packages are searched inside
.Pa $REAL_PACKAGES/All .
Defaults to nothing.
.It GENERATE_PKG_SUMMARY
If set to
.Sq yes ,
generate a new
.Pa $REAL_PACKAGES/pkg_summary.gz
file at the end of every package build by both the
.Sq auto
and
.Sq build
targets.
.It LOCALBASE
Where binary packages get installed.
Defaults to
.Pa /usr/pkg .
.It MKCONF_VARS
A list of variable names that will be appended to the generated
.Pa /etc/mk.conf
file, together with their values set in the configuration file.
Its default value contains all variables listed here.
.It NETBSD_RELEASE
Specifies which version number of
.Nx
is installed inside the chroot.
If set to
.Ql no ,
no special action is taken (this is useful if the system version inside
the chroot matches the outside one).
Otherwise, the package
.Pa pkgtools/libkver
will be installed inside the chroot, in a special purpose
prefix whose value can be set in
.Pa $DESTDIR/etc/mk.conf
via the configuration file
with the
.Va LIBKVER_STANDALONE_PREFIX
variable.
The libkver library will be configured inside the chroot, with the symbolic link
.Pa $DESTDIR/libkver_osrelease
and
.Va LD_PRELOAD
in default shells environments,
so that the
.Nx
version specified in
.Va NETBSD_RELEASE
overrides the host system version.
See
.Xr kver 3
for more information.
Defaults to
.Ql no .
.It PKG_DBDIR
Location of the packages database.
Defaults to
.Pa /var/db/pkg .
.It PKG_SYSCONFBASE
Base directory of configuration files.
Defaults to
.Pa /usr/pkg/etc .
.It PKGSRC_COMPILER
List of values specifying the chain of compilers to invoke when building
packages.
Defaults to
.Ql gcc .
If you are defining
.Va REAL_CCACHE ,
remember to prepend
.Ql ccache
to this variable's value.
.It PKGVULNDIR
Directory where the
.Pa vulnerabilities
file will be installed (inside the chroot).
Defaults to
.Pa /usr/pkg/share .
.It REAL_PKGVULNDIR
Directory where the system-wide
.Pa vulnerabilities
file resides (outside the chroot).
Defaults to
.Pa /usr/pkgsrc/distfiles .
.It ROOTSHELL
The shell of the root user.
Defaults to
.Pa /bin/ksh .
.It SETS
A list of binary sets to be extracted inside
.Sy DESTDIR .
Defaults to
.Ql base.tgz comp.tgz etc.tgz kern-GENERIC.tgz text.tgz .
If no kernel is extracted by these sets, an empty
.Pa /netbsd
file is created inside the chroot.
.It SETS_X11
A list of binary sets of the X Window system.
This has the same behavior
as
.Sy SETS .
If this variable is set to
.Ql no ,
no X Window is configured inside the chroot
jail and no other X variables take effect.
Defaults to
.Ql xbase.tgz xcomp.tgz xetc.tgz xfont.tgz xserver.tgz .
.It SYNC_UMOUNT
If set to
.Ql yes ,
run
.Xr sync 8
three times after all file systems have been unmounted.
Defaults to
.Ql no .
.It USE_AUDIT_PACKAGES
If set to
.Ql yes ,
let
.Nm
handle the
.Pa vulnerabilities
file automatically.
This means that it will install the system-wide
.Pa vulnerabilities
file inside the chroot when needed, keeping both in sync.
Defaults to
.Ql yes .
.It USE_GCC3
If set to
.Ql yes ,
the GNU C Compiler version 3 will be installed inside the chroot
environment and used to build all packages, using the
.Pa lang/gcc3
package.
Defaults to
.Ql no .
.El
.Ss Mounted file systems
In order to avoid duplicating huge system trees,
.Nm
takes advantage of file system layers.
By default, it uses
.Xr mount_null 8 ,
which duplicates a file system tree into another directory; although
you may want to use
.Xr mount_union 8 ,
or even
.Xr mount_overlay 8 .
If the
content of these variables is empty, that file system is not mounted.
.Pp
You can control which layer to use and which options you want with
special configuration options, as explained below.
.Pp
These file systems are mounted before entering the chroot and unmounted
after exiting.
In order to know if file systems are mounted or not, the
program uses a temporary file, called
.Pa $DESTDIR/pkg_comp/tmp/mount.stat ,
which controls the number of
.Nm
processes using the chroot environment.
If some of them crashes unexpectedly and you notice it does not try
to unmount the file systems, this status file may get out of sync.
Be sure to check that NO file systems are mounted when issuing a
.Sy removeroot .
.Bl -tag -width indent
.It REAL_CCACHE
Specifies where a global ccache directory resides in the real system.
Defaults to nothing, which disables the global cache.
Keep in mind that this is specially useful to keep the cache across
rebuilds of the sandbox, but be very careful if you plan to share a
cache directory between different sandboxes, as this can lead to problems.
.It REAL_DISTFILES
Specifies where distfiles reside in the real system.
Defaults to
.Pa /usr/pkgsrc/distfiles .
.It REAL_DISTFILES_OPTS
Mount options.
Defaults to
.Sy -t null -o rw .
.It REAL_PACKAGES
Specifies where to build binary packages.
This variable is specially useful.
Defaults to
.Pa /usr/pkgsrc/packages .
.It REAL_PACKAGES_OPTS
Mount options.
Defaults to
.Sy -t null -o rw .
.It REAL_PKGSRC
The pkgsrc tree.
This can be useful if you want to use several pkgsrc trees independently.
Defaults to
.Pa /usr/pkgsrc .
.It REAL_PKGSRC_OPTS
Mount options.
Defaults to
.Sy -t null -o ro .
.It REAL_SRC
The src system tree.
Usually useless, but may be needed by some packages.
Defaults to
.Pa /usr/src .
.It REAL_SRC_OPTS
Mount options.
Defaults to
.Sy -t null -o ro .
.It MAKEROOT_HOOKS
A whitespace separated list of functions or external scripts to be executed
after the sandbox is created.
Two arguments are given to each of them:
.Ar $DESTDIR ,
and the word
.Ar makeroot .
Defaults to nothing.
.It MOUNT_HOOKS
A whitespace separated list of functions or external scripts to be executed
after file systems are mounted.
Two arguments are given to each of them:
.Ar $DESTDIR ,
and the word
.Ar mount .
Defaults to nothing.
.It UMOUNT_HOOKS
A whitespace separated list of functions or external scripts to be executed
before file systems are unmounted.
Two arguments are given to each of them:
.Ar $DESTDIR ,
and the word
.Ar umount .
Defaults to nothing.
.El
.Sh TARGETS
A target specifies what
.Nm
should do (as in make).
The following list describes all supported targets,
in the logical order you should call them.
.Bl -tag -width indent
.It maketemplate
Create a sample
.Ar conf_file .
You should edit it after the creation as you will probably want to change
the default configuration, specially paths.
.It makeroot
Create the chroot environment, based on the specs of the configuration file.
This step is required before trying any other, except maketemplate.
.It build
Builds the specified packages inside the chroot.
You can pass the package names as a relative path within pkgsrc or as the
basename of the package directory (i.e. omitting the directory name).
.It install
Install the specified binary packages into the chroot.
Package names can contain globs.
The package files will be taken from within
.Sy REAL_PACKAGES .
.It chroot
Enters the chroot environment.
If no arguments are given,
.Va ROOTSHELL
is executed, otherwise whatever you typed.
If the first argument begins with a word prefixed by
.Li pkg_ ,
then the
.Ql chroot
argument can be omitted (it is implied).
.It removeroot
Remove the entire chroot tree.
You should do it with this target because it
will take care to umount needed mount points.
.It auto
This executes several targets automatically, using
.Sy AUTO_TARGET
as
.Sy BUILD_PKG_COMP_TARGET
during the build.
The order is: makeroot, build and removeroot.
This is useful to create binary packages of several pkgsrc and their
dependencies automatically.
For this to be useful, you need to set
.Sy REAL_PACKAGES
and use
.Sy AUTO_PACKAGES
or pass package names through the command line.
.Pp
If the magic word
.Ql resume
is passed as the unique argument to this target,
.Nm
will attempt to resume a previous automatic build for the given configuration.
.El
.Sh NOTES
This program uses nullfs to create virtual copies of real trees inside the
chroot environment.
.Pp
You need to install the
.Pa security/audit-packages
package in the host system (and have an up to date vulnerabilities database)
if you want security checks to work inside the
chroot environment.
.Sh SEE ALSO
.Xr pkg_delete 1 ,
.Xr pkgsrc 7 ,
.Xr mount_null 8 ,
.Xr sync 8 ,
.Xr sysctl 8
.Sh AUTHORS
.An Julio M. Merino Vidal Aq Mt jmmv@NetBSD.org

File Added: pkgsrc/pkgtools/pkg_comp1/files/pkg_comp.sh
#!/bin/sh
#
# $NetBSD: pkg_comp.sh,v 1.1 2017/02/12 10:48:55 jmmv Exp $
#
# pkg_comp - Build packages inside a clean chroot environment
# Copyright (c) 2002, 2003, 2004, 2005 Julio M. Merino Vidal <jmmv@NetBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 3. Neither the name of author nor the names of its contributors may
#    be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

ProgName="`basename $0`"

# ----------------------------------------------------------------------
# Default environment values and functions
# ----------------------------------------------------------------------

# USE_GCC3, CFLAGS, CPPFLAGS and CXXFLAGS are ommited from _MKCONF_VARS
# as they require special handling.
_MKCONF_VARS="WRKDIR_BASENAME MKOBJDIRS BSDSRCDIR WRKOBJDIR DISTDIR PACKAGES \
              PKG_DEVELOPER CLEANDEPENDS LOCALBASE PKG_SYSCONFBASE \
              CFLAGS CPPFLAGS CXXFLAGS USE_AUDIT_PACKAGES PKGVULNDIR \
              PKGSRC_COMPILER \
              LIBKVER_STANDALONE_PREFIX PKG_DBDIR"

_TEMPLATE_VARS="DESTDIR ROOTSHELL BUILD_PKG_COMP_TARGET COPYROOTCFG DISTRIBDIR \
		SETS SETS_X11 REAL_SRC REAL_SRC_OPTS REAL_PKGSRC \
                REAL_PKGSRC_OPTS REAL_DISTFILES REAL_DISTFILES_OPTS \
                REAL_PACKAGES REAL_PACKAGES_OPTS REAL_PKGVULNDIR \
                NETBSD_RELEASE MAKEROOT_HOOKS MOUNT_HOOKS UMOUNT_HOOKS \
                SYNC_UMOUNT AUTO_TARGET AUTO_PACKAGES BUILD_PACKAGES \
                REAL_CCACHE LIBKVER_STANDALONE_PREFIX GENERATE_PKG_SUMMARY"

_BUILD_RESUME=

# env_clean
#
#   Sets all variables that may appear in the config file to the null
#   string, so that we know the environment is in a consistent state.
#
env_clean()
{
    MKCONF_VARS=""
    TEMPLATE_VARS=""
    for var in ${_MKCONF_VARS} ${_TEMPLATE_VARS}; do
        eval $var=\"\"
    done
}

# env_setdefaults
#
#   Sets several reasonable defaults for many variables we will use.
#   Also checks for deprecated variables and warns the user about them.
#   To be called after reading the configuration file.
#
env_setdefaults()
{
    MKCONF_VARS="$MKCONF_VARS ${_MKCONF_VARS}"
    TEMPLATE_VARS="$TEMPLATE_VARS ${_TEMPLATE_VARS}"

    # Default values for variables that will be written to mk.conf.
    : ${WRKDIR_BASENAME:=default}
    : ${MKOBJDIRS:=yes}
    : ${BSDSRCDIR:=/usr/src}
    : ${WRKOBJDIR:=/pkg_comp/obj/pkgsrc}
    : ${DISTDIR:=/pkg_comp/distfiles}
    : ${PACKAGES:=/pkg_comp/packages}
    : ${PKG_DEVELOPER:=yes}
    : ${CLEANDEPENDS:=yes}
    : ${LOCALBASE:=/usr/pkg}
    : ${PKG_SYSCONFBASE:=/usr/pkg/etc}
    : ${CFLAGS:=}
    : ${CPPFLAGS:=}
    : ${CXXFLAGS:=}
    : ${USE_GCC3:=no}
    : ${USE_AUDIT_PACKAGES:=yes}
    : ${PKGVULNDIR:=/usr/pkg/share}
    : ${PKGSRC_COMPILER:=gcc}
    : ${PKG_DBDIR:=/var/db/pkg}

    # Default values for global variables used in the script.
    : ${DESTDIR:=/var/chroot/pkg_comp/default}
    : ${ROOTSHELL:=/bin/ksh}
    : ${COPYROOTCFG:=no}
    : ${AUTO_TARGET:=package}
    : ${BUILD_PKG_COMP_TARGET:=package}
    : ${DISTRIBDIR:=/var/pub/NetBSD}
    : ${SETS:=base.tgz comp.tgz etc.tgz kern-GENERIC.tgz text.tgz}
    : ${SETS_X11:=xbase.tgz xcomp.tgz xetc.tgz xfont.tgz xserver.tgz}
    : ${REAL_SRC:=/usr/src}
    : ${REAL_SRC_OPTS:=-t null -o ro}
    : ${REAL_PKGSRC:=/usr/pkgsrc}
    : ${REAL_PKGSRC_OPTS:=-t null -o ro}
    : ${REAL_DISTFILES:=/usr/pkgsrc/distfiles}
    : ${REAL_DISTFILES_OPTS:=-t null -o rw}
    : ${REAL_PACKAGES:=/usr/pkgsrc/packages}
    : ${REAL_PACKAGES_OPTS:=-t null -o rw}
    : ${REAL_PKGVULNDIR:=/usr/pkgsrc/distfiles}
    : ${NETBSD_RELEASE:=no}
    : ${LIBKVER_STANDALONE_PREFIX:=/libkver}
    : ${MAKEROOT_HOOKS:=}
    : ${MOUNT_HOOKS:=}
    : ${UMOUNT_HOOKS:=}
    : ${SYNC_UMOUNT:=no}
    : ${REAL_CCACHE:=}
    : ${GENERATE_PKG_SUMMARY:=yes}

    if [ -n "${MAKE_PACKAGES}" ]; then
        warn "MAKE_PACKAGES is deprecated; use {AUTO,BUILD}_PACKAGES instead."
        : ${AUTO_PACKAGES:=${MAKE_PACKAGES}}
        : ${BUILD_PACKAGES:=${MAKE_PACKAGES}}
    fi

    if [ -n "${MOUNT_SCRIPT}" ]; then
        warn "MOUNT_SCRIPT is deprecated; use MOUNT_HOOKS instead."
        : ${MOUNT_HOOKS:=${MOUNT_SCRIPT}}
    fi

    if [ -n "${UMOUNT_SCRIPT}" ]; then
        warn "UMOUNT_SCRIPT is deprecated; use UMOUNT_HOOKS instead."
        : ${UMOUNT_HOOKS:=${UMOUNT_SCRIPT}}
    fi
}

# ----------------------------------------------------------------------
# Misc functions
# ----------------------------------------------------------------------

# err msg
#
#   Shows the given error message and exit.
#
err()
{
    echo "$ProgName: $1" 1>&2
    exit 1
}

# warn msg
#
#   Shows the given warning message.
#
warn()
{
    echo "$ProgName: $1" 1>&2
}

# usage
#
#   Shows an usage message and exits.
#
usage()
{
    echo "usage: $ProgName [-(c|C) conf_file] [-Nn] target [pkg_names]" 1>&2
    exit 1
}

# copy_vulnerabilities
#
#   If USE_AUDIT_PACKAGES is set to 'yes', this function copies the
#   system-wide pkg-vulnerabilities file inside the sandbox.
#
copy_vulnerabilities()
{
    if [ "$USE_AUDIT_PACKAGES" = "yes" ]; then
        echo "PKG_COMP ==> Installing new \`pkg-vulnerabilities' file"
        if [ ! -f "$REAL_PKGVULNDIR/pkg-vulnerabilities" ]; then
            echo "$REAL_PKGVULNDIR/pkg-vulnerabilities not found."
        else
            mkdir -p $DESTDIR/$PKGVULNDIR
            cp $REAL_PKGVULNDIR/pkg-vulnerabilities $DESTDIR/$PKGVULNDIR
        fi
    fi
}

# init_script filename
#
#   Create a script that will be used within the sandbox and write some
#   common content to it.
#
init_script()
{
    rm -f $1
    cat >$1 <<EOF
#!/bin/sh
# Generated by pkg_comp on `date`

if [ -f ${LIBKVER_STANDALONE_PREFIX}/lib/libkver.so ]; then
    LD_PRELOAD=${LIBKVER_STANDALONE_PREFIX}/lib/libkver.so; export LD_PRELOAD
fi

EOF
}

# ----------------------------------------------------------------------
# Filesystem functions
# ----------------------------------------------------------------------

# fsmount
#
#   Mounts all sandboxed filesystems, if they are not mounted yet.
#
fsmount()
{
    echo "PKG_COMP ==> Mounting sandboxed filesystems"
    if [ -f $fsstate ]; then
        count=`cat $fsstate`
        count=$(($count + 1))
        echo "$count" > $fsstate
        echo "Already mounted (maybe by another pkg_comp process?)"
        return
    else
        echo "1" > $fsstate
    fi

    if [ -n "$REAL_SRC" ]; then
        if [ ! -d "$REAL_SRC" ]; then
            echo " failed."
            fsumount
            err "REAL_SRC $REAL_SRC disappeared"
        fi
        mount $REAL_SRC_OPTS $REAL_SRC $DESTDIR/usr/src
    fi

    if [ -n "$REAL_PKGSRC" ]; then
        if [ ! -d "$REAL_PKGSRC" ]; then
            echo " failed."
            fsumount
            err "REAL_PKGSRC $REAL_PKGSRC disappeared"
        fi
        mount $REAL_PKGSRC_OPTS $REAL_PKGSRC $DESTDIR/usr/pkgsrc
    fi

    if [ -n "$REAL_DISTFILES" ]; then
        if [ ! -d "$REAL_DISTFILES" ]; then
            echo " failed."
            fsumount
            err "REAL_DISTFILES $REAL_DISTFILES disappeared"
        fi
        mount $REAL_DISTFILES_OPTS $REAL_DISTFILES $DESTDIR/pkg_comp/distfiles
    fi

    if [ -n "$REAL_PACKAGES" ]; then
        if [ ! -d "$REAL_PACKAGES" ]; then
            echo " failed."
            fsumount
            err "REAL_PACKAGES $REAL_PACKAGES disappeared"
        fi
        mount $REAL_PACKAGES_OPTS $REAL_PACKAGES $DESTDIR/pkg_comp/packages
    fi

    if [ -n "${REAL_CCACHE}" ]; then
        if [ ! -d "${REAL_CCACHE}" ]; then
            echo " failed."
            fsumount
            err "REAL_CCACHE ${REAL_CCACHE} disappeared"
        fi
        mount -t null -o rw ${REAL_CCACHE} ${DESTDIR}/pkg_comp/ccache
    fi

    touch $fsstate

    if [ -n "${MOUNT_HOOKS}" ]; then
        echo "Executing mount hooks."
        for h in ${MOUNT_HOOKS}; do
            ${h} ${DESTDIR} mount
        done
    fi
}

# fsumount
#
#   Unmounts all sandboxed filesystems, if they are not in use any more.
#
fsumount()
{
    echo "PKG_COMP ==> Unmounting sandboxed filesystems"

    if [ ! -f $fsstate ]; then
        echo "None mounted."
        return
    fi

    count=`cat $fsstate`
    if [ $count -gt 1 ]; then
        count=$(($count - 1))
        echo "$count" > $fsstate
        echo "Still in use (maybe by another pkg_comp process?)"
        return
    fi

    if [ -n "${UMOUNT_HOOKS}" ]; then
        echo "Executing umount hooks."
        for h in ${UMOUNT_HOOKS}; do
            ${h} ${DESTDIR} umount
        done
    fi

    fsfailed=no

    if [ -n "$REAL_SRC" -a -d "$REAL_SRC" ]; then
        umount $DESTDIR/usr/src || fsfailed=yes
    fi

    if [ -n "$REAL_PKGSRC" -a -d "$REAL_PKGSRC" ]; then
        umount $DESTDIR/usr/pkgsrc || fsfailed=yes
    fi

    if [ -n "$REAL_DISTFILES" -a -d "$REAL_DISTFILES" ]; then
        umount $DESTDIR/pkg_comp/distfiles || fsfailed=yes
    fi

    if [ -n "$REAL_PACKAGES" -a -d "$REAL_PACKAGES" ]; then
        umount $DESTDIR/pkg_comp/packages || fsfailed=yes
    fi

    if [ -n "${REAL_CCACHE}" -a -d "${REAL_CCACHE}" ]; then
        umount ${DESTDIR}/pkg_comp/ccache || fsfailed=yes
    fi

    if [ "$SYNC_UMOUNT" != "no" ]; then
        printf "Syncing: 1"
        sync ; sleep 1
        printf " 2"
        sync ; sleep 1
        printf " 3"
        sync ; sleep 1
        echo " done."
    fi

    if [ "$fsfailed" = "yes" ]; then
        err "FATAL: failed to umount all filesystems"
    else
        rm $fsstate
    fi
}

# ----------------------------------------------------------------------
# maketemplate target
# ----------------------------------------------------------------------

# pkg_maketemplate
#
#   Generates a sample configuration file based on the list of variables
#   given in TEMPLATE_VARS and MKCONF_VARS.
#
pkg_maketemplate()
{
    if [ -f "$conffile" ]; then
        err "$conffile already exists"
    fi

    mkdir -p $confdir
    cat > $conffile <<EOF
# -*- sh -*-
#
# pkg_comp - configuration file
# See pkg_comp(8) for a detailed description of each variable.
#

EOF

    echo "# Variables used internally by pkg_comp." >> $conffile
    for var in `echo $TEMPLATE_VARS | tr ' ' '\n' | sort`; do
        eval val=\""\$$var"\"
        echo "$var=\"$val\"" >> $conffile
    done

    echo >> $conffile
    echo "# Default variables written to the generated mk.conf." >> $conffile
    for var in `echo $MKCONF_VARS | tr ' ' '\n' | sort`; do
        eval val=\""\$$var"\"
        echo "$var=\"$val\"" >> $conffile
    done

    echo "pkg_comp: $conffile created.  Edit the file by hand now."
}

# ----------------------------------------------------------------------
# makeroot target
# ----------------------------------------------------------------------

# pkg_makeroot
#
#   The 'makeroot' target.  This creates a new sandbox and then issues
#   some stuff to be called only when using this specific target.
#
pkg_makeroot()
{
    makeroot

    [ "$nflag" = "no" -a -n "$INSTALL_PACKAGES" ] &&
        pkg_install $INSTALL_PACKAGES

    if [ "$nflag" = "no" -a -n "$BUILD_PACKAGES" ]; then
        for pkg in $BUILD_PACKAGES; do
            build_and_install $pkg
        done
    fi
}

# makeroot
#
#   Creates a new sandbox.  This is independent from 'makeroot' and
#   'auto' targets.
#
makeroot()
{
    # Check for directories that will be null mounted.
    if [ -n "$REAL_SRC" -a ! -d "$REAL_SRC" ]; then
        err "REAL_SRC $REAL_SRC does not exist"
    fi

    if [ -n "$REAL_PKGSRC" -a ! -d "$REAL_PKGSRC" ]; then
        err "REAL_PKGSRC $REAL_PKGSRC does not exist"
    fi

    if [ -n "$REAL_DISTFILES" -a ! -d "$REAL_DISTFILES" ]; then
        err "REAL_DISTFILES $REAL_DISTFILES does not exist"
    fi

    if [ -n "$REAL_PACKAGES" -a ! -d "$REAL_PACKAGES" ]; then
        err "REAL_PACKAGES $REAL_PACKAGES does not exist"
    fi

    if echo ${PKGSRC_COMPILER} | grep ccache >/dev/null 2>&1 && \
        [ -z "${REAL_CCACHE}" ]; then
        warn "PKGSRC_COMPILER contains 'ccache' but REAL_CCACHE is unset"
    elif [ -n "${REAL_CCACHE}" -a ! -d "${REAL_CCACHE}" ]; then
        err "REAL_CCACHE ${REAL_CCACHE} does not exist"
    fi

    # Check for required directories.
    if [ ! -d $DISTRIBDIR ]; then
        err "DISTRIBDIR $DISTRIBDIR does not exist"
    fi

    if [ -d $DESTDIR ]; then
        err "DESTDIR $DESTDIR already exists"
    fi

    if [ "$SETS_X11" = "no" ]; then
        allsets="$SETS"
    else
        allsets="$SETS $SETS_X11"
    fi

    for s in $allsets; do
        if [ ! -f $DISTRIBDIR/binary/sets/$s ]; then
            err "$DISTRIBDIR/binary/sets/$s does not exist"
        fi
    done

    echo "PKG_COMP ==> Creating sandbox \`${DESTDIR}'"

    mkdir -p $DESTDIR
    cd $DESTDIR

    for s in $allsets; do
        echo "Extracting $s..."
        tar xzpf $DISTRIBDIR/binary/sets/$s
    done

    [ -f ${DESTDIR}/netbsd ] || touch ${DESTDIR}/netbsd

    echo "Making device nodes..."
    cd $DESTDIR/dev
    ./MAKEDEV all
    cd $DESTDIR

    echo "Setting root's environment..."
    chroot $DESTDIR chpass -s $ROOTSHELL
    if [ "$COPYROOTCFG" = "yes" ]; then
        cp /root/.* $DESTDIR/root >/dev/null 2>&1
    fi
    if [ -n "${REAL_CCACHE}" ]; then
        # This is a workaround for older versions of ccache.mk that do not
        # pass the CCACHE_DIR variable down to ccache.
        ( cd ${DESTDIR}/root && ln -fs ../pkg_comp/ccache .ccache )
    fi

    echo "Setting up initial configuration..."

    mkdir -p $DESTDIR/usr/src
    mkdir -p $DESTDIR/usr/pkgsrc
    mkdir -p $DESTDIR/pkg_comp/distfiles
    mkdir -p $DESTDIR/pkg_comp/packages
    mkdir -p $DESTDIR/pkg_comp/tmp
    mkdir -p $DESTDIR/pkg_comp/obj/pkgsrc
    [ -n "${REAL_CCACHE}" ] && mkdir -p ${DESTDIR}/pkg_comp/ccache
    ( cd $DESTDIR && ln -s pkg_comp p )

    # Set sh configuration
    echo "umask 022" >> $DESTDIR/etc/profile
    echo "ENV=/etc/shrc" >> $DESTDIR/etc/profile
    echo "export PS1=\"pkg_comp:`basename $conffile`# \"" >> $DESTDIR/etc/shrc
    echo "set -o emacs" >> $DESTDIR/etc/shrc
    echo "export PKG_DBDIR=\"${PKG_DBDIR}\"" >> ${DESTDIR}/etc/shrc

    # Set csh configuration
    echo "umask 022" >> $DESTDIR/etc/csh.login
    echo "set prompt=\"pkg_comp:`basename $conffile`# \"" >> $DESTDIR/etc/csh.login
    echo "set prompt=\"pkg_comp:`basename $conffile`# \"" >> $DESTDIR/etc/csh.cshrc
    echo "setenv PKG_DBDIR \"${PKG_DBDIR}\"" >> ${DESTDIR}/etc/csh.cshrc

    cp /etc/resolv.conf $DESTDIR/etc/resolv.conf

    makeroot_mkconf

    echo "PKG_DBDIR=${PKG_DBDIR}" >> ${DESTDIR}/etc/pkg_install.conf

    # From now on, filesystems may be mounted, so we need to trap
    # signals to umount them.
    trap "echo \"*** Process aborted ***\" ; fsumount ; exit 1" INT QUIT

    makeroot_libkver

    if [ "$USE_GCC3" = "yes" -a "$Nflag" = "no" ]; then
        if [ -z "`echo $BUILD_PACKAGES $INSTALL_PACKAGES | grep gcc3`" ]; then
            AVOID_GCC3=yes build_and_install lang/gcc3
        fi
    fi

    makeroot_x11

    if [ -n "${MAKEROOT_HOOKS}" ]; then
        echo "Executing makeroot hooks."
        for h in ${MAKEROOT_HOOKS}; do
            ${h} ${DESTDIR} makeroot
        done
    fi
}

# makeroot_mkconf
#
#   Generates a mk.conf file inside the sandbox, based on the content
#   of MKCONF_VARS and EXTRAMK.  Also handles some special stuff.
#
makeroot_mkconf()
{
    file="$DESTDIR/etc/mk.conf"

    cat >> $file <<EOF
#
# /etc/mk.conf
# File automatically generated by pkg_comp on `date`
#
.ifdef BSD_PKG_MK

EOF

    for var in $MKCONF_VARS; do
        eval val=\""\$$var"\"
        echo "$var ?= $val" >> $file
    done

    if [ -n "$EXTRAMK" ]; then
        for mkfile in $EXTRAMK; do
            if [ ! -f "$mkfile" ]; then
                err "Cannot find $mkfile"
            else
                cat $mkfile >> $file
            fi
        done
    fi

    if [ "$USE_AUDIT_PACKAGES" != "yes" ]; then
        echo "ALLOW_VULNERABLE_PACKAGES ?= YES" >> $file
    fi

    if [ "$USE_GCC3" = "yes" ]; then
        cat >>$file <<EOF
.if !defined(AVOID_GCC3) && exists(/usr/pkg/share/examples/gcc-3.3/mk.conf)
USE_GCC3 = yes
CFLAGS += $CFLAGS
CPPFLAGS += $CPPFLAGS
CXXFLAGS += $CXXFLAGS
.include "/usr/pkg/share/examples/gcc-3.3/mk.conf"
.endif
EOF
    else
        cat >>$file <<EOF
CFLAGS += $CFLAGS
CPPFLAGS += $CPPFLAGS
CXXFLAGS += $CXXFLAGS

.endif # BSD_PKG_MK
EOF
    fi
}

# makeroot_libkver
#
#   If NETBSD_RELEASE is set to a version string, installs libkver
#   inside the sandbox and configures it.
#
makeroot_libkver()
{
    local prefix script statfile

    if [ "$NETBSD_RELEASE" != "no" ]; then
        _BUILD_PKG_COMP_TARGET="$BUILD_PKG_COMP_TARGET"
        BUILD_PKG_COMP_TARGET="standalone-install"
        build_and_install pkgtools/libkver
        BUILD_PKG_COMP_TARGET="$_BUILD_PKG_COMP_TARGET"
        echo "LD_PRELOAD=${LIBKVER_STANDALONE_PREFIX}/lib/libkver.so; export LD_PRELOAD" >> $DESTDIR/etc/shrc
        echo "setenv LD_PRELOAD ${LIBKVER_STANDALONE_PREFIX}/lib/libkver.so" >> $DESTDIR/etc/csh.login
        echo "setenv LD_PRELOAD ${LIBKVER_STANDALONE_PREFIX}/lib/libkver.so" >> $DESTDIR/etc/csh.cshrc
        ln -s "$NETBSD_RELEASE" $DESTDIR/libkver_osrelease
    fi
}

# makeroot_x11
#
#   If X11 is enabled, installs x11-links inside the sandbox.
#
makeroot_x11()
{
    if [ "$SETS_X11" != "no" ]; then
        [ "$Nflag" = "no" ] && build_and_install pkgtools/x11-links
    fi
}

# ----------------------------------------------------------------------
# auto target
# ----------------------------------------------------------------------

# pkg_auto pkgs
#
#   The 'auto' target.
#
pkg_auto()
{
    local pkgs rfile target

    pkgs="${*:-${AUTO_PACKAGES}}"
    rfile=${DESTDIR}/pkg_comp/tmp/auto.list
    target="${AUTO_TARGET}"

    [ -z "${REAL_PACKAGES}" ] && err "this is useless without REAL_PACKAGES"
    [ -z "${pkgs}" ] &&
        err "this is useless without AUTO_PACKAGES nor package names"

    if [ "$1" = resume ]; then
        [ -f ${rfile} ] || err "there is no auto build to resume"
        pkgs=`cat ${rfile}`
    elif [ -f ${rfile} ]; then
        err "there is an stopped auto build; removeroot first or resume it"
    else
        makeroot

        [ "$nflag" = "no" -a -n "$INSTALL_PACKAGES" ] &&
            pkg_install $INSTALL_PACKAGES

        echo ${pkgs} | tr ' ' '\n' > ${rfile}
    fi

    checkroot
    _BUILD_RESUME=${rfile} BUILD_PKG_COMP_TARGET=${target} pkg_build ${pkgs}
    pkg_removeroot
}

# generate_pkg_summary directory
#
#    Generates a pkg_summary.gz file in the specified directory.
generate_pkg_summary()
{
    local directory="${1}"; shift

    echo "PKG_COMP ==> Generating pkg_summary.tgz"
    for pkg in "${directory}"/*.tgz; do pkg_info -X "${pkg}"; done \
        | gzip -c >"${directory}"/pkg_summary.gz
}

# ----------------------------------------------------------------------
# build target
# ----------------------------------------------------------------------

# pkg_build pkgs
#
#   The build target.  Also used as a helper function within this script
#   to build several packages when needed.
#
pkg_build()
{
    local failed invalid p pkgs script statfile

    pkgs=
    invalid=
    for pkg in "${@}"; do
        local match="$(find_pkg "${pkg}")"
        if [ -z "${match}" ]; then
            invalid="${invalid} ${pkg}"
        else
            pkgs="${pkgs} ${match}"
        fi
    done
    if [ -n "$invalid" ]; then
        err "invalid packages:$invalid"
    fi

    # Build them
    fsmount
    copy_vulnerabilities
    failed=""
    for p in $pkgs; do
        echo "PKG_COMP ==> Building and installing $p"
        prefix=$(mktemp $DESTDIR/pkg_comp/tmp/pkg_comp-XXXXXX)
        rm $prefix
        script="$prefix.sh"
        statfile="$prefix.stat"
        init_script $script
        cat >> $script <<EOF
cd /usr/pkgsrc/$p
make $BUILD_PKG_COMP_TARGET
if [ \$? != 0 ]; then
    touch /pkg_comp/tmp/`basename $statfile`
fi
make clean
EOF
        chmod +x $script
        chroot $DESTDIR /pkg_comp/tmp/`basename $script`
        rm $script
        if [ -f $statfile ]; then
            failed="$failed $p"
            rm $statfile
        elif [ -n "${_BUILD_RESUME}" ]; then
            grep -v "^${p}\$" < ${_BUILD_RESUME} > ${_BUILD_RESUME}.new
            mv ${_BUILD_RESUME}.new ${_BUILD_RESUME}
        fi
    done
    fsumount
    if [ -n "$failed" ]; then
        echo "PKG_COMP ==> Build error summary"
        echo "Build failed for:"
        for p in $failed; do
            echo "    $p"
        done
    fi
    if [ "${GENERATE_PKG_SUMMARY}" = yes ]; then
        generate_pkg_summary "${REAL_PACKAGES}/All"
    fi
}

# find_pkg name
#
#   Checks if the given package exists and outputs its path within pkgsrc.
#   Outputs nothing if the package is not found.
find_pkg()
{
    local name="${1}"

    case "${name}" in
    */*)
        if [ -d "${REAL_PKGSRC}/${name}" ]; then
            echo "${name}"
        else
            :  # Not found; output nothing.
        fi
        ;;
    *)
        local match="$(cd "${REAL_PKGSRC}" && echo */"${name}")"
        if [ -d "${REAL_PKGSRC}/${match}" ]; then
            echo "${match}"
        else
            :  # Not found; output nothing.
        fi
    esac
}

# build_and_install pkg
#
#   Builds a package and ensures it gets installed.  The use of destdir to
#   build packages may cause a package to get built but not installed,
#   which is not OK for this script.  This is for internal usage only.
#
build_and_install()
{
    pkg=${1}
    fsmount
    if pkg_build ${pkg}; then
        script=$(mktemp ${DESTDIR}/pkg_comp/tmp/pkg_comp-XXXXXX).sh
        init_script ${script}
        cat >>${script} <<EOF
cd /usr/pkgsrc/${pkg}
pkgname=\$(make show-var VARNAME=PKGNAME)
if pkg_info -E \${pkgname} 2>/dev/null; then
    :
else
    echo "PKG_COMP ==> Forcing installation of \${pkgname}"
    cd /pkg_comp/packages/All
    pkg_add \${pkgname}
fi
EOF
        chmod +x ${script}
        chroot ${DESTDIR} /pkg_comp/tmp/$(basename ${script})
        rm ${script}
    fi
    fsumount
}

# ----------------------------------------------------------------------
# install target
# ----------------------------------------------------------------------

# pkg_install pkgs
#
#   The install target.  Also used as a helper function within this
#   script to install several packages when needed.
#
pkg_install()
{
    local failed pkgs stat

    pkgs="$*"

    [ -z "$REAL_PACKAGES" ] && err "REAL_PACKAGES is not set"

    copy_vulnerabilities

    fsmount
    failed=""
    for p in $(cd ${REAL_PACKAGES}/All && echo ${pkgs}); do
        echo "PKG_COMP ==> Installing binary package: $p"
        stat=$DESTDIR/pkg_comp/tmp/install.sh
        init_script $stat
        cat >> $stat <<EOF
cd /pkg_comp/packages/All
pkg_add $p
EOF
        chmod +x $stat
        chroot $DESTDIR /pkg_comp/tmp/install.sh || failed="$failed $p"
        rm $stat
    done
    fsumount
    [ -n "$failed" ] && echo "Installation failed for:$failed"
}

# ----------------------------------------------------------------------
# chroot target
# ----------------------------------------------------------------------

# pkg_chroot cmd
#
#   The 'chroot' target.
#
pkg_chroot()
{
    local prefix script exitstatus

    [ -d $DESTDIR ] || err "$DESTDIR does not exist"

    copy_vulnerabilities

    fsmount
    echo "PKG_COMP ==> Entering sandbox \`$DESTDIR'"
    prefix=$(mktemp $DESTDIR/pkg_comp/tmp/pkg_comp-XXXXXX)
    rm $prefix
    script="$prefix.sh"
    init_script $script
    if [ $# -eq 0 ]; then
        cat >> $script <<EOF
ENV=/etc/shrc $ROOTSHELL
EOF
    else
        cat >> $script <<EOF
$*
EOF
    fi
    chmod +x $script
    ENV=/etc/shrc chroot $DESTDIR /pkg_comp/tmp/`basename $script`
    exitstatus=$?
    echo
    rm $script
    fsumount
    return $exitstatus
}

# ----------------------------------------------------------------------
# removeroot target
# ----------------------------------------------------------------------

# pkg_removeroot
#
#   The 'removeroot' target.
#
pkg_removeroot()
{
    [ -f $fsstate ] && err "filesystems may still be mounted; cannot remove"
    echo "PKG_COMP ==> Removing sandbox \`${DESTDIR}'"
    rm -rf $DESTDIR
}

# ----------------------------------------------------------------------
# Main program
# ----------------------------------------------------------------------

confdir="$HOME/pkg_comp"

# Parse options
args=`getopt c:C:nN $*`
if [ $? != 0 ]; then
    usage
fi
set -- $args
conffile=
nflag=no
Nflag=no
while [ $# -gt 0 ]; do
    case "$1" in
        -c)
            [ -n "$conffile" ] && usage
            conffile="$confdir/$2.conf"
            shift
            ;;
        -C)
            [ -n "$conffile" ] && usage
            conffile="$2"
            shift
            ;;
        -n)
            nflag=yes
            ;;
        -N)
            nflag=yes
            Nflag=yes
            ;;
        --)
            shift; break
            ;;
    esac
    shift
done

if [ $# -lt 1 ]; then
    usage
fi

if [ -z "$conffile" ]; then
    conffile="$confdir/default.conf"
fi

case "$1" in
    pkg_*)
        target=chroot
        ;;
    *)
        target="$1"
        shift
        ;;
esac
args="$*"

# readconf
#
#   Reads the configuration file and ensures that the environment is in
#   a consistent state.
#
readconf()
{
    if [ -f $conffile ]; then
        [ `id -u` -ne 0 ] && err "must be run as root"
        env_clean
        . $conffile
        env_setdefaults
    else
        err "$conffile does not exist"
    fi

    fsstate="$DESTDIR/pkg_comp/tmp/mount.stat"
}

# checkroot
#
#   Checks that the sandbox is initialized, that it's a valid directory
#   and configures a signal trap for SIGINT and SIGQUIT.
#
checkroot()
{
    if [ ! -d "$DESTDIR" ]; then
        err "sandbox not initialized; use makeroot first."
    fi
    if [ "$DESTDIR" = "/" ]; then
        err "DESTDIR cannot be /"
    fi

    # From now on, filesystems may be mounted, so we need to trap
    # signals to umount them.
    trap "echo \"*** Process aborted ***\" ; fsumount ; exit 1" INT QUIT
}

case "$target" in
    maketemplate)
        env_clean
        env_setdefaults
        pkg_maketemplate
        exit 0
        ;;
    makeroot)
        readconf
        pkg_makeroot
        exit 0
        ;;
    build)
        readconf
        checkroot
        pkg_build $args
        exit 0
        ;;
    install)
        readconf
        checkroot
        pkg_install $args
        exit 0
        ;;
    chroot)
        readconf
        checkroot
        pkg_chroot $args
        exit $?
        ;;
    removeroot)
        readconf
        checkroot
        pkg_removeroot
        ;;
    auto)
        readconf
        pkg_auto $args
        ;;
    *)
        err "unknown target \`$target'"
        ;;
esac

exit 0

# vim: expandtab:softtabstop=4:shiftwidth=4