Installing player/stage on OS X 10.5 Leopard

This tutorial will go through the steps for installing player/stage on OS X. We’ll work through any issues encountered along the way, and verify the stage installation. The tutorial won’t go into verifying the player installation against any hardware.

UPDATE (6/20/10): These instructions don’t work for the latest MacPorts install of player (3.0.0) + OSX 10.6 (Snow Leopard). For example, if you try to run player you get the following:

$ player
Registering driver
Player v.3.0.0
USAGE:  player [options] []

Where [options] can be:
  -h             : print this message.
  -d      : debug message level (0 = none, 1 = default, 9 = all).
      : port where Player will listen. Default: 6665
  -q             : quiet mode: minimizes the console output on startup.
  -l    : log player output to the specified file
     : load the the indicated config file

The following 81 drivers were compiled into Player:

    Segmentation fault

Or if you try to run player with the stage plugin you get this:

$ player cfg/voronoi.cfg
Registering driver
Player v.3.0.0

* Part of the Player/Stage/Gazebo Project [].
* Copyright (C) 2000 - 2009 Brian Gerkey, Richard Vaughan, Andrew Howard,
* Nate Koenig, and contributors. Released under the GNU General Public License.
* Player comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
* are welcome to redistribute it under certain conditions; see COPYING
* for details.

loading plugin stageplugin
error   : Failed to load plugin stageplugin.
error   : libtool reports error: file not found
error   : plugin search path: /Users/jaustin/work/player-bots/voronoibot:cfg:/opt/local/lib/
error   : failed to load plugin: stageplugin
error   : failed to parse config file cfg/voronoi.cfg driver blocks

There are a couple of related issues posted for the playerstage-player MacPorts port (22642, 23179, 26048, 26329), and my suspicion is that it has to do with compiling with x86_64 architecture in OS X 10.6. It seems like one can try to build the macports using different options to get around the architecture issue, or try building player from source. I’ll post an update if I figure it out.

Step one: Install MacPorts (aka DarwinPorts)

This installation requires
After you’ve installed from the disk image, update ports to the latest version
$ sudo port selfupdate

Step two: Install player/stage

If you don’t have cmake, get it now, else the install will fail:
$ cmake
-bash: cmake: command not found
$ sudo port install cmake
Then install stage (playerstage-stage has a dependency on playerstage-player, so player will be installed as well):
$ sudo port install playerstage-stage
Note: On Snow Leopard, this install took forever for me. I did have some internet issues in the middle of the install, but it still took most of the day to build. So I would recommend being patient here.
By default, the installer will use /opt/local as the install prefix, giving you the following setup:
/opt/local/bin (executables, including the 'stage' program)
/opt/local/lib (libraries, including libstage)
/opt/local/share/player (contains data resources, such as images)
/opt/local/share/stage (contains data resources, such as images)
Since /opt/local/bin should already be on your path, you shouldn’t have to do any extra setup to access the executable.

Step three: Verify installation (OS X 10.5)

At this point, you want to try running stage against an example world. However it seems that the DarwinPorts installation doesn’t install any worlds under /opt/local/share/stage. So you can go to the player/stage SourceForge site and download the latest stage source archive.
Extract the archive and copy the worlds directory to /opt/local/share/stage.
Now, cd into the stage directory and run the test:
$ cd /opt/local/share/stage
$ stage worlds/
dyld: Library not loaded: libstage.3.2.2.dylib
Referenced from: /opt/local/bin/stage
Reason: image not found
Trace/BPT trap
Looks like the stage libraries are not on our path, so let’s add them (note that you should also add this to your ~/.profile):
$ export DYLD_LIBRARY_PATH=/opt/local/lib
And try again:
$ stage worlds/
stage dyld: Symbol not found: __cg_jpeg_resync_to_restart
Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/ImageIO
Expected in: /opt/local/lib/libjpeg.7.dylib
Trace/BPT trap
We still have issues. It looks like the version of libjpeg.dylib on our library path is a different version from what ImageIO is expecting. Maybe there was a transitive dependency in the DarwinPorts install that’s screwed us over, who knows. Anyway, if we point to OS X’s version of libjpeg, maybe we’ll eliminate this issue.
$ cd /opt/local/lib
$ sudo rm libjpeg.dylib
$ sudo ln -s /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Resources/libJPEG.dylib libjpeg.dylib
$ cd /opt/local/share/stage
$ stage worlds/
dyld: Symbol not found: __cg_TIFFClientOpen
Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/ImageIO
Expected in: /opt/local/lib/libTIFF.dylib
Looks like a similar issue, so we’ll try the same trick again (and yet again for libpng):
$ sudo rm libtiff.dylib
$ sudo ln -s /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Resources/libTIFF.dylib libtiff.dylib
$ sudo rm libpng.dylib
$ sudo ln -s /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Resources/libPng.dylib libpng.dylib
$ cd /opt/local/share/stage

