Reputation: 153
I have a makefile in my src directory. The makefile should build the data structures, which are in DataStructures/, and then iterate over all cpp files in calculations/ and create a corresponding .so file in ../bin/calculations
I tried the following syntax:
DAST = DataStructures/
COMPS = computations/
BIN = ../bin/
OBJECTS = ${DAST}Atom.o ${DAST}Molecule.o
COMPILE = g++ -Wall -g -c -std=c++0x -I/usr/local/include/openbabel-2.0 LINK = g++ -Wall -g -std=c++0x ${OBJECTS} -lopenbabel -I/usr/local/include/openbabel-2.0
all: ${BIN}main ${DAST}Molecule.o ${DAST}Atom.o ${BIN}${COMPS}%.so
${BIN}main: ${OBJECTS} main.cpp
${LINK} main.cpp -o ${BIN}main
${DAST}Molecule.o: ${DAST}Molecule.h ${DAST}Molecule.cpp
${COMPILE} ${DAST}Molecule.cpp -o ${DAST}Molecule.o
${DAST}Atom.o: ${DAST}Atom.h ${DAST}Atom.cpp
${COMPILE} ${DAST}Atom.cpp -o ${DAST}Atom.o
${BIN}${COMPS}%.o: ${COMPS}%.cpp
gcc -Wall -fPIC -c -lopenbabel $< -I/usr/local/include/openbabel-2.0 -std=c++0x
${BIN}${COMPS}%.so: ${COMPS}%.o
gcc -shared -Wl,-soname,libcsmtest.so.1 -o libcsmtest.so $@
clean:
rm -rf ${OBJECTS}
.PHONY: all clean
But it obviously doesn't work, as I get the following output:
shai@ubuntu:~/csm/csm2/src$ make all
make: *** No rule to make target `../bin/computations/%.so', needed by 'all'. Stop.
thanks
Upvotes: 0
Views: 1420
Reputation: 16338
You need to specify in the all:
target, the prerequisites explicitly.
In Makefile parlance, % is a wildcard that can be used in automatic rules. However, the all:
target is a simple target with no such wildcard, thus ${BIN}${COMPS}%.so
is wrong in that context.
Please note that when I say 'wildcard' in this context, this wildcard matches the target against the prerequisites, not against the filesystem like *
do in glob expressions.
Also, while your hart is in the right place, as a matter of style, your Makefile can be better:
all
target, but only the final targets you wish to ship. %.so
, because a library is often constructed from more than one object.*.cpp
(or .c
) as well as all the headers included (directly and indirectly) by the *.cpp
file.${COMPILE}
as you do, one should use $(CXX)
for your C++ compiler, and $(CXXFLAGS)
for the standard flags you wish to pass to that compiler.Upvotes: 2
Reputation: 6649
You need something like
SOBJECTS = ... all: ${BIN}main ${SOBJECTS} ...
You need a way to gather all the *.so names in the variable SOBJECTS
. You can do this manually, or use some of make
's internal functions to scan the source directory.
Also notice that I removed the two *.o
files as dependencies from the all
target. They are not final goals of the build (I assume), so you don't need to mention them there.
Besides this there are other stylistic points which I would do differently, but at the moment they are not causing immediate problems, so I won't digress, but I advise you to have a look at some tutorials to see how things are done generally.
For starters, look at Paul's Rules of Makefiles, and How Not to Use VPATH.
Upvotes: 1