Как заставить файл makefile восстановить цель

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

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

Как заставить файл makefile восстановить цель?

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

Ответ 1

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

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

...

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

Ответ 2

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

Ответ 3

Один трюк, который был документирован в руководстве 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", который существует и не имеет зависимостей, и поэтому обновляется. Тогда есть реальная причина...

Ответ 4

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

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

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

.PHONY: clean    
clean:
    $(clean)

Ответ 5

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

Ответ 6

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

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

force:
       touch yourProgram.cpp
       make

Ответ 7

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

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

clean:
    rm *.o output

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

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

make new 

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

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

'новые' звонки чистые 'clean' do 'rm', который удаляет все объектные файлы с расширением '.o' 'new' calls 'make'. "make" видеть, что файлов ".o" нет, поэтому он идет вперед и снова создает все ".o". то компоновщик связывает весь файл .o с одним исполняемым выходом

Удачи.

Ответ 8

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

Ответ 9

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

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

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

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

Ответ 10

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

nmake /A 

восстанавливает все

Ответ 11

На самом деле это зависит от цели. Если это фальшивая цель (т.е. Цель НЕ относится к файлу), вы должны объявить ее как .PHONY.

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

Ответ 13

Это уже упоминалось, но я подумал, что могу добавить к использованию touch

Если вы touch все исходные файлы должны быть скомпилированы, команда touch изменяет временные метки файла на системное время, когда была выполнена команда touch.

Исходный файл timstamp - это то, что make использует для "знать", что файл был изменен и нуждается в повторной компиляции

Например: если проект был проектом С++, выполните touch *.cpp, затем запустите make еще раз, и make должен перекомпилировать весь проект.

Ответ 14

В моей системе Linux (Centos 6.2) существует значительная разница между объявлением целевой .PHONY и созданием фальшивой зависимости от FORCE, когда правило действительно создает файл, соответствующий цели. Когда файл необходимо регенерировать каждый раз, он требует, чтобы оба фальшивая зависимость FORCE в файле и .PHONY для поддельной зависимости.

неверно:

date > [email protected]

справа:

FORCE
    date > [email protected]
FORCE:
    .PHONY: FORCE