Come faccio a creare un semplice makefile per gcc su Linux?


130

Ho tre file: program.c, program.he headers.h.

program.cinclude program.he headers.h.

Devo compilare questo su Linux usando il compilatore gcc . Non sono sicuro di come farlo. Netbeans ne ha creato uno per me, ma è vuoto.


1
Esiste una soluzione estremamente elegante (e ben documentata) su spin.atomicobject.com/2016/08/26/makefile-c-projects .
Casey,

Risposte:


193

Interessante, non sapevo che renderebbe predefinito l'uso del compilatore C date le regole relative ai file di origine.

Ad ogni modo, una semplice soluzione che dimostra semplici concetti di Makefile sarebbe:

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

(tieni presente che make richiede tab invece di rientro dello spazio, quindi assicurati di risolverlo durante la copia)

Tuttavia, per supportare più file C, dovresti creare nuove regole per ciascuno di essi. Pertanto, per migliorare:

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

Ho cercato di renderlo il più semplice possibile omettendo variabili come $ (CC) e $ (CFLAGS) che di solito si vedono nei makefile. Se sei interessato a capirlo, spero di averti dato un buon inizio.

Ecco il Makefile che mi piace usare per l'origine C. Sentiti libero di usarlo:

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)

Utilizza le funzioni jolly e patsubst dell'utility make per includere automaticamente i file .c e .h nella directory corrente, il che significa che quando aggiungi nuovi file di codice alla tua directory, non dovrai aggiornare il Makefile. Tuttavia, se si desidera modificare il nome dell'eseguibile, delle librerie o dei flag del compilatore generati, è possibile modificare le variabili.

In entrambi i casi, non utilizzare autoconf, per favore. Ti sto implorando! :)


7
Per essere tecnicamente corretto, credo che dovresti usare .PHONY: clean all defaultper quegli obiettivi che dovrebbero essere usati dalla riga di comando. Inoltre, Autoconf / Automake non sono poi così male. Certo, si sentono male e abituarsi a loro è divertente quanto forzare la testa attraverso un muro di mattoni, ma funzionano, sono ben sviluppati e copriranno la maggior parte delle tue basi per quanto riguarda la portabilità, e ti renderà la vita molto più semplice alla fine una volta che ti sarai abituato al loro design orribile.
Chris Lutz,

Immagino che funzioni, ma ho pensato che se avessi digitato "make" sul terminale il programma dovrebbe essere eseguito. Questo è quello che ottengo: gcc statsh.o -Wall -lm -o prog È possibile semplicemente digitare make ed eseguire il programma?
user69514,

dove aggiungeresti la bandiera openmp -fopenmp
MySchizoBuddy

1
Perché non usare autoconf joey-adams?
Michal Gonda,

7
Se qualcuno si chiede perché ci siano trattini di fronte a rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg

25

Ad esempio questo semplice Makefile dovrebbe essere sufficiente:

CC = gcc 
CFLAGS = -Wall

tutto: programma
programma: program.o
program.o: program.c program.h headers.h

pulito:
    rm -f program program.o
eseguire il programma
    ./programma

Nota che ci deve essere <tab>nella riga successiva dopo clean and run, non spazi.

AGGIORNAMENTO Commenti di seguito applicati


@ user69514: makedi solito senza argomenti costruisci solo il tuo software. Per eseguirlo, utilizzare make run(disponibile in questa risposta, ma non necessariamente in tutti Makefilei), oppure eseguirlo direttamente:./program
MestreLion

14
all: program
program.o: program.h headers.h

è abbastanza. il resto è implicito


1
E se l'intero programma è un singolo .cfile, program:è necessario solo . Dolce :)
MestreLion il

10

Il file make più semplice può essere

all : test

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

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

clean :
        rm test *.o

puoi aggiungere maggiori dettagli per spiegare cosa fa il tuo Makefile
Federico

2
puoi effettivamente andare molto più semplice. vedi @anonym 1 liner
Mark Lakata,

0

A seconda del numero di intestazioni e delle tue abitudini di sviluppo, potresti voler esaminare gccmakedep. Questo programma esamina la directory corrente e aggiunge alla fine del makefile le dipendenze dell'intestazione per ogni file .c / cpp. Questo è eccessivo quando hai 2 intestazioni e un file di programma. Tuttavia, se hai 5+ piccoli programmi di test e stai modificando una delle 10 intestazioni, puoi fare affidamento su make per ricostruire esattamente quei programmi che sono stati modificati dalle tue modifiche.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.