views:

383

answers:

4

The other day I set up an unbuntu installation in a VM and went to gather the tools and libraries I figured I would need for programming moslty in C++.

I had a problem though, where to put things such as 3rd party source libraries, etc. From what I can gather, a lot of source distributions assume that a lot of their dependencies are already installed in a certain location and assume that a lot of tools are also installed in particular locations.

To give an example of what I currently do on windows, is I have a directory where I keep all source code. C:\code. In this directory, I have a directory for all 3rd party libraries, c:\code\thirdparty\libs. This way I can easily set up relative paths for all of the dependencies of any projects I write or come across and wish to compile. The reason I am interested in setting up a linux programming environment is that it seems that both the tool and library dependaecy problems have been solved efficiently making it easy for example to build OpenSSH from source.

So what I was looking for was a decent convetion I can use when I am trying to ogranize my projects and libraries on linux that is easy to maintain and easy to use.

+4  A: 

For libraries/includes...

/usr/local/lib
/usr/local/include
Paul Nathan
+1  A: 

Ubuntu = Debian = apt-get goodness

Start with Linux Utilities:

%> sudo apt-get install util-linux
jakemcgraw
+6  A: 

Short answer: don't do a "heaps of code in local dir" thing.

Long answer: don't do a "heaps of code in local dir" thing, because it will be nightmare to keep up-to-date, and if you decide to distribute your code, it will be nightmare to package it for any decent distribution.

Whenever possible, stick to the libraries shipped in the distribution (ubuntu has 20000+ packets, it ought to have most of what you'll need prepackaged). When there is not package, you caninstall by hand to /usr/local (but see above about upgrades and DONT do that).

Better, use "stow" or "installwatch" (or both) to install to per-library dirs (/usr/local/stow/libA-ver123) and then symlink files from there to /usr/local or /usr/ (stow does the simlinking part). Or just package the lib for your distribution.

ADEpt
+3  A: 

Where possible code against the system/distro provided libraries. This makes it easiest to ship a product on that distro.

However, if you are building a commercial application, because there are so many flavors of Linux distros that can mean you have to maintain a plethora of different application builds for each distro. Which isn't necessarily a bad thing as it means you can more cleanly integrate with the distro's package management system.

But in the case where you can't do that it should be fairly easy to download the source of each 3rd party dependency you have and integrate the building of that dependency into a static lib that is linked to your executable. That way you know exactly what you're linking against but has the downside of bloating out your executable size. This can also be required if you need a specific library (or version) not provided by the distro.

If you want your code to build on as broad a variety of different Unix systems then you're probably wise looking into GNU autoconf and automake. These help you construct a configure script and makefile for your project so that it will build on practically any Unix system.

Also look into pkg-config which is used quite a bit now on Linux distributions for helping you include and link to the right libraries (for libs that support pkg-config).

If you're using subversion to manage your source there is a "convention" that most subversion repositories use to manage their own code and "vendor" code.

Most svn repositories have a "vendor" tree (that goes along with the trunk, branches & tags trees). That is the top for all 3rd party vendor code. In that directory you have directories for each library you use. Eg:

branches/
tags/
trunk/
vendor/somelib
vendor/anotherlib

Beneath each of these libs is a directory for each library version and a "current" directory for the most up-to-date version in your repository.

vendor/somelib/1.0
vendor/somelib/1.1
vendor/somelib/current

Then your project's tree should be laid out something like this:

trunk/source # all your code in here trunk/libs # all vendor code in here

The libs directory should be empty but it will have svn:externals meta data associated with it, via:

svn propedit svn:externals trunk/libs

The contents of this property would be something along the lines of (assumes subversion 1.5):

^/vendor/somelib/current   somelib
^/vendor/anotherlib/1.0    anotherlib

This means that when you checkout your code subversion also checks out your vendor libraries into your trunk/libs directory. So that when checked out it looks like this:

trunk/source
trunk/libs/somelib
trunk/libs/anotherlib

This is described (probably a whole lot better) in the Subversion Book. Particularly the section on handling vendor branches and externals.

orj