The lowest-budget solution is simply to store the third party and open source projects in a reliable network file share (NFS, samba, etc). Then you can either sync locally or just build/link directly against the mounted file share.
It's also important to keep each project in a directory structure that includes the version number in the path (e.g. /nih_libs/boost/1.44.1/...) so that you can easily drop in a new version and start using as needed on a project by project basis. I'm always amazed how many places neglect this step and then have nothing but pain when they want to upgrade to a new version of a lib.
Can you elaborate a bit more on this?
I've also seen really simple projects get by with just an "install_deps" task in the Makefile, which you run first thing on a new clone. ("The simplicity of Maven meets the dependency management of Make," the wags will say.)
However, yes, checking in dependencies with your code is the way to go.
Deps that can be reliably included with just a meta-descriptor (i.e. Gemfile, pom.xml, etc.) are still exceptionally rare. Thus the natural choice is to put the rest right next to the code that it belongs to. Well, natural choice unless you're stuck in a 90s java mindset...
That said the Maven dependency model isn't too bad; fortunately you don't have to adopt Maven to get it, you can just use Ivy.
Perfect? No. But standard practice? Yes.
Since the histories of the dependencies don't get tracked, merging them can be tricky. Especially when dependencies get upgraded separately by multiple people.
I agree with this statement, but that home is definitely not with your code. There are tools better suited for that. For instance nexus & maven.
Nexus store artifacts (which are really any piece of data: a jar, a tar.gz, a zip file). That's where you put your dependencies. Maven manage a project's build, that's where you tell what are your dependencies.
But really, there are many other tools out there to handle that (ant, nant, pypi, etc.).