Personally I've started isolating all code that isn't dependent on application specific classes/structs (like CHAR_DATA, OBJ_DATA, etc), put them in a separate directory, compile as a static or shared library and link it in with the mud code. For example I've put functions like capitalize, str_cmp, str_prefix, etc in a directory called <main dir>/src/lib/utils/ along with the following Makefile:
PREFIX = ../../..
OBJS = utils.o
CXX = g++
CXXFLAGS = -Wall -O2 -MD -ansi
LIBNAME = libmudutils.a
ar cru $@ $(OBJS)
@rm -f *.a *.d *~ core* $(OBJS)
cp $(LIBNAME) $(PREFIX)/lib
cp *.hpp $(PREFIX)/include
So I type 'make install' which will compile a static library called mudutils.a and copy it, along with the header file(s) into <main dir>/lib/ and <main dir>/include/ respectively. In the main Makefile I then link in -lmudutils and make sure the linker finds the library by adding -I../include (that's a capital i, not a lowercase L) and -L../lib to compiling and linking stage as appropriate.
I think this approach has some advantages. 1) You don't have to recompile the library unless you do changes to it. 2) You don't get tempted as easily to play around with (recode just "because"
basic functions that works well as they are. 3) It encourages you to write code that isn't dependant on other classes/structs, and can therefore be used in other projects as well.
Changing the Makefile to create a shared library instead isn't too hard either, if you prefer that (ie, you won't need to recompile the mud after changing the library).