M. Kalter
M. Kalter

Reputation: 13

Why doesn't makefile function properly?

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

Answers (1)

code_fodder
code_fodder

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

Related Questions