Reputation: 75
I have a base directory src, and two subdirectories src/foo and src/tests. In src/tests I have a Makefile that builds src/tests/tests.cpp. I want this to depend on src/foo/*.o, which I am compiling with
%.o : %.cpp
${GCC} -c ${CXXFLAGS} $< -o $@
in src/foo/Makefile. Is there a good way to structure my Makefiles by including one in another or something?
In other words, src/foo/Makefile looks like:
OBJECT_FILES += bar.o baz.o ...
main: main.o ${OBJECT_FILES}
${GCC} ${CXXFLAGS} main.o ${OBJECT_FILES} -o main
%.o : %.cpp
${GCC} -c ${CXXFLAGS} $< -o $@
and I want src/tests/Makefile to do something like:
# Obviously this is impossible right now since OBJECT_FILES is not defined in this Makefile.
tests: tests.o ${OBJECT_FILES}
${GCC} ${CXXFLAGS} tests.o ${OBJECT_FILES} -o tests
tests.o: tests.cpp
...
Upvotes: 0
Views: 69
Reputation: 206697
Assuming you are using GNU make, you can use a phony target.
.PHONY: foo_objets
foo_objects:
$(MAKE) -C ../../src/foo
and define foo_objects
as a dependency of test
.
tests: tests.o ${OBJECT_FILES} foo_objects
${GCC} ${CXXFLAGS} tests.o ${OBJECT_FILES} -o tests
Upvotes: 0
Reputation: 8583
Combining two self contained make files for a single project is difficult, and, in fact, not recommended. Please read Recursive Make Considered Harmful for fuller explanation as to why. Please note, this applies only to calling make recursively, and only when the different parts of the project have inter-dependencies.
The problem is that when you forgo the recursive option, the other options are not great. The most obvious would be to include
your src
makefile from your tests
directory. This won't work, however, as that src
makefile makes implicit assumptions about current directory that do not hold true when you are in the tests
directory.
Your best options is to create one make file in the root of the project, that builds both src
and tests
. This would make the dependency specification trivial.
While at it, it seems to me that your project needs are as standard as they can get. Even your pattern rule for compiling is just a simplified version of the pattern rule built into make
(i.e. - you could drop it from your make file, and everything will continue to work). When such is the case, trying to reinvent the wheel seems unnecessary to me.
I recommend using one of the standard build generating tools. automake
is my favorite, because it is universally available and requires no special tools on the compiling machines. Its learning curve is slightly steeper to climb than others, especially for simple projects, but the tools you gain while learning it are also useful for projects not using it.
Then again, for the above stated reasons, some hate the auto tools with a vengeance. To each his own.
Upvotes: 1