Bagaimana cara membuat makefile sederhana untuk gcc di Linux?

130

Saya memiliki tiga file: program.c, program.hdan headers.h.

program.ctermasuk program.hdan headers.h.

Saya perlu mengkompilasi ini di Linux menggunakan kompiler gcc . Saya tidak yakin bagaimana melakukan ini. Netbeans membuatkan untuk saya, tapi itu kosong.

pengguna69514
sumber
1
Ada solusi yang sangat elegan (dan didokumentasikan dengan baik) di spin.atomicobject.com/2016/08/26/makefile-c-projects .
Casey

Jawaban:

193

Menarik, saya tidak tahu make default menggunakan kompiler C yang diberikan aturan tentang file sumber.

Bagaimanapun, solusi sederhana yang menunjukkan konsep Makefile sederhana adalah:

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

(ingatlah bahwa membuat memerlukan tab alih-alih lekukan ruang, jadi pastikan untuk memperbaikinya saat menyalin)

Namun, untuk mendukung lebih banyak file C, Anda harus membuat aturan baru untuk masing-masing file tersebut. Jadi, untuk meningkatkan:

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

Saya mencoba membuat ini sesederhana mungkin dengan menghilangkan variabel seperti $ (CC) dan $ (CFLAGS) yang biasanya terlihat di makefiles. Jika Anda tertarik untuk mencari tahu, saya harap saya sudah memberi Anda awal yang baik untuk itu.

Inilah Makefile yang saya suka gunakan untuk sumber C. Jangan ragu untuk menggunakannya:

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)

Ia menggunakan fitur wildcard dan patsubst dari make utility untuk secara otomatis memasukkan file .c dan .h dalam direktori saat ini, artinya ketika Anda menambahkan file kode baru ke direktori Anda, Anda tidak perlu memperbarui Makefile. Namun, jika Anda ingin mengubah nama executable, libraries, atau flag compiler yang dihasilkan, Anda bisa memodifikasi variabel.

Dalam kedua kasus, tolong jangan gunakan autoconf. Aku memohon Anda! :)

Joey Adams
sumber
7
Agar benar secara teknis, saya percaya Anda harus menggunakan .PHONY: clean all defaultuntuk target-target yang dimaksudkan untuk digunakan dari baris perintah. Juga, Autoconf / Automake tidak seburuk itu. Tentu, mereka merasa tidak enak, dan membiasakan diri dengan mereka sama menyenangkannya dengan memaksa kepala Anda melalui dinding bata, tetapi mereka berhasil, dan mereka berkembang dengan baik, dan mereka akan mencakup sebagian besar pangkalan Anda sejauh portabilitas, dan akan membuat hidup Anda jauh lebih mudah pada akhirnya setelah Anda terbiasa dengan desain mereka yang buruk.
Chris Lutz
Saya kira ini berhasil, tapi saya pikir jika saya mengetik "make" di terminal program harus dijalankan. Inilah yang saya dapatkan: gcc statsh.o -Wall -lm -o prog Apakah mungkin untuk mengetik dan membuat program?
user69514
di mana Anda akan menambahkan flag openmp -fopenmp
MySchizoBuddy
1
Mengapa tidak menggunakan autoconf joey-adams?
Michal Gonda
7
Jika ada yang bertanya-tanya mengapa ada garis putus-putus di depan rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg
25

Misalnya Makefile sederhana ini sudah cukup:

CC = gcc 
CFLAGS = -Dinding

semua: program
program: program.o
program.o: program.c program.h header.h

bersih:
    rm -f program program.o
jalankan program
    ./program

Perhatikan harus ada <tab>di baris berikutnya setelah bersih dan berjalan, bukan spasi.

UPDATE Komentar di bawah ini berlaku

Viliam
sumber
@ user69514: maketanpa argumen biasanya hanya membangun perangkat lunak Anda. Untuk menjalankannya, gunakan make run(tersedia dalam jawaban ini, tetapi tidak harus dalam semua Makefiles), atau jalankan langsung:./program
MestreLion
14
all: program
program.o: program.h headers.h

cukup. sisanya tersirat

anonim
sumber
1
Dan jika seluruh program Anda adalah satu .cfile, hanya program:diperlukan. Manis :)
MestreLion
10

File make yang paling sederhana bisa

all : test

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

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

clean :
        rm test *.o
Indrakumar
sumber
Anda dapat menambahkan lebih detail untuk menjelaskan apa yang dilakukan Makefile Anda
Federico
2
Anda sebenarnya bisa jauh lebih sederhana. lihat @anonymous 1 liner
Mark Lakata
0

Bergantung pada jumlah tajuk dan kebiasaan pengembangan Anda, Anda mungkin ingin menyelidiki gccmakedep. Program ini memeriksa direktori Anda saat ini dan menambahkan ke akhir makefile dependensi header untuk setiap file .c / cpp. Ini berlebihan jika Anda memiliki 2 header dan satu file program. Namun, jika Anda memiliki 5+ program pengujian kecil dan Anda mengedit satu dari 10 header, Anda kemudian dapat mempercayai untuk membangun kembali program-program yang diubah oleh modifikasi Anda.


sumber