Pergunta

Supondo que temos a regra:

a: b c d e

e b, c, d e e são independentes uns dos outros.

é a ordem de fazer b, c, d, e definido? Parece que geralmente eles serão feitos em b fim, c, d, e, mas pode às vezes acontecer, que a ordem será diferente?

Foi útil?

Solução

Claro, se eu usar make -j a, eles podem todos são construídas ao mesmo tempo (dependendo se b, c, d, ou e por sua vez, tem outras dependências / inter-relacionados).

Outras dicas

Não, a ordem é não definido. Isso é o todo ponto na utilização de programação orientada a dependência declarativa:. Que o computador pode escolher a ordem de avaliação ideal, ou de facto, avaliá-los, mesmo ao mesmo tempo

Em que condições prévias pedido será feito pelo make GNU?

Depende do tipo de pré-requisito. De acordo tho o GNU Make manual , Seção 4.2:

Na verdade, existem dois tipos diferentes de pré-requisitos compreendido por GNU make: pré-requisitos normais, como descrito na anterior seção, e pré-requisitos única encomendas. Um pré-requisito normal, faz dois declarações: primeiro, que impõe uma ordem em que as receitas serão invocados: as receitas para todos os pré-requisitos de um alvo será concluída antes de a receita para o alvo é executado. Em segundo lugar, impõe a relação de dependência: se algum pré-requisito é mais recente do que a alvo, então o alvo é considerado out-of-date e deve ser reconstruído.

Normalmente, isso é exatamente o que você quer: se pré-requisito de um alvo é atualizado, em seguida, o alvo também deve ser atualizado.

Ocasionalmente, no entanto, você tem uma situação onde você quer impor uma ordenação específica sobre as regras para ser chamado sem forçando o alvo a ser atualizado se uma dessas regras é executado. Nesse caso, você quiser definir fim-only pré-requisitos. Fim-only pré-requisitos podem ser especificados colocando um símbolo pipe (|) na lista de pré-requisitos: nenhum pré-requisitos para a esquerda do símbolo pipe são normais; quaisquer pré-requisitos para a direita são fim-only:

   targets: normal-prerequisites | order-only-prerequisites

A seção de pré-requisitos normal pode, naturalmente, ser vazio. Além disso, você pode ainda declarar várias linhas de pré-requisitos para o mesmo alvo: eles são acrescentados adequadamente (pré-requisitos normais são acrescentados ao a lista de pré-requisitos normais; pré-requisitos única encomendas são anexada à lista de pré-requisitos única ordem-). Note que se você declarar o mesmo arquivo para ser tanto um normal e um fim-only pré-requisito, o pré-requisito normal, tem precedência (já que eles tem um super rigoroso do comportamento de um fim-único pré-requisito).

Considere um exemplo onde os alvos são para ser colocado em um separado diretório e esse diretório pode não existir antes make é executado. No Nessa situação, você quer que o diretório a ser criado antes de qualquer alvos são colocados em-lo, mas, porque a data e hora em diretórios mudar sempre que um arquivo é adicionado, removido ou renomeado, certamente não quero reconstruir todos os alvos sempre que o diretório de timestamp muda. Uma maneira de gerenciar isso é com fim-only Pré-requisitos: tornar o diretório uma ordem-único pré-requisito em todos os as metas:

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir $(OBJDIR)

Agora, a regra para criar o diretório ‘objdir’ será executado, se necessário, antes de qualquer ‘.o’ é construído, mas não ‘.o’ será construído porque o ‘Objdir’ diretório timestamp alterado.

No direito ordem, com base nas regras que você fornece. Para o seu exemplo em particular, que poderia significar qualquer um de uma série de diferente (4! = 24, de memória) ordens.

Todos os programas make são livres para escolher a ordem em que quiser, desde que as dependências são honrados. Se houvesse outras regras no seu exemplo, dizer c: b, então c serão feitas antes da b (mas que não é o caso, como você aponta).

Se você precisa confiar em uma ordem específica, você vai precisar de mais regras para aplicá-la. Caso contrário make pode fazer o que bem entende. A documentação para GNU make afirma só como regras são processados, e não a ordem em que as dependências dentro de uma regra são processados. A ordem lógica mais (para mim, pelo menos) seria a ordem em que eles são listados, mas isso não é garantido.

Não, você não pode contar com a ordenação quando não há relações de dependência.

  • Faça precisa fazer uma topológica tipo , porque dependências podem ter relacionamentos adicionais e múltiplas. O tipo que faz faz é potencialmente bastante complexa, como nós no gráfico pode estar relacionada várias vezes em diferentes níveis
  • em algoritmos gerais de classificação não são naturalmente estável , mesmo para os tipos à base de chave simples

Se as questões de ordem, você pode aplicá-la seletivamente usando make recursiva . Por exemplo, suponha que você não se importa que ordem b e c são feitos em, contanto que eles estão ambos feitos antes d e d é feita antes e. Em seguida, você pode escrever sua regra como:

a: b c
    $(MAKE) d
    $(MAKE) e
    # Additional steps to make a

Esteja ciente de que, dependendo da complexidade de d e e, esta abordagem pode fazer coisas más para os seus tempos de compilação: veja recursiva Marca Considerado Nocivo (PDF) para argumentos contra a fazê-lo desta forma.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top