We use pkgsrc to maintain a consistent set of development sources across OS X, FreeBSD, Debian, and other Linux distributions. pkgsrc works reasonably well, has a decently large repository of packages (relatively easy to add a new package), active development, and is mostly portable.
Note: what follows is really only interesting if you’re looking into using pkgsrc, otherwise it’ll make you yawn. I’m writing this because I found little information on the web to help me out, and I wanted to make sure others don’t repeat my mistakes.
One portability problem we encountered was the use of sqlite3 with python25. When linking python25 against pkgsrc’s sqlite3 on OS X, we’d get “Non-aligned pointer being freed” errors, along the lines of this thread. In the thread, one person suggested to use the native sqlite3 library if it exists.
This was deeply unsatisfying to me. I was convinced there was simply some argument I had to pass into the sqlite3 build to make it magically work on OS X.
(This would suggest to me that pkgsrc’s sqlite3 on OS X is broken. Is the upstream sqlite3 broken as well?)
Alas, it broke me, and after hours of wasted time, I simply modified the pkgsrc python25 makefile to check for the existence of a native sqlite3:
.if !exists(/usr/include/sqlite3.h) .include "../../databases/sqlite3/buildlink3.mk" .endif
Not totally correct (I ignore version checking), but it works for the systems I care about anyway.
There’s a subtle point I should mention here. pkgsrc sets up a special build/link environment for packages based on what other packages the target depends on. For example, if the python25’s pkgsrc makefile includes sqlite3’s buildlink3.mk, then pkgsrc sets up an environment for python25 that contains a series of symlinks in work/.buildlink/lib to the sqlite3 libraries in the pkgsrc installation tree. The compiler and linker generally includes system library paths on its own, so what you’re left with is the possibility to build against pkgsrc’s sqlite3, or the system sqlite3 if it exists. If pkgsrc’s sqlite3 is installed, then that’s the package that takes precedence.
In the case of FreeBSD, the native (ie, ports) version of sqlite3 gets installed into /usr/local, which is not automatically included in the link path. As a result, the build of python25 will not link against any valid version of sqlite3 in the absence of adding pkgsrc’s sqlite3 to its dependency list. What’s worse, there’s no obvious error. The Python build system allows you to enable sqlite3, but doesn’t abort the build if no sqlite3 exists. You’re left with “No _sqlite3.so in /usr/lib/python2.5/lib-dynload” type errors unless you include sqlite3 as a dependency in the python25 package.
Once you understand how pkgsrc works, it seems like it’d be a great tool to eliminate multiple packaging problems. That said, I dream of the day that FreeBSD’s ports system can be made portable enough to eliminate the need for pkgsrc. I know that pkgsrc is a fork of ports, but it’s nowhere near as complete. There’s more value in having a packaging system with lots of packages than one with advanced features (IPS, I’m looking at you). Number of packages goes hand in hand with number of users; number of users goes hand in hand with ease of locating packages. That’s a chicken and egg problem here that’s very hard for an upstart packaging system to solve. I honestly don’t think that MacPorts or DarwinPorts is worth the effort — it’s completely counter productive to build a packaging system that works conceptually like ports or pkgsrc, but isn’t actually ports or pkgsrc.
Anyway, end rant.