2012-10-16 2 views
2

Итак, я пытаюсь понять make-файлы. На данный момент у меня есть проект с некоторыми модулями, которые более или менее не зависят друг от друга.правильное использование makefile

Моего дерева каталогов, как это:

root/ 
- Source/ <-- referenced as $(INPUTPATH) 
- Build/ <-- referenced as $(BUILDPATH) 
- Release/ <-- referenced as $(OUTPUTPATH) 
- Makefile 

Я хочу, чтобы иметь источник (.cpp/ .h) от источника /, объектов на Build /, и исполняемый в данном Выпуск/*.

Итак, моя идея состояла в том, чтобы иметь несколько различных целей, и использовать их как это:

all: maps auxiliars methods 
    @echo "linking...";\ 
    $(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o ${OUTPUTPATH}/MainProgram 

dependency1: $(INPUTPATH)/foo.cpp 
    @echo "compiling ArbPrecision...";\ 
    cd ${BUILDPATH};\ 
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$? 

dependency2: dependency1 $(INPUTPATH)/bar.cpp 
    @echo "compiling saddleConstructor...";\ 
    cd ${BUILDPATH};\ 
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/bar.cpp 

maps: dependency2 $(INPUTPATH)/*Map.cpp 
    @echo "compiling maps...";\ 
    cd ${BUILDPATH};\ 
    $(CC) $(CFLAGS) $(CINCLUDE) -c ../$(INPUTPATH)/*Map.cpp 
... (auxiliars and methods) 

в $ CINCLUDE и CFLAGS просто компилятор такие вещи, как заголовки и внешние LIBS.

Все работает почти идеально: на каждой цели он запрашивает зависимости другой цели и для * cpp на источнике. Если этого не существует, он вызывает цель и компилирует * cpp. Исполняемый файл создается без ошибок.

Однако, если я дважды вызываю «make», время, которое требуется для компиляции, одинаково для первого и второго времени, даже если я не вношу никаких изменений в источник. Так что, по-видимому, я не правильно задаю зависимости.

Может ли кто-нибудь указать мне правильное направление для выполнения этой подборки? Я делаю что-то неправильно, и я не понимаю, что это такое.

Спасибо, Jorge

+1

При компиляции входной файл является исходным файлом (то есть .cpp-файлом), а выход представляет собой объектный файл (обычно файл .o или .obj). Вот где вы должны быть зависимыми. Вы должны сказать, что bar.o зависит от bar.cpp и т. Д. Аналогично, шаг привязки, ваша программа зависит от группы объектных файлов, поэтому они должны быть определены в зависимостях для 'all'. – john

ответ

3

Производитель рассчитывает работать прочь файлов. Для каждого правила он проверяет, существует ли целевой файл , названный этим правилом (1), и (2) обновлен (т. Е. Изменен после любой из его зависимостей). Если файл не обновлен, он выполняет правило, чтобы обновить его.

Поэтому, как ваш Makefile в настоящее время пишется, когда вы запускаете make, Make выполняет следующие действия:

  • all является первым правилом, так что если вы не указали никаких аргументов, сделать обрабатывает all правила ,
  • Нет файла с именем all, поэтому необходимо выполнить правило all.
  • all зависит от правила dependency1. Нет файла с именем dependency1, поэтому необходимо выполнить правило dependency1.
  • dependency1 зависит от правила dependency2. Не существует файла с именем dependency2, поэтому должно быть выполнено правило dependency2.

Что же вы хотите что-то похожее на следующее:

OBJS := foo.o bar.o Map.o 

all: $(OUTPUTPATH)/MainProgram 

$(OUTPUTPATH)/MainProgram: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) $(CLIBS) -o $(OUTPUTPATH)/MainProgram 

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

.PHONY: all 

Обратите внимание на следующее:

  • Поскольку Make работает на файлах, цели и зависимостей правила перечислены по имени файла везде, где возможное.
  • Вместо того, чтобы перечислять файлы .cpp по отдельности, для создания каждого файла .o используется файл pattern rule. В правиле шаблона $< и [email protected]automatic variables используются, чтобы указать первое предварительное условие (файл) и целевое (файл), соответственно.
  • Сделать эхо свои команды по умолчанию, так что вам не нужно echo.
  • Для GNU Make, all указан как phony target, чтобы сохранить Make от поиска файла с именем all.
+0

Правило шаблона должно содержать имена каталогов: '$ (BUILDPATH) /%. O: $ (INPUTPATH) /%. Cpp' – anatolyg

+0

@anatolyg - Спасибо. Я упрощал пути, частично фокусировался на концепциях, а отчасти потому, что был ленив. :-) –

+0

Хорошо, это большая разница ...: p Почему вы скомпилировали объекты с -o и исполняемым файлом с -o? Разве не -c для компиляции и -o для связи? –

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