У меня есть 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
.PHONY
была не единственная ваша проблема, и вы не должны редактировать решение в вопросе, или, по крайней мере, больше.)Ответы:
Вы можете объявить одну или несколько ваших целей фальшивыми .
источник
:
, а не только к конечному результату, который вы хотите создать (например, ваш двоичный файл). В вопросеrelease
,debug
,clean
иinstall
являются мишенями MAKE, неxxx_util
илиxxxcore.so
или что - нибудь еще.-B
Переключатель , чтобы сделать, чей длинную форму--always-make
, говоритmake
Пренебрегать метки время и сделать указанные цели. Это может победить цель использования make, но это может быть то, что вам нужно.источник
Один прием, который раньше
make
описывался в руководстве по Sun, - это использование (несуществующей) цели «.FORCE». Вы можете сделать это, создав файл force.mk, который содержит:Затем, если ваш существующий make-файл вызван
makefile
, вы можете запустить:Поскольку
.FORCE
ничего не существует, все, что от него зависит, будет устаревшим и перестроенным.Все это будет работать с любой версией
make
; в Linux у вас есть GNU Make и, следовательно, вы можете использовать цель .PHONY, как обсуждалось.Также стоит подумать, почему
make
релиз считается актуальным. Это может быть потому, что у вас естьtouch release
команда среди выполненных команд; это может быть связано с тем, что существует файл или каталог с именем 'release', который существует и не имеет зависимостей и поэтому является актуальным. Тогда есть фактическая причина ...источник
Кто-то еще предложил .PHONY, который определенно правильно. .PHONY следует использовать для любого правила, для которого сравнение даты между входом и выходом недопустимо. Поскольку у вас нет целей в форме,
output: input
вы должны использовать .PHONY для ВСЕХ из них!Все это говорит о том, что вам, вероятно, следует определить некоторые переменные в верхней части вашего make-файла для различных имен файлов и определить настоящие правила make, которые имеют как входные, так и выходные разделы, чтобы вы могли использовать преимущества make, а именно то, что вы будете на самом деле только компилировать вещи, которые необходимо копмилировать!
Редактировать: добавлен пример. Не проверено, но это, как вы делаете .PHONY
источник
.PHONY
цели не имеет значения. Это может быть где угодноMakefile
.Если я правильно помню, make использует временные метки (время изменения файла), чтобы определить, актуальна ли цель. Распространенным способом принудительного пересоздания является обновление этой метки времени с помощью команды «touch». Вы можете попробовать вызвать 'touch' в вашем make-файле, чтобы обновить временную метку одной из целей (возможно, одного из этих подфайлов), что может заставить Make выполнить эту команду.
источник
Этот простой метод позволит make-файлу нормально функционировать, когда форсирование нежелательно. Создайте новую цель под названием force в конце вашего make-файла . Сила цель будет касаться файла, используемая по умолчанию цели зависит. В приведенном ниже примере я добавил touch myprogram.cpp . Я также добавил рекурсивный вызов сделать . Это приведет к тому, что цель по умолчанию будет выполняться каждый раз, когда вы вводите make force .
источник
make
внутри Makefile. Используйте$(MAKE)
вместо этого.Я попробовал это, и это сработало для меня
добавить эти строки в Makefile
сохранить и теперь звонить
и он снова все перекомпилирует
Что произошло?
1) «новые» звонки чистые. 'clean' do 'rm', который удаляет все объектные файлы с расширением .o.
2) «новые» звонки «сделать». 'make' видит, что нет файлов '.o', поэтому он снова создает все '.o'. тогда компоновщик связывает все файлы .o в одном исполняемом файле
Удачи
источник
new
лучшего использования,$(MAKE)
чемmake
В соответствии с рекурсивной маркой Миллера, считающейся вредной, вам следует избегать звонков
$(MAKE)
! В случае, если вы показываете, это безвредно, потому что на самом деле это не make-файл, а просто скрипт-обертка, который с таким же успехом мог бы быть написан в Shell. Но вы говорите, что продолжаете в том же духе на более глубоких уровнях рекурсии, так что вы, вероятно, столкнулись с проблемами, показанными в этом откровенном эссе.Конечно, с GNU сделать это громоздко, чтобы избежать. И хотя они знают об этой проблеме, это их документированный способ ведения дел.
ОТО, makepp был создан как решение этой проблемы. Вы можете писать свои make-файлы на уровне каталогов, но все они объединяются в полный обзор вашего проекта.
Но устаревшие make-файлы написаны рекурсивно. Таким образом, существует обходной путь, при котором
$(MAKE)
ничего не происходит, кроме как направить подзапросы обратно в основной процесс makepp. Только если вы делаете избыточные или, что еще хуже, противоречивые вещи между вашими субмейками, вы должны запросить--traditional-recursive-make
(что, конечно, нарушает это преимущество makepp). Я не знаю других ваших make-файлов, но если они написаны правильно, с makepp необходимые перестройки должны выполняться автоматически, без необходимости каких-либо хаков, предложенных здесь другими.источник
:
), он всегда будет восстанавливать при необходимости.Если вам не нужно сохранять какие-либо результаты, которые вы уже успешно скомпилировали
перестраивает все
источник
Это на самом деле зависит от цели. Если это фальшивая цель (то есть цель НЕ связана с файлом), вы должны объявить ее как .PHONY.
Однако, если цель не является фальшивой целью, но вы просто хотите по какой-то причине ее перестроить (например, когда вы используете макрос предварительной обработки __TIME__), вы должны использовать схему FORCE, описанную в ответах здесь.
источник
http://www.gnu.org/software/make/manual/html_node/Force-Targets.html#Force-Targets
источник
Это уже упоминалось, но думал, что я мог бы добавить к использованию
touch
Если вы
touch
скомпилировали все исходные файлы,touch
команда изменит временные метки файла на системное времяtouch
команда была выполнена.Timstamp исходного файла - это то, что
make
используется, чтобы «знать», что файл изменился, и его нужно перекомпилировать.Например: если проект был проектом c ++, то выполните
touch *.cpp
, затемmake
снова запустите , и make должна перекомпилировать весь проект.источник
Как указал абернер, в руководстве по сборке GNU есть рекомендуемое решение, которое использует «поддельную» цель для принудительного восстановления цели:
Это будет работать чисто, независимо от любых других зависимостей.
Я добавил точку с запятой в решение из руководства, иначе требуется пустая строка.
источник
В моей системе Linux (Centos 6.2) есть существенная разница между объявлением цели .PHONY и созданием фиктивной зависимости от FORCE, когда правило действительно создает файл, соответствующий цели. Когда файл должен быть заново создан каждый раз, ему требовалась как поддельная зависимость FORCE для файла, так и .PHONY для поддельной зависимости.
неправильно:
право:
источник
make clean
удаляет все уже скомпилированные объектные файлы.источник