Для чего нужны правила двоеточия в Makefile? - PullRequest
29 голосов
/ 25 октября 2011

Раздел 4.13 руководства по GNU Make описывает так называемые правила двоеточия:

Правила двойного двоеточия - это правила, написанные с помощью «::» вместо «:» после целевых имен,Они обрабатываются иначе, чем обычные правила, когда одна и та же цель появляется в нескольких правилах.

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

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

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

Правила двойного двоеточия несколько неясны и часто не очень полезны;они предоставляют механизм для случаев, в которых метод, используемый для обновления цели, отличается в зависимости от того, какие файлы предварительных требований вызвали обновление, и такие случаи редки.

В каждом правиле с двумя двоеточиями должны указываться команды;если это не так, неявное правило будет использоваться, если оно применяется.Смотрите раздел «Использование неявных правил».

Я как бы понимаю значение каждого предложения этого раздела в отдельности, но мне все еще не ясно, какие правила двойного двоеточия предназначены для .Что касается редкости, я еще не видел ни одного проекта с открытым исходным кодом, чей Makefile not начинался с

all::

Следовательно: Какова цель правил двойных двоеточийв Makefiles?

Ответы [ 5 ]

13 голосов
/ 20 сентября 2014

Каждое :: правило обрабатывается независимо, поэтому оно может быть проще.Например, единственное правило:

libxxx.a : sub1.o sub2.o
    ar rv libxxx.a sub1.o
    ar rv libxxx.a sub2.o

может быть заменено двумя более простыми правилами:

libxxx.a :: sub1.o
    ar rv libxxx.a sub1.o

libxxx.a :: sub2.o
    ar rv libxxx.a sub2.o

Утилиты, такие как AutoMake, легче разбрасывают многие простые правила, чем несколько сложных..

Отличный ответ с большим количеством примеров был опубликован, затем снят и найден здесь:

https://web.archive.org/web/20180122002430/http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html

Спасибо Р.К. Оуэну за его написание и Эдварду Минниксучтобы найти его снова!

8 голосов
/ 01 ноября 2015

Существует три ситуации, в которых полезно использовать двойное двоеточие:

  1. Переключение между правилами компиляции, в зависимости от того, какое условие является более новым, чем цель.Следующий пример основан на «Примере 19-3. Правила двойного двоеточия» из http://books.gigatux.nl/mirror/cinanutshell/0596006977/cinanut-CHP-19-SECT-3.html

Образец .c файла:

c@desk:~/test/circle$ cat circle.c 
#include <stdio.h>

int main (void)
{
  printf("Example.\n");
  return 0;
}

Используемый Makefile:

c@desk:~/test/circle$ cat Makefile 
# A makefile for "circle" to demonstrate double-colon rules.

CC = gcc
RM = rm -f
CFLAGS = -Wall -std=c99
DBGFLAGS = -ggdb -pg
DEBUGFILE = ./debug
SRC = circle.c

circle :: $(SRC)
        $(CC) $(CFLAGS) -o $@ -lm $^

circle :: $(DEBUGFILE)
        $(CC) $(CFLAGS) $(DBGFLAGS) -o $@ -lm $(SRC)

.PHONY : clean

clean  :
        $(RM) circle

Результат:

c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
make: *** No rule to make target 'debug', needed by 'circle'.  Stop.
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c
c@desk:~/test/circle$ vim circle.c 
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
c@desk:~/test/circle$ vim debug 
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c
Создание терминала для правила шаблона.

Следующий пример объясняет эту ситуацию: файл a.config получен из a.cfg, который, в свою очередь, получен из a.cfg1 (a.cfgявляется промежуточным файлом).

c@desk:~/test/circle1$ ls
a.cfg1  log.txt  Makefile
c@desk:~/test/circle1$ cat Makefile 
CP=/bin/cp

%.config:: %.cfg
        @echo "$@ from $<"
        @$(CP) $< $@

%.cfg: %.cfg1
        @echo "$@ from $<"
        @$(CP) $< $@

clean:
        -$(RM) *.config

Результат (поскольку правило% .config является терминальным, make запрещает создание промежуточного файла a.cfg из a.cfg1):

c@desk:~/test/circle1$ make a.conf
make: *** No rule to make target 'a.conf'.  Stop.

Без двойного двоеточия для% .config получается:

c@desk:~/test/circle1$ make a.config
a.cfg from a.cfg1
a.config from a.cfg
rm a.cfg
Создайте правило, которое выполняется всегда (полезно для чистых правил).Правило не должно иметь предпосылок!

c @ desk: ~ / test / circle3 $ cat Makefile

CP=/bin/cp  
a.config::  
    @echo "Always" >> $@  

a.config::  
    @echo "Always!" >> $@  

clean:  
    -$(RM) *.config  

Результат:

c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config 
Always
Always!
c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config
Always
Always!
Always
Always!
5 голосов
/ 26 октября 2011

Как сказано в документации, правила двойного двоеточия редко бывают очень полезными.Это хороший, небольшой способ не называть отдельные цели составной фальшивой цели (как и все :), но в этой роли это не обязательно.Я могу сформировать только один надуманный пример, где они необходимы:

Предположим, у вас есть лог-файл L, который объединен с несколькими другими лог-файлами L1, L2, .... Вы формулируете ряд правил с двойным двоеточием:

L :: L1
     cat $< >> $@ && rm $<

L :: L2
     cat $< >> $@ && rm $<

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

5 голосов
/ 25 октября 2011

Они удобны для нерекурсивных make-файлов и целей, таких как clean. То есть отдельный файл .mk может добавлять свои собственные команды к цели clean, уже определенной в другом месте.

Документация дает ответ:

Правила двойного двоеточия несколько неясны и не часто очень полезны; они предоставляют механизм для случаев, в которых метод, используемый для обновления цели, отличается в зависимости от того, какие файлы предварительных требований вызвали обновление, и такие случаи редки.

0 голосов
/ 22 февраля 2019

Я приведу простой пример, который, надеюсь, прояснит использование:

Поэкспериментируйте со следующим make-файлом:

  a.faux:: dep1.fake
      $(info run a dep1.fake)
      touch a.faux

  a.faux:: dep2.fake
      $(info run a dep2.fake)
      touch a.faux

  dep1.fake:
      touch dep1.fake

  dep2.fake:
      touch dep2.fake

Запустите make a.faux, это вызовет dep1.fake иdep2.fake бежать.Удалите dep1.fake и снова запустите make a.faux, только dep1.fake запустится.

...