Идентичная номенклатура 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
, который для компилятора Си.
(Я пропустил шаблонные правила и автоматические переменные, так как вы, кажется, о них не знаете - я призываю вас изучить их, они очень полезны, но это на другой день.)