Làm cách nào để tạo một tệp tạo tệp đơn giản cho gcc trên Linux?


130

Tôi có ba tác phẩm: program.c, program.hheaders.h.

program.cbao gồm program.hheaders.h.

Tôi cần biên dịch cái này trên Linux bằng trình biên dịch gcc . Tôi không chắc làm thế nào để làm điều này. Netbeans đã tạo một cái cho tôi, nhưng nó trống rỗng.


1
Có một giải pháp cực kỳ thanh lịch (và được ghi chép đầy đủ) tại spin.atomicobject.com/2016/08/26/makefile-c-projects .
Casey

Câu trả lời:


193

Thật thú vị, tôi không biết make sẽ mặc định sử dụng trình biên dịch C đưa ra các quy tắc liên quan đến các tệp nguồn.

Dù sao, một giải pháp đơn giản thể hiện các khái niệm Makefile đơn giản sẽ là:

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

(lưu ý rằng thực hiện yêu cầu tab thay vì thụt lề không gian, vì vậy hãy chắc chắn khắc phục điều đó khi sao chép)

Tuy nhiên, để hỗ trợ nhiều tệp C hơn, bạn phải tạo quy tắc mới cho mỗi tệp. Do đó, để cải thiện:

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

Tôi đã cố gắng làm điều này đơn giản nhất có thể bằng cách bỏ qua các biến như $ (CC) và $ (CFLAGS) thường thấy trong tệp tạo tệp. Nếu bạn quan tâm đến việc tìm ra điều đó, tôi hy vọng tôi đã cho bạn một khởi đầu tốt về điều đó.

Đây là Makefile tôi muốn sử dụng cho nguồn C. Hãy sử dụng nó:

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)

Nó sử dụng các tính năng ký tự đại diện và patsubst của tiện ích make để tự động bao gồm các tệp .c và .h trong thư mục hiện tại, nghĩa là khi bạn thêm các tệp mã mới vào thư mục của mình, bạn sẽ không phải cập nhật Makefile. Tuy nhiên, nếu bạn muốn thay đổi tên của các cờ thực thi, thư viện hoặc trình biên dịch được tạo, bạn chỉ có thể sửa đổi các biến.

Trong cả hai trường hợp, đừng sử dụng autoconf. Tôi đang cầu xin bạn! :)


7
Để chính xác về mặt kỹ thuật, tôi tin rằng bạn nên sử dụng .PHONY: clean all defaultcho những mục tiêu được sử dụng từ dòng lệnh. Ngoài ra, Autoconf / Automake không tệ đến thế. Chắc chắn, họ cảm thấy khủng khiếp, và làm quen với họ cũng thú vị như việc buộc đầu bạn qua một bức tường gạch, nhưng họ làm việc, và họ phát triển tốt, và họ sẽ bao quát hầu hết các căn cứ của bạn về tính di động, và cuối cùng sẽ làm cho cuộc sống của bạn dễ dàng hơn rất nhiều khi bạn đã quen với thiết kế khủng khiếp của họ.
Chris Lutz

Tôi đoán điều này hoạt động, nhưng tôi nghĩ nếu tôi gõ "make" trên thiết bị đầu cuối thì chương trình sẽ chạy. Đây là những gì tôi nhận được: gcc statsh.o -Wall -lm -o prog Có thể chỉ cần gõ make và thực hiện chương trình không?
dùng69514

nơi bạn sẽ thêm cờ openmp -fopenmp
MySchizoBuddy

1
Tại sao không sử dụng autoconf joey-adams?
Michal Gonda

7
Nếu có ai thắc mắc tại sao lại có dấu gạch ngang phía trước rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg

25

Ví dụ, Makefile đơn giản này phải đủ:

CC = gcc 
CFLAGS = -Wall

tất cả: chương trình
chương trình: chương trình
chương trình.o: chương trình.c chương trình.h tiêu đề.h

dọn dẹp:
    chương trình rm -f chương trình.o
chạy chương trình
    ./chương trình

Lưu ý phải có <tab>trên dòng tiếp theo sau khi sạch và chạy, không phải khoảng trắng.

CẬP NHẬT Ý kiến ​​dưới đây được áp dụng


@ user69514: makekhông có đối số thường chỉ xây dựng phần mềm của bạn. Để chạy nó, hãy sử dụng make run(có sẵn trong câu trả lời này, nhưng không nhất thiết phải trong tất cả các Makefiles) hoặc chạy trực tiếp:./program
MestreLion

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

Là đủ. phần còn lại là ngầm


1
Và nếu toàn bộ chương trình của bạn là một .ctệp duy nhất , chỉ program:cần thiết. Ngọt ngào :)
MestreLion

10

Các tập tin đơn giản nhất có thể là

all : test

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

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

clean :
        rm test *.o

bạn có thể thêm chi tiết để giải thích Makefile của bạn làm gì
Federico

2
bạn thực sự có thể đi đơn giản hơn rất nhiều. xem @anonymous 1 liner
Mark Lakata

0

Tùy thuộc vào số lượng tiêu đề và thói quen phát triển của bạn, bạn có thể muốn điều tra gccmakenep. Chương trình này kiểm tra thư mục hiện tại của bạn và thêm vào cuối makefile các phụ thuộc tiêu đề cho mỗi tệp .c / cpp. Điều này là quá mức khi bạn có 2 tiêu đề và một tệp chương trình. Tuy nhiên, nếu bạn có hơn 5 chương trình thử nghiệm nhỏ và bạn đang chỉnh sửa một trong 10 tiêu đề, thì bạn có thể tin tưởng thực hiện để xây dựng lại chính xác những chương trình đã được thay đổi bởi các sửa đổi của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.