Aqui está o meu Makefile simples:
#create an exe file
run: link
gcc link.o -o run
#sketch link.o
link.o: main.o sum.o
ld -r main.o sum.o -o link.o
#sketch main.o
main.o: main.c
gcc -c main.c -o main.o
#sketch sum.o
sum.o: sum.c
gcc -c sum.c -o sum.o
#make clean recipie
clean:
rm *.o
rm run
Esse makefile pode ser algo meio imaturo ou fraco. Mas minha real preocupação é com o processo que o alvo está sendo atingido. Antes de contar a pergunta real, vamos primeiro ver sua saída.
gcc -c main.c -o main.o
gcc -c sum.c -o sum.o
ld -r main.o sum.o -o link.o
cc link.o -o link
gcc link.o -o run
Minha pergunta é: isso é por causa da link
dependência run
ou por causa da link.o
menção na seção de comando de run
, make
o comando procura link.o
e novamente é por causa main.o
sum.o
das dependências dele link.o
procura por dependências de menção ou por causa main.o
sum.o
da seção de comando e o primeiro comando no destino main.o
é encontrados e sum.o
e link.o
respectivamente? É por causa do arquivo mencionado nas dependências ou menção do arquivo no comando?
Esta é provavelmente uma duplicata de sua pergunta anterior, O que realmente está causando o problema 'O sistema não consegue encontrar o arquivo especificado' no make? , mas vamos usar este para explicar em detalhes o que está acontecendo.
Make leva suas declarações Makefile literalmente:
run: link
diz querun
precisalink
, e a receita associada diz que para criarrun
, ele deve executargcc link.o -o run
link.o: main.o sum.o
diz quelink.o
precisamain.o
esum.o
, e a receita associada diz que para criarlink.o
, ele deve executarld -r main.o sum.o -o link.o
main.o: main.c
diz quemain.o
precisamain.c
, e a receita associada diz que para criarmain.o
, ele deve executargcc -c main.c -o main.o
sum.o: sum.c
faz o mesmo parasum.c
esum.o
Quando você corre
Faça tentativas para satisfazer o primeiro destino no Makefile,
run
. Ele vê que não hálink
arquivo e não há regra em seu Makefile que especifique como construir arquivoslink
. No entanto, Make “sabe” como construir um arquivo sem extensão a partir de um.o
arquivo , então ele usa essa regra interna para construirlink
; que resolveque é
cc
de onde vem o comando (a rigor, é o valor padrão da$(CC)
variável Make).Uma vez
link
disponível, o Make considera que os pré-requisitosrun
foram atendidos e executa a receita correspondente:Note que
link
não é realmente usado aqui. Isso apenas confunde as coisas; você deve escrever a primeira regra comoDetalhadamente, Make resolve
run
da seguinte forma:run
precisalink
link
não tem regra explícita, mas pode ser construída usando a regra interna delink.o
link.o
necessidadesmain.o
esum.o
main.o
necessidadesmain.c
, que existesum.o
necessidadessum.c
, que existeOs pré-requisitos agora estão resolvidos e o Make pode executar as receitas:
gcc -c main.o -o main.o
construirmain.o
gcc -c sum.c -o sum.o
construirsum.o
ld -r main.o sum.o -o link.o
construirlink.o
cc link.o -o link
construirlink
gcc link.o -o run
construirrun
Se você reescrever a
run
regra comorun: link.o
, a resolução muda pararun
precisalink.o
link.o
necessidadesmain.o
esum.o
main.o
necessidadesmain.c
, que existesum.o
necessidadessum.c
, que existee a construção para
gcc -c main.o -o main.o
construirmain.o
gcc -c sum.c -o sum.o
construirsum.o
ld -r main.o sum.o -o link.o
construirlink.o
gcc link.o -o run
construirrun