Por que usar make sobre um script de shell?

128

Make me parece simplesmente um script de shell com manipulação um pouco mais fácil dos argumentos da linha de comando.

Por que é padrão executar make em vez de ./make.sh

HoboBen
fonte
para a pergunta inversa: por que usar o shell script sobre make (por causa do aparente tratamento mais fácil dos argumentos da linha de comando), especialmente para tarefas do administrador do sistema, leia aqui: unix.stackexchange.com/a/497601/1170
lesmana

Respostas:

125

A idéia geral é que makesuporta (razoavelmente) reconstruções mínimas - ou seja, você diz quais partes do seu programa dependem de quais outras partes. Quando você atualiza alguma parte do programa, ele reconstrói apenas as partes que dependem disso. Embora você possa fazer isso com um script de shell, seria muito mais trabalhoso (verificar explicitamente as datas da última modificação em todos os arquivos etc.) A única alternativa óbvia com um script de shell é reconstruir tudo sempre. Para pequenos projetos, essa é uma abordagem perfeitamente razoável, mas para um grande projeto, uma reconstrução completa pode demorar uma hora ou mais - usando make, você pode realizar a mesma coisa em um ou dois minutos ...

Eu provavelmente também devo acrescentar que existem algumas alternativas a serem feitas que têm pelo menos recursos amplamente semelhantes. Especialmente nos casos em que apenas alguns arquivos em um projeto grande estão sendo reconstruídos, alguns deles (por exemplo, Ninja ) geralmente são consideravelmente mais rápidos que o make.

Jerry Coffin
fonte
66

Make é um sistema especialista

Existem várias coisas que são difíceis de fazer com scripts de shell ...

  • Obviamente, ele verifica o que está desatualizado, de modo a criar apenas o que precisa ser construído
  • Ele executa uma classificação topológica ou algum outro tipo de análise em árvore que determina o que depende de qual e em que ordem construir as coisas desatualizadas, de modo que todo pré-requisito seja construído antes de cada dependência e apenas uma vez.
  • É uma linguagem para programação declarativa . Novos elementos podem ser adicionados sem a necessidade de mesclá-los em um fluxo de controle imperativo.
  • Ele contém um mecanismo de inferência para processar regras, padrões e datas, e isso, quando combinado com as regras do seu Makefile específico, é o que torna o sistema especialista .
  • Tem um processador de macro.
  • Veja também: um resumo anterior do make .
DigitalRoss
fonte
2
É bastante limitado como um sistema especialista, no entanto. Por exemplo, cada inferência pode usar a mesma regra apenas uma vez.
Reinierpost 27/09/10
1
Apenas para elaborar o ponto 2) em termos de engenharia mais leigos, um script shell impõe uma ordem linear, enquanto um makefile é semelhante a uma árvore. Remove dependências cronológicas desnecessárias (embora, na prática, o processo de fabricação seja executado linearmente).
Sridhar Sarnobat 13/10
2
... Eu acho que o problema com Makefiles sobre scripts de shell é análogo ao problema com CSS sobre javascript. Não é tão óbvio em que ordem cronológica cada nó é executado. Embora pelo menos com Makefiles você ainda veja o comando shell real. Com CSS, mesmo isso é abstraído.
Sridhar Sarnobat
Eu tenho alguns comentários que eu aprecio se alguém os esclarecer. 1 / não são seus primeiro e dois pontos relacionados, no sentido de que esse tipo topológico é como a construção incremental é implementada? 2 / você não pode apontar o número 3 implementado usando a composição de funções também. 3 / eu gostaria de entender mais sobre as vantagens de 4 e 5 para o usuário final MakeFile, e por que essas vantagens não pode ser implementado através da composição de comandos shell juntos
Amine Hajyoussef
Esta é a primeira vez que me deparei com o Make descrito como um sistema especialista. Como alguém que construiu sistemas especializados, não é algo que eu consideraria. O Make obviamente possui um mecanismo de inferência para deduzir como criar seu programa através das regras declarativas especificadas no makefile, mas é menos óbvio que é um sistema baseado em conhecimento, pois as regras (leaf) são comandos de shell a serem executados, e não fatos. E o termo "sistema especialista" é usado para se referir a um sistema que capturou com sucesso a experiência de um especialista de classe mundial, o que não é o caso. O júri ainda está fora de mim.
Dennis
9

Make garante que apenas os arquivos necessários sejam recompilados quando você fizer alterações nos arquivos de origem.

Por exemplo:

final : 1.o 2.o
    gcc -o final 1.o 2.o

1.o : 1.c 2.h
    gcc -c 1.c

2.o : 2.c 2.h
    gcc -c 2.c

Se eu alterar 2.hapenas o arquivo e executar make, ele executará todos os 3 comandos, na ordem inversa.

Se eu alterar 1.capenas o arquivo e executar make, ele executará apenas os 2 primeiros comandos na ordem inversa.

Tentar fazer isso com seu próprio script de shell envolverá muita if/elseverificação.

Chris Dodd
fonte
ou use algo assim rsync -r -c -I $SOURCE $DEST_DIRcom casca.
Spartacus9
9

Assim como acima, Make é uma linguagem de programação paralela declarativa (-ish).

Digamos que você tenha 4.000 arquivos gráficos para converter e 4 CPUs. Tente escrever um shell script de 10 linhas (estou sendo generoso aqui) que fará isso de maneira confiável enquanto satura suas CPUs.

Talvez a verdadeira questão seja por que as pessoas se preocupam em escrever scripts shell.

bobbogo
fonte
1
Sim, você está afrouxando a ordem linear total em uma ordem mais parecida com uma árvore.
Sridhar Sarnobat
4

make manipula dependências: o makefile as descreve: o binário depende dos arquivos de objeto, cada arquivo de objeto depende de um arquivo de origem e de cabeçalhos ... quando o make é executado, a data dos arquivos é comparada para determinar o que precisa ser recompilado .

Pode-se chamar diretamente um destino para não criar tudo descrito no Makefile.

Além disso, a sintaxe make fornece substituição, vpath

Tudo isso pode ser escrito em scripts de shell, com make você já o possui.

filante
fonte