2007-11-27

Using pkgsrc in Mac OS X

Mac OS X has the default of case insensitive HFS+ file system and it seems to me that although case sensitive HFSX+ is supported, the OS is not heavily tested on it. E.g. FileVault won't work with it at all. I opted to case sensitive disk images.

Create and populate /usr/pkgsrc

# mkdir /Library/Images
# hdiutil create -volname pkgsrc -size 10g -type SPARSEBUNDLE -fs HFSX /Library/Images/pkgsrc
# mkdir /usr/pkgsrc
# hdiutil attach /Library/Images/pkgsrc.sparsebundle -nobrowse -mountpoint /usr/pkgsrc -owners on
# cd /usr
# cvs -z3 -d anoncvs@anoncvs.NetBSD.org:/cvsroot co -P pkgsrc
# cd /usr/pkgsrc
# cvs -d:pserver:anonymous@pkgsrc-wip.cvs.sourceforge.net:/cvsroot/pkgsrc-wip login
CVS password:
# cvs -z3 -d:pserver:anonymous@pkgsrc-wip.cvs.sourceforge.net:/cvsroot/pkgsrc-wip co -P wip


Create /usr/pkg

# hdiutil create -volname pkg -size 10g -type SPARSEBUNDLE -fs HFSX /Library/Images/pkg
# mkdir /usr/pkg
# hdiutil attach /Library/Images/pkg.sparsebundle -nobrowse -mountpoint /usr/pkg -owners on


Jvvm figured out how to mount the images at boot time. http://julipedia.blogspot.com/2007/04/mounting-volumes-on-mac-os-xs-startup.html. I made a few changes. There is a configuration file for mounting images:

/etc/hditab:
# HD Image Tab configuration file
# Imagefile options (for hdiutil attach)
/Library/Images/pkgsrc.sparsebundle -nobrowse -mountpoint /usr/pkgsrc -owners on
/Library/Images/pkg.sparsebundle -nobrowse -mountpoint /usr/pkg -owners on

Using jvvm's example I made a startup item directory /Library/StartupItems/DiskImages/ with the following files in it. The latter needs to be executable.

/Library/StartupItems/DiskImages/StartupParameters.plist:
{
Description = "Automatic attachment of disk images";
OrderPreference = "First";
Uses = ("Disks");
}


/Library/StartupItems/DiskImages/DiskImages:
#! /bin/sh
. /etc/rc.common

basePath="/Library/StartupItems/DiskImages"
tabFile="/etc/hditab"

doCompact() {
cat $tabFile | while read image rest ; do
image=${image%%#*}
[ -z "$image" ] && continue
hdiutil compact $image
done
}

StartService() {
doCompact
cat $tabFile | while read line ; do
line=${line%%#*}
[ -z "$line" ] && continue
hdiutil attach $line
done
}


StopService() {
true
}

RestartService() {
true
}

RunService "$1"

The images should be automatically mounted at boot. Test the script by umounting /usr/pkgsrc and /usr/pkg manually and running:
# /Library/StartupItems/DiskImages/DiskImages start

Next pkgsrc needs to be bootstrapped

# cd /usr/pkgsrc/bootstrap
# ./bootstrap --prefix /usr/pkg --pkgdbdir /usr/pkg/pkgdb --sysconfdir /usr/pkg/etc --varbase /usr/pkg/var

To add pkgsrc in your path create file /etc/path.d/pkgsrc with lines /usr/pkg/bin and /usr/pkg/sbin. Manual page search path is set in file /etc/manpath.d/pkgsrc with line /usr/pkg/man. There is a default mk.conf in /usr/pkg/etc/mk.conf. I made the following changes to mine.

/usr/pkg/etc/mk.conf:
COPTS?= -pipe ${DEFCOPTS}
CFLAGS+= -pipe

.ifdef BSD_PKG_MK # begin pkgsrc settings

PKG_DBDIR= /usr/pkg/pkgdb
LOCALBASE= /usr/pkg
VARBASE= /usr/pkg/var
PKG_TOOLS_BIN= /usr/pkg/sbin
PKGMANDIR= man

TOOLS_PLATFORM.pax?= /usr/pkg/bin/pax
TOOLS_PLATFORM.tar?= /usr/pkg/bin/tar

#MAKE_JOBS ?= 2
WRKOBJDIR ?= /usr/pkg/var/obj
MASTER_SORT ?= .fi .se .no .ee

PKG_DEFAULT_OPTIONS += inet6

_ACCEPTABLES=yes

.endif # end pkgsrc settings


I used sparse images here, because I'm short on disk space but there are cons; Sparse images cause disk fragmentation and removing files from the image doesn't free the space until the image is compacted. If you really want to tune it up make ~1GB DMG for /usr/pkgsrc, big sparce image for /usr/pkg and a ~2GB /usr/pkg/var DMG for changing data. The set WRKOBJDIR?=/usr/pkg/var/obj and DISTDIR?=/usr/pkg/var/distfiles in mk.conf.

Comments and hints are very welcome :)