Na verdade, você está certo: ele executa outra instância do make. Uma possível solução seria:
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : clean clearscr all
clearscr:
clear
Ao chamar, make fresh
você obtém primeiro o clean
alvo, depois o clearscreen
que é executado clear
e, finalmente, o all
que faz o trabalho.
EDITAR 4 de agosto
O que acontece no caso de compilações paralelas com a -j
opção de make ? Existe uma maneira de corrigir a ordem. Do manual do make, seção 4.2:
Ocasionalmente, no entanto, você tem uma situação em que deseja impor uma ordem específica nas regras a serem chamadas, sem forçar a atualização do destino se uma dessas regras for executada. Nesse caso, você deseja definir os pré-requisitos somente do pedido. Os pré-requisitos somente do pedido podem ser especificados colocando um símbolo de barra vertical (|) na lista de pré-requisitos: quaisquer pré-requisitos à esquerda do símbolo de barra vertical são normais; quaisquer pré-requisitos à direita são apenas pedidos: alvos: pré-requisitos normais | pré-requisitos apenas de pedido
A seção de pré-requisitos normais pode, obviamente, estar vazia. Além disso, você ainda pode declarar várias linhas de pré-requisitos para o mesmo destino: eles são anexados apropriadamente. Observe que se você declarar o mesmo arquivo como um pré-requisito normal e somente de pedido, o pré-requisito normal terá precedência (uma vez que eles são um superconjunto estrito do comportamento de um pré-requisito somente de pedido).
Portanto, o makefile se torna
.PHONY : clearscr fresh clean all
all :
compile executable
clean :
rm -f *.o $(EXEC)
fresh : | clean clearscr all
clearscr:
clear
EDITAR 5 de dezembro
Não é grande coisa executar mais de uma instância de makefile, pois cada comando dentro da tarefa será um sub-shell de qualquer maneira. Mas você pode ter métodos reutilizáveis usando a função de chamada .
log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)
install:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
command1 # this line will be a subshell
command2 # this line will be another subshell
@command3 # Use `@` to hide the command line
$(call log_error, "It works, yey!")
uninstall:
@[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
....
$(call log_error, "Nuked!")
.PHONY :
é tratado como alguma palavra-chave que sempre é executada, enquanto os alvos não falsos são destinados a ser arquivos.