Почему makefile не работает должным образом? - PullRequest
0 голосов
/ 01 октября 2019

У меня есть этот make-файл:

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

Первая строка подразумевает, что make-файл идет в ветку else, но он должен идтидо ifeq, потому что $ <расширяется до <code>src/libtest.cpp, что равно src/$(libname).cpp после расширения. Я не устанавливаю libname через командную строку. Почему это не работает?

1 Ответ

0 голосов
/ 01 октября 2019

IIRC расширение происходит до фактического выполнения правила, поэтому $<, вероятно, расширен до пустого. Т.е. make-файл анализирует if / else перед запуском правила.

Затем, когда правило запускается, оно «предварительно выбрало» остальную часть, поскольку при принятии решения $< не было тем, что есть во время правила.

То, что выможно использовать сценарий оболочки (я предполагаю, что 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 записываются как $${shell_var}, а переменные make-файла $(make_var) -только если они вам нужны!

Также обратите внимание, что если вы хотите специально использовать BASH, добавьте это в начало вашего make-файла:

SHELL:=/bin/bash
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...