Como faço para criar um makefile simples para o gcc no Linux?

130

Eu tenho três arquivos: program.c, program.he headers.h.

program.cinclui program.he headers.h.

Eu preciso compilar isso no Linux usando o compilador gcc . Não tenho certeza de como fazer isso. O Netbeans criou um para mim, mas está vazio.

user69514
fonte
1
Existe uma solução extremamente elegante (e bem documentada) em spin.atomicobject.com/2016/08/26/makefile-c-projects .
Casey

Respostas:

193

Interessante, eu não sabia que o make padrão seria usar o compilador C, dadas as regras relativas aos arquivos de origem.

De qualquer forma, uma solução simples que demonstre conceitos simples do Makefile seria:

HEADERS = program.h headers.h

default: program

program.o: program.c $(HEADERS)
    gcc -c program.c -o program.o

program: program.o
    gcc program.o -o program

clean:
    -rm -f program.o
    -rm -f program

(lembre-se de que make exige tabulação, em vez de recuo de espaço, verifique isso ao copiar)

No entanto, para oferecer suporte a mais arquivos C, você precisará criar novas regras para cada um deles. Assim, para melhorar:

HEADERS = program.h headers.h
OBJECTS = program.o

default: program

%.o: %.c $(HEADERS)
    gcc -c $< -o $@

program: $(OBJECTS)
    gcc $(OBJECTS) -o $@

clean:
    -rm -f $(OBJECTS)
    -rm -f program

Tentei tornar isso o mais simples possível, omitindo variáveis ​​como $ (CC) e $ (CFLAGS) que geralmente são vistas em makefiles. Se você estiver interessado em descobrir isso, espero ter lhe dado um bom começo nisso.

Aqui está o Makefile que eu gosto de usar para fonte C. Sinta-se livre para usá-lo:

TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)

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

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f *.o
    -rm -f $(TARGET)

Ele usa os recursos curinga e patsubst do utilitário make para incluir automaticamente arquivos .c e .h no diretório atual, ou seja, quando você adiciona novos arquivos de código ao seu diretório, não precisa atualizar o Makefile. No entanto, se você quiser alterar o nome dos executáveis, bibliotecas ou sinalizadores do compilador gerados, basta modificar as variáveis.

Nos dois casos, não use o autoconf, por favor. Eu estou te implorando! :)

Joey Adams
fonte
7
Para ser tecnicamente correto, acredito que você deve usar .PHONY: clean all defaultpara os destinos que devem ser usados ​​na linha de comando. Além disso, o Autoconf / Automake não é tão ruim assim. Claro, eles se sentem horríveis, e se acostumar com eles é tão divertido quanto forçar sua cabeça a atravessar uma parede de tijolos, mas eles funcionam, e são bem desenvolvidos, e cobrem a maior parte de suas bases até a portabilidade, e facilitará sua vida muito depois que você se acostumar com o design horrível deles.
28711 Chris Lutz
Eu acho que isso funciona, mas pensei que se eu digitasse "make" no terminal, o programa deveria ser executado. É isso que eu recebo: gcc statsh.o -Wall -lm -o prog É possível apenas digitar make e executar o programa?
user69514
onde você adicionar o -fopenmp bandeira OpenMP
MySchizoBuddy
1
Por que não usar autoconf joey-adams?
Michal Gonda
7
Se alguém perguntar por que existem traços em frente rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg
25

Por exemplo, este Makefile simples deve ser suficiente:

CC = gcc 
CFLAGS = -Wall

tudo: programa
program: program.o
program.o: program.c program.h headers.h

limpar \ limpo:
    rm -f program program.o
rodar programa
    ./programa

Observe que deve haver <tab>na próxima linha após a limpeza e execução, não espaços.

ATUALIZAÇÃO Comentários abaixo aplicados

Viliam
fonte
@ user69514: makesem argumentos geralmente constrói apenas seu software. Para executá-lo, use make run(disponível nesta resposta, mas não necessariamente em todos os Makefiles) ou execute-o diretamente:./program
MestreLion
14
all: program
program.o: program.h headers.h

basta. o resto está implícito

anônimo
fonte
1
E se todo o seu programa for um único .carquivo, apenas program:será necessário. Doce :)
MestreLion
10

O arquivo make mais simples pode ser

all : test

test : test.o
        gcc -o test test.o 

test.o : test.c
        gcc -c test.c

clean :
        rm test *.o
Indrakumar
fonte
você pode adicionar mais detalhes para explicar o que o seu Makefile faz
Federico
2
você pode realmente ser muito mais simples. Veja @anonymous 1 liner
Mark Lakata
0

Dependendo do número de cabeçalhos e de seus hábitos de desenvolvimento, convém investigar o gccmakedep. Este programa examina seu diretório atual e adiciona ao final do makefile as dependências do cabeçalho para cada arquivo .c / cpp. Isso é um exagero quando você tem 2 cabeçalhos e um arquivo de programa. No entanto, se você tiver mais de 5 pequenos programas de teste e estiver editando um dos 10 cabeçalhos, poderá confiar no make para reconstruir exatamente os programas que foram alterados pelas suas modificações.


fonte