Как вы заставляете make-файл перестраивать цель - PullRequest
144 голосов
/ 03 мая 2009

У меня есть make-файл, который создает, а затем вызывает другой make-файл. Поскольку этот make-файл вызывает больше make-файлов, которые выполняют работу, он действительно не изменяется. Таким образом, он продолжает думать, что проект построен и обновлен.

dnetdev11 ~ # make
make: `release' is up to date.

Как мне заставить make-файл перестроить цель?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

Примечание: имена удалены для защиты невинных

Редактировать: Финал Фиксированная версия:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib

Ответы [ 14 ]

614 голосов
/ 03 мая 2009

Переключатель -B для создания, длинная форма которого --always-make, сообщает make игнорировать временные метки и создавать указанные цели. Это может победить цель использования make, но это может быть то, что вам нужно.

25 голосов
/ 03 мая 2009

Вы можете объявить одну или несколько ваших целей фальшивыми .

Лживая цель - это цель, которая на самом деле не является именем файла; скорее это это просто имя для рецепта, который будет выполнен, когда вы делаете явный запрос. Есть две причины использовать фальшивую цель: чтобы избежать конфликт с файлом с тем же именем и для повышения производительности.

...

Лживая цель не должна быть предпосылкой для реального файла цели; если это, его рецепт будет запускаться каждый раз, когда make идет, чтобы обновить это файл. Пока ложная цель никогда не является обязательным условием реального цель, фальшивый рецепт цели будет выполняться только тогда, когда цель - указанная цель

15 голосов
/ 03 мая 2009

Один прием, который раньше документировался в руководстве Sun для make, заключается в использовании (несуществующей) цели «.FORCE». Вы можете сделать это, создав файл force.mk, содержащий:

.FORCE:
$(FORCE_DEPS): .FORCE

Затем, если ваш существующий make-файл называется makefile, вы можете выполнить:

make FORCE_DEPS=release -f force.mk -f makefile release

Поскольку .FORCE не существует, все, что от него зависит, будет устаревшим и перестроено.

Все это будет работать с любой версией make; в Linux у вас есть GNU Make, и поэтому вы можете использовать цель .PHONY, как обсуждалось.

Стоит также подумать, почему make считает выпуск актуальным. Это может быть потому, что у вас есть команда touch release среди выполненных команд; это может быть связано с тем, что существует файл или каталог с именем 'release', который существует и не имеет зависимостей и поэтому является актуальным. Тогда есть настоящая причина ...

13 голосов
/ 03 мая 2009

Кто-то еще предложил .PHONY, что определенно правильно. .PHONY следует использовать для любого правила, для которого сравнение даты между входом и выходом недопустимо. Поскольку у вас нет целей в виде output: input, вы должны использовать .PHONY для ВСЕХ из них!

Все это говорит о том, что вы, вероятно, должны определить некоторые переменные в верхней части вашего make-файла для различных имен файлов и определить настоящие правила make, которые имеют как входные, так и выходные разделы, чтобы вы могли использовать преимущества make, а именно: только на самом деле компилировать вещи, которые необходимы для компиляции!

Редактировать: добавлен пример. Не проверено, но это то, как вы делаете .PHONY

.PHONY: clean    
clean:
    $(clean)
4 голосов
/ 21 апреля 2015

Этот простой метод позволит make-файлу нормально функционировать, когда форсирование нежелательно. Создайте новую цель с именем force в конце вашего makefile . Цель force коснется файла, от которого зависит цель по умолчанию. В приведенном ниже примере я добавил touch myprogram.cpp . Я также добавил рекурсивный вызов в make . Это приведет к тому, что цель по умолчанию будет выполняться каждый раз, когда вы набираете make force .

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make
4 голосов
/ 03 мая 2009

Если я правильно помню, make использует временные метки (время модификации файла), чтобы определить, актуальна ли цель. Распространенным способом принудительного пересоздания является обновление этой временной метки с помощью команды «touch». Вы можете попробовать вызвать «touch» в вашем make-файле, чтобы обновить временную метку одной из целей (возможно, одного из этих подфайлов), что может заставить Make выполнить эту команду.

3 голосов
/ 04 февраля 2016

Я попробовал это, и у меня это сработало

добавить эти строки в Makefile

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

сохраните и теперь звоните

make new 

и все снова будет перекомпилировано

Что случилось?

1) «новые» звонки чистые. 'clean' do 'rm', который удаляет все объектные файлы с расширением '.o'.

2) «новые» звонки «сделать». 'make' видит, что нет файлов '.o', поэтому он снова создает все '.o'. затем компоновщик связывает все файлы .o в одном исполняемом файле

Удачи

1 голос
/ 27 октября 2016

Если вам не нужно сохранять какие-либо результаты, которые вы уже успешно скомпилировали

nmake /A 

перестраивает все

1 голос
/ 08 июля 2012

В соответствии с рекурсивной маркой Миллера, считающейся вредной , вам следует избегать вызова $(MAKE)! В случае, если вы показываете, это безвредно, потому что на самом деле это не make-файл, а просто скрипт-обертка, который с таким же успехом мог бы быть написан в Shell. Но вы говорите, что продолжаете в том же духе на более глубоких уровнях рекурсии, так что вы, вероятно, столкнулись с проблемами, показанными в этом откровенном эссе.

Конечно, с GNU сделать это громоздким, чтобы избежать. И хотя они знают об этой проблеме, это их документированный способ действий.

OTOH, makepp был создан как решение этой проблемы. Вы можете писать свои make-файлы на уровне каталогов, но все они объединяются в полный обзор вашего проекта.

Но устаревшие make-файлы пишутся рекурсивно. Таким образом, существует обходной путь, когда $(MAKE) ничего не делает, кроме как направляет подзапросы обратно в основной процесс makepp. Только если вы делаете избыточные или, что еще хуже, противоречивые вещи между вашими субмейками, вы должны запросить --traditional-recursive-make (что, конечно, нарушает это преимущество makepp). Я не знаю других ваших make-файлов, но если они написаны правильно, с makepp необходимые перестройки должны происходить автоматически, без необходимости каких-либо хаков, предложенных здесь другими.

0 голосов
/ 29 ноября 2017

make clean удаляет все уже скомпилированные объектные файлы.

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