I am starting a project which has several applications. These applications share some common functionality in terms of source files. Each application should have its own make file but be able to link in these shared source files from a common location.
To illustrate this, here’s my directory layout:
project/
lib/
shared1/
shared1.c
shared1.h
shared2/
shared2.c
shared2.h
app1/
app1.c
app1.h
makefile
app2/
app2.c
app2.h
makefile
Currently one of the makefiles looks a bit like this:
CC=gcc
XXXCFLAGS=-Wall -Wextra -pedantic -I../../lib/shared1
CFLAGS=-I. $(XXXCFLAGS)
DEPS = app2.h ../../lib/shared1/shared1.h
OBJ = ${DEPS:.h=.o}
LIBS=-lpthread
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
app2: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
-
Is this roughly the right way to go about managing shared source, or is there a better way. Should they be separately compiled libraries? If so, how?
-
Are relative paths like this ok?
-
Should I be using autotools for something like this? After looking at examples I couldn’t see how to link shared code or a library.
Any guidance is most appreciated.
This is a reasonable way to lay out your source tree, although you might consider separating source files and header files. If you want to build a library (if many apps use, say,
shared1) you can write a rule for it, and put the rule in a makefile inshared1/. There are several ways to use such a rule, but don’t worry about that until you’re sure you want a library.Paths are a necessary evil. They lock the makefile to a particular directory layout, but you can’t entirely do without them. What you can do is keep them corralled:
Your use of dependencies is a little peculiar. For one thing, it’s better to derive the list of objects from the list of sources, since you might have a source without a header or a header without a source:
Second, you make every object file depend on all headers, which is probably overkill. Suppose we can assume
foo.owill depend onfoo.h, and also thatapp2.odepends onshared1.h; then we can write a much better rule:If you have a lot of objects and this approach is too cumbersome, there is a very sophisticated method of handling these lists automatically, but it’s an advanced technique you’d probably better not try just yet.
Finally, if you find that all of your app makefiles look much alike, you can take all of the common stuff and put it in a makefile in
project/Then the app makefiles can look like this: