为什么makefile不能正常运行?

时间:2019-10-01 05:23:14

标签: 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

运行make之后,我得到了:

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

第一行表示makefile转到else分支,但它应该转到ifeq,因为$ <扩展为src/libtest.cpp,它在扩展后等于src/$(libname).cpp。我没有通过命令行设置libname。为什么不起作用?

1 个答案:

答案 0 :(得分:0)

IIRC扩展发生在规则实际运行之前,因此$<可能会扩展为空。即makefile在运行规则之前先分析if / else。

然后,当规则运行时,它已经“预选”了else部分,因为它做出的决定$<并不是规则期间的内容。

所以您可以做的是使用shell脚本(我假设是bash),诸如此类:

%.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

注意:bash / shell var的写法类似于$${shell_var},makefile var的写法是$(make_var)-以防万一您需要它们!

还请注意,如果要专门使用BASH,请将其添加到makefile的顶部:

SHELL:=/bin/bash