Running Perforce on FreeBSD 10

Yesterday I updated our company server to FreeBSD 10. It went pretty well with only a few glitches: had to remove libiconv (documented in UPDATING) and some of the ports (such as Perl 5.16) needed manual recompilation as portupgrade failed on them.

But I quickly discovered that Perforce does not work – attempting to start the server produces the error message:

Shared object "libstdc++.so.6" not found, required by "p4d"

The reason is that FreeBSD 10 includes a new C++ stack and gcc, including libstdc++, is not installed by default.

So the problem is easy to fix: install lang/gcc from ports. This will bring back libstdc++ and Perforce will run smoothly again.

Update 4/23/2014: Perforce version 2014.1 has a FreeBSD 10 specific build, which does not depend on libstdc++.

Forcing Xcode to Use Downloaded DocSets

Since Xcode is available from the App Store, developer documentation is a separate download. As is command line tools. When you first start Xcode it starts to download them. But during the latest AirPort Extreme firmware fiasco I realized something shocking: Xcode does not use the downloaded docsets at all! You can try it for yourself: disconnect your Mac from the net and try to access any of the docs.

This is a huge problem if you want to do some work in a network-less location (on a plane for example).

Why?

The Xcode app installs a stubs for the docsets, so that you can begin to use them right off the bat. These stubs contain just the table of contents and get the actual pages off the web. The problem is that even after downloading the (almost) full docsets, Xcode still uses these stubs. I said almost, because even the full docsets have some parts missing: such as OS X man pages (which is not a big deal, just use man for those).

You can check the currently used docset locations on the Xcode Preferences pane: go into Downloads | Documentation, click on a docset name, and click on the triangle on the left below the docset list. This will bring up some information about the given docset. Scroll down to check “Installed Location”: if it shows that the docset resides inside Xcode, then you have this problem.

The Fix

Fixing this is easy:

  • Quit Xcode.
  • Find and remove all docset bundles from your Mac. You’ll find them in /Applications/Xcode.app/Contents/Developer/Documentation/DocSets (these are the stubs) and ~/Library/Developer/Shared/Documentation/DocSets (these are the downloaded-but-not-used ones).
  • Start Xcode and open the Preferences pane. Under Downloads | Documentation tab you can download the docsets you plan to use. Now if you check the “Installed Location” it should show that the docsets in use are the downloaded ones from your home folder.

Of course you’ll have run these circles after each Xcode update – until Apple fixes the problem.

Integrating Perforce with Xcode 4

I prefer to work with first rate tools. You might call it snobbery, but I’m just too old for spending my precious time on fiddling with inferior products. That’s why I’m using Mac OS X and even more the reason I chose Perforce as our source control system. It simply blows the competition away.

When Apple introduced Xcode 4, I had realized with horror that they removed Perforce support. This was simply unacceptable for me. I would give up on Xcode much easier than giving up one of the cornerstones of our business. So I waited patiently, filed bug reports with Apple, until the buggy-to-the-level-of-unusability Xcode 4 was released. I decided to stick with Xcode 3 for the foreseeable future (until of course Apple dropped the tools and I had to migrate).

I did not want much from the Xcode side – just let me check out the files when I start working on them. I usually handle all the other stuff (like diffing, code review, etc) from P4V. Then while walking through all the Xcode 4 options and menu items (to familiarize myself with the inevitable new tool) I found something on the Behaviors preference pane.

You can execute a shell script every time Xcode unlocks a file. Fortunately Perforce locks all the files that are under source control and not in the checked out state – so you can be sure that all your files will be locked when not checked out. This fits perfectly with the Unlock file behavior. When you start working on a file Xcode wants to unlock it and executes your script. The script could then check out the given file from Perforce. The checkout will unlock the file, so everybody will be happy.

My xcode4edit.sh script is pretty straightforward:

#!/bin/sh
`cat ~/.profile | grep P4PORT`
`cat ~/.profile | grep P4CHARSET`
`cat ~/.profile | grep P4USER`
`cat ~/.profile | grep P4CLIENTPATH`
/usr/local/bin/p4 edit ${1#file://localhost}

This is checked in into the root of the depot so every team member have access to it. My .profile (as well as other members of the group) contains the actual configuration parameters:

export P4PORT=<server>:1666
export P4USER=<user>
export P4CHARSET=utf8
export P4CLIENTPATH=/Volumes/Data/Workspace

Of course you can add additional configuration variables to the script and into .profile if you want.

Output from the p4 edit command will go into the Console, so you can use that for debugging any problems you face.