2017-02-09 4 views
5

У GNU Make есть -B опция, которая заставляет make игнорировать существующие цели. Он позволяет восстанавливать цель, но также восстанавливает все дерево зависимостей цели. Интересно, есть ли способ принудительно восстановить цель, не перестраивая ее зависимости (используя опции GNU Make, настройки в Makefile, совместимое программное обеспечение make и т. Д.)?Есть ли способ заставить перестроить цель (make -B), не перестраивая свои зависимости?

Иллюстрация проблемы:

$ mkdir test; cd test 
$ unexpand -t4 >Makefile <<EOF 
huge: 
    @echo "rebuilding huge"; date >huge 
small: huge 
    @echo "rebuilding small"; sh -c 'cat huge; date' >small 
EOF 
$ make small 
rebuilding huge 
rebuilding small 
$ ls 
huge Makefile small 
$ make small 
make: 'small' is up to date. 
$ make -B small 
rebuilding huge # how to get rid of this line? 
rebuilding small 
$ make --version | head -n3 
GNU Make 4.0 
Built for x86_64-pc-linux-gnu 
Copyright (C) 1988-2013 Free Software Foundation, Inc. 

Конечно можно rm small; make small, но есть встроенный способ?

+0

Does [этот вопрос] (http://stackoverflow.com/questions/12199237/tell-make-to-ignore-dependencies-when-the-top-target-has-created-помогли вам? – sycko

+0

Спасибо, но не так много: как я показал, используя 'ls',' огромный' здесь сохраняется (без '.SECONDARY:' target), а перестройка скорее связана с '-B'. –

ответ

3

Один из способов заключается в использовании опции -o для всех целей вы не хотите быть переделано:

-o FILE, --old-file=FILE, --assume-old=FILE 
     Consider FILE to be very old and don't remake it. 

РЕДАКТИРОВАНИЕ

Я думаю, что вы неправильно понимают документацию для -B; он говорит:

-B, --always-make 
     Unconditionally make all targets. 

Отметим, что все цели здесь; huge, конечно, цель, поэтому, если вы используете -B, он будет переделан.

Однако, я также неправильно прочитал ваш вопрос. Я думал, что вы хотели восстановить small без восстановления huge даже если huge новый, но вы пытаетесь получить small быть восстановлен, даже если huge имеет не изменилось, не так ли?

Вы определенно не хотите использовать -B. Этот вариант совсем не то, что вы ищете.

Обычно люди будут делать, что, удалив small:

rm -f small 
make small 

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

Вы можете использовать -W huge, но это означает, что вам нужно знать имя предпосылки, а не только цель, которую вы хотите построить.

+0

Спасибо, 'make -B -o огромный маленький' действительно работает, но он не идеален, если такие зависимости не могут быть получены автоматически ... –

+0

Я согласен, что это не идеально, но вы просили какой-либо метод :) – MadScientist

+0

Да, это почему я поддержал (но не готов отметить ответ, как принято). На самом деле, если бы вариант делал то, что он сам говорил (считайте цель очень старой и поэтому заставляйте ее в одиночку переделывать вместо того, чтобы игнорировать ее как очень новую), ответ был бы идеальным. –

2

Файл в довольно неприятную хака:

huge: 
    @echo "rebuilding huge"; date >huge 

small: $(if $(filter just,${MAKECMDGOALS}),huge) 
    @echo "rebuilding small"; sh -c 'cat huge; date' >small 

.PHONY: just 
just: ; 

Теперь вы можете

$ make -B just small 
+0

Это противно! –

+0

Спасибо, это самый «автоматический вызов» до сих пор, но, к сожалению, он не будет работать с правилами '$ <', '$ ^' и т. Д. В правилах. –

3

это поможет:

touch huge; make small 

?

+0

Спасибо, он работает (и так делает 'make -W огромный маленький'), но он не идеален, если такие зависимости не могут быть получены автоматически ... –

0

Ну, до сих пор я использую это частичное решение:

$ cat >~/bin/remake <<'EOF' 
#!/bin/sh 
# http://stackoverflow.com/questions/42139227 
for f in "[email protected]"; do 
    if [ -f "$f" ]; then 
    # Make the file very old; it's safer than removing. 
    touch [email protected] "$f" 
    fi 
done 
make "[email protected]" 
EOF 
$ chmod u+x ~/bin/remake 
$ # PATH="$HOME/bin:$PATH" in .bashrc 
$ remake --debug=b small 
GNU Make 4.0 
Built for x86_64-pc-linux-gnu 
Copyright (C) 1988-2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
Reading makefiles... 
Updating goal targets.... 
Prerequisite 'huge' is newer than target 'small'. 
Must remake target 'small'. 
rebuilding small 
Смежные вопросы