2012-08-14 5 views
1

Мой Makefile содержит следующие строкиздание .o файл, используя Makefile, разъяснение необходимости

11 SRC := $(shell echo src/*.cpp) 
12 SRC += $(shell echo $(TEST_ROOT)/*.cpp) 
13 
14 OBJECTS = $(SRC:.cpp=.o) 

22 # [debug] target 
23 $(TARGET): $(OBJECTS) 
24 $(CC) $(OBJECTS) -o $(TARGET) 
25 
26 # [debug] .o 
27 $(OBJECTS): $(SRC) 
28 $(CC) $(CFLAGS) $(DEBUG_FLAGS) -c $(SRC) $(OBJECTS) 

Который не может, потому что ... ну, очевидно, следующий не способ сделать это

g++ -pedantic -Wall -Werror -O0 -g -Wno-format -DUSE_MEASURE -c src/Timer.cpp test/TimerTest.cpp src/Timer.o test/TimerTest.o 

Как должен ли я изменить строку # 28, чтобы произвести .o из всех моих источников, пожалуйста?

ответ

2

Это должно сделать трюк:

$(OBJECTS): %.o : %.cpp 
    $(CC) $(CFLAGS) $(DEBUG_FLAGS) -c $< [email protected] 

Это правило будет строить один объектный файл, и сделать это будет вызывать один раз для каждого объекта, что другое правило нуждается. Вы можете написать правило, которое будет строить все объектные файлы за один проход, но для этого нет никакого преимущества.

EDIT:

Пусть SRC является src/foo.cpp src/bar.cpp testroot/baz.cpp,
так OBJECTS является src/foo.o src/bar.o testroot/baz.o

Мы могли бы иметь отдельное правило для каждого:

src/foo.o : src/foo.cpp 
    ... 

src/bar.o : src/bar.cpp 
    ... 

testroot/baz.o : testroot/baz.cpp 
    ... 

Но это излишним (так как команды очень похожи) и неудобно (поскольку мы не делаем ant добавлять/удалять правила всякий раз, когда мы добавляем/удаляем цели). Таким образом, мы используем pattern rule:

%.o : %.cpp 
    ... 

Теперь, когда Make хочет построить src/foo.o, он видит, что цель соответствует шаблону %.o, стебель (соответствующий %) является src/foo, и соответствующий PREREQ, src/foo.cpp существует, так он использует это правило.

Но мы имеем переменную OBJECTS, в котором перечислены цели, которые мы хотим построить с этим правилом, так что мы можем ограничить его к static pattern rule, который выглядит примерно так же, но имеет некоторые преимущества, мы не должны попасть в здесь:

$(OBJECTS) : %.o : %.cpp 
    ... 

Теперь для ... часть. Команда сообщает компилятору сканировать prereq (src/foo.cpp) и строить цель (src/foo.o), поэтому мы должны ссылаться на эти вещи в команде. Automatic variables помочь с этим; [email protected] это имя цели, и $< это имя первого (и в этом случае только) предпосылку:

$(OBJECTS): %.o : %.cpp 
    $(CC) $(CFLAGS) $(DEBUG_FLAGS) -c $< [email protected] 
+0

Beta - Спасибо вам большое. Очень приятный и информативный ответ. Если бы я мог бы с ++ вам дважды! –

+0

Быстрый вопрос, используя описанный вами сценарий, как я могу создать как отладочную версию, так и версию выпуска кода? Настройка '$ (D_OBJECTS):% .o:% .cpp' и' $ (R_OBJECTS):% .o:% .cpp' не работает –

+0

@James: у вас есть некоторые решения сделать в первую очередь. Вы не можете очень хорошо иметь две версии 'foo.o' в том же каталоге, чтобы вы могли: a) иметь отдельные каталоги' debug/'и' release/'для объектов (мой любимый подход), b) называть их 'foo_debug.o' и' foo_release.o', или c) имеют только одну версию 'foo.o', существующую одновременно, с некоторой уловкой, чтобы помочь запомнить, какой из них она есть. – Beta

Смежные вопросы