$ stage worlds/
Stage 3.2.2
[Loading worlds/][Include][Include][Include]
Try holding the ctrl key and moving your mouse cursor around to change the view. You can also press “p” to unpause the simulation.
Now let’s test to see that plugins are working:
$ stage worlds/
Stage 3.2.2
[Loading worlds/][Include][Include][Include]warn:
multi-thread support is experimental and may not work properly, if at all. (/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_science_playerstage-stage/work/Stage-3.2.2-Source/libstage/ Load) [threads 2]
A window should pop up. Press “p” and watch the robots move around.
This verifies that the stage plugins are working.

Verify Installation (OS X 10.6)

With 10.6, I had a much easier time installing for some reason (perhaps because I used MacPorts instead of DarwinPorts?). The only issue I found was that the STAGEPATH variable was not set, so I set that and was good to go.
$ stage worlds/
Stage 3.2.2
 [Loading worlds/][Include][Include][Include]Libtool error: file not found. Can't open your plugin controller. Quitting
err: Failed to open "wander". Check that it can be found by searching the directories in your STAGEPATH environment variable, or the current directory if STAGEPATH is not set.]
 (/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_science_playerstage-stage/work/Stage-3.2.2-Source/libstage/ LoadControllerModule)
libtool error #2
$ export STAGEPATH=/opt/local/lib
$ stage worlds/
Stage 3.2.2
 [Loading worlds/][Include][Include][Include]

Unfortunately, while the stage plugin seems to work, the player port is broken on OS X 10.6 (see the top of this post).

Tutorial: Moving from Subversion (svn) to Perforce (p4)

I suppose most tutorials out there go the other direction, from Perforce to Subversion. Yet I ended up in a situation recently where needed to work on a codebase that was being managed with Perforce. Coming from a Subversion-heavy background, I found myself initially puzzled and frustrated by a lot of conventions in Perforce–especially when it came to using the command line client, p4. So after gaining some familiarity with p4, I decided to write up some notes for anyone else who might be in my situation.


