Reputation: 13
I have this makefile:
src = $(notdir $(wildcard src/*.cpp))
obj = $(src:.cpp=.o)
libname ?= libtest
importlib_flags = -ldl -lboost_filesystem
parser: $(obj)
g++ -o $@ $^
%.o: src/%.cpp
ifeq ($<,src/$(libname).cpp)
g++ -fpic -c $(libname).cpp -o $(libname).o
g++ -shared -Wl,-soname,$(libname).so.1 -o $(libname).so.1.0.1 $(libname).o -lc
else
g++ -c $< -o $@ $(if $(findstring importlib, $<), $(importlib_flags))
endif
.PHONY: clean
clean:
rm -rf *.o *.so* parser
After I run make, I get this:
g++ -c src/libtest.cpp -o libtest.o
g++ -c src/importlib.cpp -o importlib.o -ldl -lboost_filesystem
g++ -c src/token.cpp -o token.o
g++ -c src/main.cpp -o main.o
g++ -o parser libtest.o importlib.o token.o main.o
First line implies makefile goes to else
branch, but it should go to ifeq
because $< expands to src/libtest.cpp
which is equal to src/$(libname).cpp
after being expanded. I don't set libname
via command line. Why doesn't it work?
Upvotes: 0
Views: 39
Reputation: 16411
IIRC the expansion happens before the rule is actually run, therefore the $<
is probably expanded to empty. I.e. the makefile parses the if/else before it runs the rule.
Then when the rule is run, it has "pre-selected" the else part since when it did the decision $<
was not what it is during the rule.
So what you can do is use shell script (I am assuming bash), somthing like:
%.o: src/%.cpp
if [[ "$<" == "src/$(libname).cpp" ]] ; then \
g++ -fpic -c $(libname).cpp -o $(libname).o ; \
g++ -shared -Wl,-soname,$(libname).so.1 -o $(libname).so.1.0.1 $(libname).o -lc ; \
else \
g++ -c $< -o $@ $(if $(findstring importlib, $<), $(importlib_flags)) ; \
fi
Note bash/shell vars are written like $${shell_var}
and makefile vars are $(make_var)
- just incase you need them!
Also note if you want to specifically use BASH add this to the top of your makefile:
SHELL:=/bin/bash
Upvotes: 1