Идентичная номенклатура Makefile для использования переменных в разных командах сборки с разными результатами

Есть три программы, созданные этим Makefile. Они следуют одному и тому же шаблону, но при запуске выдают разные команды сборки. В частности, мне нужна компиляция с c++11 но может достичь этого только с помощью одной из команд сборки. Почему это?

Makefile:

CXX=g++
RM=rm -f
CFLAGS=-std=c++11 -g -Wall $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
SOURCES=generic_queue.cpp map_compare.cpp vector_search.cpp
OBJS=$(SOURCES:.cpp=.o)

all: $(SOURCES) generic_queue_test list_of_lists map_compare_test vector_search_test

# Note that $(CFLAGS) is used in the $(CXX) ... command
# each time that a .o file is built.

vector_search_test: $(OBJS) vector_search_test.o
    $(CXX) $(LDFLAGS) -o vector_search_test vector_search_test.o $(LDLIBS)

vector_search_test.o: vector_search.cpp vector_search.h
    $(CXX) $(CFLAGS) -c vector_search.cpp -o vector_search_test.o

generic_queue_test: $(OBJS) generic_queue_test.o
    $(CXX) $(LDFLAGS) -o generic_queue_test generic_queue_test.o $(LDLIBS)

generic_queue_test.o: generic_queue.cpp generic_queue.h fixed_priority_queue.h
    $(CXX) $(CFLAGS) -c generic_queue.cpp -o generic_queue_test.o

list_of_lists: $(OBJS) list_of_lists.o
    $(CXX) $(LDFLAGS) -o list_of_lists list_of_lists.o $(LDLIBS)

list_of_lists.o: list_of_lists.cpp list_of_lists.h
    $(CXX) $(CFLAGS) -c list_of_lists.cpp -o list_of_lists.o

map_compare_test: $(OBJS) map_compare.o
    $(CXX) $(LDFLAGS) -o map_compare map_compare.o $(LDLIBS)

map_compare.o: map_compare.cpp map_compare.h
    $(CXX) $(CFLAGS) -c map_compare.cpp -o map_compare.o


clean:
    $(RM) $(OBJS) generic_queue_test.o list_of_lists.o map_compare.o

dist-clean: clean
    $(RM) generic_queue_test list_of_lists map_compare

Выход:

g++    -c -o generic_queue.o generic_queue.cpp
g++ -std=c++11 -g -Wall -pthread -m64 -I/usr/include/root -c map_compare.cpp -o map_compare.o
g++    -c -o vector_search.o vector_search.cpp

Мы видим, что только второй g++ команда полностью использует CFLAGS переменная. Зачем? Это связано с $(shell ...) часть CFLAGS переменная?

Изменить: смог решить мою проблему, изменив имя файла объекта vector_search_test.o в vector_search.o Почему это работает?

1 ответ

Решение

В вашем make-файле есть несколько ошибок, дополняющих это поведение.

Сначала рассмотрим OBJS, который содержит

generic_queue.o map_compare.o vector_search.o

Эти файлы являются предпосылками для других целей, но вы никогда не используете generic_queue.o или же vector_search.o, Ошибка № 1: у вас есть дополнительные предпосылки по ошибке.

Эти файлы являются предпосылками для других целей, поэтому Make должна их собрать. Но как? Вы предоставили правила для трех объектных файлов:

vector_search_test.o: vector_search.cpp vector_search.h
    ...

generic_queue_test.o: generic_queue.cpp generic_queue.h fixed_priority_queue.h
    ...

list_of_lists.o: list_of_lists.cpp list_of_lists.h
    ...

map_compare.o: map_compare.cpp map_compare.h
    ...

Этот последний сделает для map_compare.o, но вы не дали никаких правил для generic_queue.o или же vector_search.o (и на самом деле нет причин, по которым вам следует это делать, поскольку вы никогда не используете их). Но Make знает, как выполнять определенные стандартные сборки, такие как foo.cpp => foo.o, Если вы не предоставите правило, Make будет использовать его неявное правило, которое работает примерно так:

generic_queue.o: generic_queue.cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c generic_queue.cpp -o generic_queue.o

Это очень похоже на правила, которые вы написали. На самом деле, вы, вероятно, не заметили бы разницы - и вы могли бы опустить свои правила и позволить Make полагаться на это, но ошибка #2, вы добавили свои флаги -std=c++11 -g -Wall whatever к неправильной переменной. Использовать CXXFLAGS хранить флаги для компилятора C++; Вы добавили свой к CFLAGS, который для компилятора Си.

(Я пропустил шаблонные правила и автоматические переменные, так как вы, кажется, о них не знаете - я призываю вас изучить их, они очень полезны, но это на другой день.)

Другие вопросы по тегам