The main thing to keep in mind when moving from svn to p4 is this:
Subversion works off of the file system via .svn folders. This is perhaps slower for large checkouts, but it also means that you don’t have to tell svn every little change you want to make. Using svn st, you can easily get a diff between the repository version and your current checkout.
Perforce, on the other hand, works off a relational database. This allows it to be much faster when doing checkouts, checkins, etc. However, it also means that you have to tell your Perforce client every little thing you want to do. Want to edit a file? Whoa, not so fast–you have to tell Perforce that you’re editing it! Added a file locally and forgot to add it to the changelist? Too bad, p4 won’t (easily) help you out there! These differences means you’re going to have to change your workflow when working on “checked out” code. See the “Best Practices” section below.
Other things to keep in mind:
  • Unlike Subversion, Perforce does not keep folders in version control–only files. This means you’ll see a lot of placeholder.txt in your depot tree.
  • In Subversion, you “check out” a local copy of the code from a given root (for example, svn co In Perforce, you must create a workspace and configure a view, which will tell the Perforce client what code you want to check out. In subversion you could have many different roots checked out in different places on your file system, and be able to move between them seamlessly. In Perforce you can only use one workspace (aka client) at a time. See svn co below for more information.
  • In Subversion, you need to be inside your working copy if you want to run svn commands. In Perforce, since you are only working with one workspace/client at a time, you can run p4 commands from anywhere in the filesystem.

Equivalent Commands

svn st

Frustratingly, there is no direct equivalent of svn st in p4. You can get all of information that svn st would give you, but you have to run multiple commands.
The first thing you should look at is p4 opened. This gives you a list of all files that have been modified (with p4 edit), plus files that have been added (p4 add) or deleted (p4 delete).

In Subversion, if there are files you have added or deleted locally, and these files are not in version control, then when you run svn st they will show up marked with a “?”. With p4, there is no easy way to get a list of these sorts of files. You really have to become diligent with your workflow, and never forget to add files after creating them.
In Subversion, if there are files in the repository but you have deleted them locally without telling subversion, it will come up in svn st marked with a “!”. To get this list of files in p4, use p4 diff -sd. Similarly, if you have modified files locally and haven’t told p4 by running p4 edit on the file, you can see the list using p4 diff -se.

In Subversion, if you have made local edits to files and these changes conflict with the latest from the repo, they will come up marked with “C”. To list these files in p4, use p4 resolve -n.

To summarize:

A — p4 opened
M — p4 opened
D — p4 opened
C — p4 resolve -n
! — p4 diff -se / p4 diff -sd / p4 diff -sb
? — (no equivalent)

svn diff

This one is pretty straightforward. p4 diff will give you diffs on all files currently open for edit, so it is very similar to svn diff in that sense. One key difference: p4 diff will NOT tell you files that have been added or deleted, either locally or in a changelist.

svn update

Use p4 sync. You can also specify which files you want to sync. For example, if you want to sync recursively from your current folder on down, you can execute: p4 sync ./…

If p4 sync isn’t behaving how you expect, or you’ve somehow screwed up your workspace, you can try p4 sync -f. The ‘-f‘ parameter “forces” the sync. While this command can be very useful, you really need to understand what you’re doing when you use it, because it’s possible you could blow away your changes.

So here’s what’s going on: When you run p4 sync the first time, Perforce remembers what you have synced and assumes the files are still there in the same state in your local copy. So if, say, you accidentally deleted a file and you try running p4 sync again, p4 will do nothing. If you force the sync, your Perforce client will “refresh”–that is, re-download–all of your files from the depot. For every file that it finds, if you’re not currently editing the file, it will overwrite that file. This means that, depending on your settings, running a force sync may clobber writable files. In other words, if you have been editing a file manually, without running p4 edit beforehand, your changes will be blown away.

svn commit

Use p4 submit.

svn checkout

To get a revision of the code, you must setup a workspace (aka client) and define one or more views for that workspace.
First, make sure the P4PORT environment variable is set (Confusingly enough, this variable is actually the full url plus port of the perforce server). E.g.,
export P4PORT=""

Then, setup your client by running p4 client. This will open up a text editor with a bunch of defaults. It might look something like this

# A Perforce Client Specification.
## Client: The client name.
# Update: The date this specification was last modified.
# Access: The date this client was last used in any way.
# Owner: The user who created this client.
# Host: If set, restricts access to the named host.
# Description: A short description of the client (optional).
# Root: The base directory of the client workspace.
# AltRoots: Up to two alternate client workspace roots.# Options: Client options:
# [no]allwrite [no]clobber [no]compress
# [un]locked [no]modtime [no]rmdir
# SubmitOptions:
# submitunchanged/submitunchanged+reopen
# revertunchanged/revertunchanged+reopen
# leaveunchanged/leaveunchanged+reopen
# LineEnd: Text file line endings on client: local/unix/mac/win/share.
# View: Lines to map depot files into the client workspace.
## Use 'p4 help client' to see more about client views and options.

Client: jaustin-laptop

Owner: vaustje

Host: jaustin-laptop

Description:Created by jaustin.

Root: /home/jaustin/work/jaustin

Options: noallwrite noclobber nocompress unlocked nomodtime normdir

SubmitOptions: submitunchanged

LineEnd: local

View://depot_root/... //jaustin-laptop/depot_root/...
The main thing you care about are “Client:“, “Root:” and “View:“. Client will default to your hostname, and you can change it to whatever you want. It must be unique, so if you’ve already created a workspace with the name my_awesome_workspace, you can’t create it again. Root is where the code will be downloaded to, and defaults to your current directory. View lists the mapping between the code in the depot and your local checkout. It’s kind of like running svn co to get everything, versus running svn co to get a specific part of the repository.
After you’ve configured that file how you want, save and close it. p4 should then say something like

Client jaustin-laptop saved.

To use your workspace, you must set the P4CLIENT variable:
export P4CLIENT="jaustin-laptop"

Finally, you can run p4 sync to download the latest revisions of files in your view.

If you use a client often, I recommend adding the P4PORT and P4CLIENT variables to some file that is always sourced, for example .bashrc or .bash_profile. That way you don’t have to worry about setting them for every session.

svn info

Use p4 info.

svn log

Use p4 filelog.

svn add

Use p4 add.

svn copy

As far as I can tell this doesn’t exist? Please correct me if I’m wrong.

svn delete

Use p4 delete. Keep in mind that you can’t delete a file if it is open for edit.

svn move

Newer versions of the p4 client (2009.1 onwards) have a move command, so you can move a file by running p4 edit followed by p4 move against a file.
If you have an older version of p4, you need to run p4 integrate followed by p4 delete on the original file. Like so:
p4 integrate //depot/foo/bar.c //depot/foo/baz.c
p4 delete //depot/foo/bar.c
p4 submit

svn revert

Use p4 revert.

Best Practices

DON’T get around Perforce by manually edit file permissions

This will only cause you pain and headaches. If you can’t understand why you can’t get the file open for edit, it’s better to figure out that issue early on, because if you manually edit files, by the time you want to submit you’ll be completely lost.
DO get in the practice of telling p4 everything you want to do
I’ve seen the following scenario happen a lot of times: Developer opens up a file that’s under a Perforce workspace and makes some edits. When they go to save, the editor tells them that the file is read-only and prompts them to override and save anyway. The dev says, “Oh, I just want to make a temporary change that I plan to revert… I’ll just save the file and not worry about running p4 edit.” Afterwards, they completely forget that they made the edit. This means that a few weeks down the road, their edit will be either completely forgotten when submitting code back to the depot, or it will be blown away when they run a p4 sync -f. Please, even for quick edits that you plan to revert immediately, just tell p4 what you are doing. It will save you a lot of headaches in the future.

Use a GUI tool or IDE plugin if possible

Unlike svn, it seems that p4 is not intended to be the ultimate solution for developers working in Perforce. Frankly, it’s limited and difficult to use for anything more than the simple add, edit, and revert commands. There are tools built upon it, however, that will give you that functionality that is missing and remove some of the frustrations of developing using p4. P4V is a common GUI tool, and I always use it when doing something tricky like a branch integration. If you’re using an IDE for development, I definitely recommend getting a plugin. p4wsad is a decent plugin for Eclipse, and JetBrains products, like Intellij IDEA and RubyMine, come with built-in Perforce integration that works pretty well.
Run p4 sync twice (followed by p4 resolve -n)
Most of the time, when you run p4 sync, a lot of information will go flying by on the screen. In all that, there might be some useful messages that you missed. One of these messages is “Can’t clobber writable file.” This occurs when you’ve made a read-only file writable. Perforce doesn’t want to clobber this file, so it will skip over it when running a sync. This is a very important message, because it means that your workspace isn’t actually up-to-date! My solution to this is to always run p4 sync twice–the first time to pull down the latest revisions, and the second time to makes sure I see the message File(s) up-to-date.

Another thing I like to run after a sync is p4 resolve -n. This command will tell me what files I have locally opened for edit that conflict with the latest in the depot. While Perforce will force me to resolve these conflicts before submitting, I like to know about issues BEFORE running the submit, and the messages telling me about conflicts are also often lost in the huge list of changes when I run p4 sync.

Tips and Tricks

Checking out your entire client workspace

Since Perforce wants you to tell it every time you edit a file or add something new, it will actuallychange the file permissions when you get code from the depot. If you have a file that has not been checked out with p4 edit, it will be in read-only mode. Of course this means that you will often land in the frustrating position of opening a file, editing it, and then not being able to save it when you’re done. While I don’t recommend it except for in special cases, sometimes checking out your entire workspace is a good option. For one thing, it will make a p4 diff pretty pointless, and reverting unchanged files afterwards is dangerous, but at least you don’t have to worry about file permissions as you go about your business.

You can do a recursive checkout with the following command (‘…’ acts as a recursive wildcard):
p4 edit //workspace_name/...

When you’re ready to submit and want to get rid of all the unchanged files that show up when you run p4 diff, you can run this to revert all unchanged files:
p4 revert -a //workspace_name/...

This is somewhat dangerous since if you forget the ‘-a‘ you risk reverting your local changes! If you find yourself doing this a lot, I recommend making an alias for p4 revert -a that will save you from a mistake.

Marking a file as always executable

If you have scripts checked into Perforce, and want to set the execute flag, run the following against the file:

p4 edit -t text+x FILE_NAME

For example:

[hosting@somebox tmp]$ ls -l
total 1-r--r--r-- 1
hosting hosting 1407 Mar 17 09:38
[hosting@somebox tmp]$ p4 edit -t text+x
[hosting@somebox tmp]$ ls -l
total 1-rwxrwxr-x 1
hosting hosting 1407 Mar 17 09:38
[hosting@somebox tmp]$ p4 submit