make: Nada a ser feito para `todos '

97

Estou passando por um pgm, por exemplo, para criar um arquivo make.

http://mrbook.org/tutorials/make/

Minha pasta eg_make_creation contém os seguintes arquivos,

desktop:~/eg_make_creation$ ls
factorial.c  functions.h  hello  hello.c  main.c  Makefile

Makefile

# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall

all:hello

hello:main.o factorial.o hello.o
  $(CC) main.o factorial.o hello.o -o hello

main.o:main.c
  $(CC) $(CFLAGS) main.c

factorial.o:factorial.c
  $(CC) $(CFLAGS) factorial.c

hello.o:hello.c
  $(CC) $(CFLAGS) hello.c

clean:
  rm -rf *o hello

erro:

desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.

Por favor me ajude a entender como compilar este programa.

Angus
fonte
12
Tente fazer um "make clean" seguido por um "make all"
Paul R
11
Isso não é um erro, apenas significa que helloestá atualizado. Mude cleanpara rm -f *.o helloantes de fazer algo inesperado, depois execute make clean alle veja se funciona.
Mat
1
Você também deve adicionar .phony: all clean, uma vez que alle cleannão são nomes de arquivo.
Kerrek SB
3
Não coloque o -c em seus CFLAGS.
wildplasser

Respostas:

121

Às vezes, o erro "Nada a fazer para todos" pode ser causado por espaços antes do comando na regra makefile em vez de tab. Certifique-se de usar tabulações em vez de espaços dentro de suas regras.

all:
<\t>$(CC) $(CFLAGS) ...

ao invés de

all:
    $(CC) $(CFLAGS) ...

Por favor, consulte o GNU make manual para a descrição da sintaxe da regra: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax

VirtualVDX
fonte
obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) módulos limpos: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Narendra Jaggi
o arquivo acima é um arquivo válido ??
Narendra Jaggi
No contexto de makefiles pai-filho, às vezes o erro "Nada a ser feito para todos" pode ser causado por alvos filhos sendo incorretamente marcados como declarados .PHONY no Makefile pai.
donhector
Eu tinha all : src/server/mod_wsgi.la, e mudei para all : </t> src/server/mod_wsgi.la. Agora recebo o erro: make: execvp: src/server/mod_wsgi.la: Permission denied Makefile:29: recipe for target 'all' failed make: *** [all] Error 127depois sudo make. Qualquer ajuda?
Mooncrater
@Mooncrater Consulte gnu.org/software/make/manual/make.html#Rule-Syntax . Aqui se lê: As linhas da receita começam com um caractere de tabulação (ou o primeiro caractere no valor da variável .RECIPEPREFIX; consulte Variáveis ​​Especiais). A primeira linha da receita pode aparecer na linha após os pré-requisitos, com um caractere de tabulação, ou pode aparecer na mesma linha, com um ponto e vírgula. De qualquer maneira, o efeito é o mesmo. Então, seu pré-requisito simplesmente se tornou a receita. Você não precisa de guia neste caso.
VirtualVDX de
31

Remova o helloarquivo de sua pasta e tente novamente.

O allalvo depende do helloalvo. O hellodestino primeiro tenta encontrar o arquivo correspondente no sistema de arquivos. Se ele encontrar e estiver atualizado com os arquivos dependentes, não há nada a fazer.

semana
fonte
obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) módulos limpos: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Narendra Jaggi
o acima é um arquivo make válido?
Narendra Jaggi
21

Quando você apenas dá make, ele cria a primeira regra em seu makefile, ou seja, "all". Você especificou que "all" depende de "hello", que depende de main.o, factorial.o e hello.o. Portanto, 'make' tenta ver se esses arquivos estão presentes.

Se eles estiverem presentes, 'make' vê se suas dependências, por exemplo, main.o tem uma dependência main.c, foram alteradas. Se eles mudaram, o make reconstrói, senão pula a regra. Da mesma forma, ele continua construindo recursivamente os arquivos que foram alterados e finalmente executa o comando principal, "all" no seu caso para fornecer um executável, 'hello' no seu caso.

Se eles não estiverem presentes, faça cegamente constrói tudo sob a regra.

Voltando ao seu problema, não é um erro, mas 'make' está dizendo que todas as dependências em seu makefile estão atualizadas e não é necessário fazer nada!

Chethan Ravindranath
fonte
16

Make está se comportando corretamente. hellojá existe e não é mais antigo que os .carquivos e, portanto, não há mais trabalho a ser feito. Existem quatro cenários em que o make precisará (re) construir:

  • Se você modificar um de seus .carquivos, ele será mais recente do que helloe terá que ser reconstruído ao executar make.
  • Se você deletar hello, obviamente terá que reconstruí-lo
  • Você pode forçar o make a reconstruir tudo com a -Bopção.make -B all
  • make clean allirá deletar helloe requerer uma reconstrução. (Eu sugiro que você dê uma olhada no comentário de @Mat sobrerm -f *.o hello
Aaron McDaid
fonte
4

Acho que você perdeu uma guia na 9ª linha. A linha após all: hello deve ser uma guia em branco. Certifique-se de ter uma guia em branco na 9ª linha. Isso fará com que o interpretador entenda que você deseja usar a receita padrão para makefile.

Techie
fonte
4

Isso não é um erro; o comando make no unix funciona com base nos carimbos de data / hora. Ou seja, digamos que você tenha feito certas alterações factorial.cppe compilado usando o makemake mostra a informação de que apenas o cc -o factorial.cppcomando é executado. Da próxima vez, se você executar o mesmo comando, ou seja, makesem fazer nenhuma alteração em nenhum arquivo com .cppextensão, o compilador diz que o arquivo de saída está atualizado. O compilador fornece essas informações até que façamos certas alterações em qualquer um file.cpp.

A vantagem do makefileé que ele reduz o tempo de recompilação, compilando os únicos arquivos que são modificados e usando os .oarquivos object ( ) dos arquivos não modificados diretamente.

Muneshwar
fonte
0

Cheguei a esse erro peculiar e difícil de depurar por um caminho diferente. Meu problema acabou sendo que eu estava usando uma regra de padrão em uma etapa de compilação quando o destino e a dependência estavam localizados em diretórios distintos. Algo assim:

foo/apple.o: bar/apple.c $(FOODEPS)

%.o: %.c
    $(CC) $< -o $@

Eu tinha várias dependências configuradas dessa forma e estava tentando usar uma receita de padrão para todas elas. Claramente, uma única substituição para "%" não vai funcionar aqui. Fiz regras explícitas para cada dependência e me vi de volta entre os cachorros e unicórnios!

foo/apple.o: bar/apple.c $(FOODEPS)
    $(CC) $< -o $@

Espero que isso ajude alguém!

Sfaleron
fonte