ฉันจะสร้าง makefile อย่างง่ายสำหรับ gcc บน Linux ได้อย่างไร


130

ฉันมีสามไฟล์: program.c, และprogram.hheaders.h

program.cรวมถึงและprogram.hheaders.h

ฉันต้องการคอมไพล์ไฟล์นี้บน Linux โดยใช้gcc compiler ฉันไม่แน่ใจว่าจะทำอย่างไร Netbeans สร้างขึ้นมาสำหรับฉัน แต่มันว่างเปล่า


1
มีวิธีแก้ปัญหา (และเอกสารที่ดี) ที่หรูหรามากที่spin.atomicobject.com 2016/08/26/makefile-c-projects
Casey

คำตอบ:


193

น่าสนใจฉันไม่ทราบว่าการเริ่มต้นจะใช้คอมไพเลอร์ C ที่กำหนดกฎเกี่ยวกับไฟล์ต้นฉบับ

อย่างไรก็ตามโซลูชันที่เรียบง่ายที่แสดงให้เห็นถึงแนวคิด Makefile ง่าย ๆ คือ:

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

(จำไว้ว่าต้องใช้แท็บแทนการเว้นวรรคเพื่อให้แน่ใจว่าได้แก้ไขเมื่อทำการคัดลอก)

อย่างไรก็ตามเพื่อรองรับไฟล์ C มากขึ้นคุณจะต้องสร้างกฎใหม่สำหรับแต่ละไฟล์ ดังนั้นเพื่อปรับปรุง:

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

ฉันพยายามทำให้สิ่งนี้เรียบง่ายที่สุดเท่าที่จะทำได้โดยละเว้นตัวแปรเช่น $ (CC) และ $ (CFLAGS) ที่มักจะเห็นใน makefiles หากคุณสนใจที่จะหาสิ่งนั้นฉันหวังว่าฉันจะให้คุณเริ่มต้นที่ดี

นี่คือ Makefile ที่ฉันชอบใช้สำหรับแหล่ง C อย่าลังเลที่จะใช้มัน:

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)

มันใช้คุณสมบัติ wildcard และ patsubst ของ make ยูทิลิตี้เพื่อรวมไฟล์. c และ. h ในไดเรกทอรีปัจจุบันโดยอัตโนมัติซึ่งหมายความว่าเมื่อคุณเพิ่มไฟล์รหัสใหม่ลงในไดเรกทอรีของคุณคุณจะไม่ต้องอัปเดต Makefile อย่างไรก็ตามหากคุณต้องการเปลี่ยนชื่อของไฟล์เรียกทำงานไลบรารีหรือคอมไพเลอร์ที่สร้างขึ้นคุณสามารถแก้ไขตัวแปรได้

ไม่ว่าในกรณีใดโปรดอย่าใช้ autoconf ฉันขอร้องคุณ! :)


7
เพื่อให้ถูกต้องทางเทคนิคฉันเชื่อว่าคุณควรใช้.PHONY: clean all defaultสำหรับเป้าหมายที่ตั้งใจจะใช้จากบรรทัดคำสั่ง นอกจากนี้ Autoconf / Automake ก็ไม่เลวเช่นกัน แน่นอนว่าพวกเขารู้สึกแย่และการชินกับมันเป็นเรื่องสนุกเหมือนบังคับหัวของคุณผ่านกำแพงอิฐ แต่พวกเขาทำงานและพัฒนาขึ้นมาอย่างดีและพวกเขาจะครอบคลุมฐานส่วนใหญ่ของคุณเท่าที่พกพาได้ และจะทำให้ชีวิตของคุณง่ายขึ้นมากในที่สุดเมื่อคุณคุ้นเคยกับการออกแบบที่น่ากลัว
คริสลัทซ์

ฉันเดาว่ามันใช้งานได้ แต่ฉันคิดว่าถ้าฉันพิมพ์ "ทำ" บนเทอร์มินัลโปรแกรมควรทำงาน นี่คือสิ่งที่ฉันได้รับ: gcc statsh.o -Wall -lm -o prog เป็นไปได้ไหมที่จะพิมพ์ make และรันโปรแกรม?
user69514

คุณจะเพิ่มธง openmp -fopenmp ที่ไหน
MySchizoBuddy

1
ทำไมไม่ใช้ autoconf joey-adams?
Michal Gonda

7
หากใครสงสัยว่าทำไมมีขีดกลางหน้าrm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg

25

ตัวอย่างเช่น Makefile แบบง่ายนี้ควรเพียงพอ:

CC = gcc 
CFLAGS = -Wall

ทั้งหมด: โปรแกรม
โปรแกรม: program.o
program.o: program.c program.h ส่วนหัว

สะอาด
    rm -f program program.o
รัน: โปรแกรม
    ./โปรแกรม

หมายเหตุจะต้อง<tab>อยู่ในบรรทัดถัดไปหลังจากล้างและเรียกใช้ไม่ใช่ที่ว่าง

อัปเดตความคิดเห็นด้านล่างที่ใช้


@ user69514: makeโดยไม่มีข้อโต้แย้งมักจะสร้างซอฟต์แวร์ของคุณ หากต้องการเรียกใช้ให้ใช้make run(มีอยู่ในคำตอบนี้ แต่ไม่จำเป็นในทุกMakefileๆ รายการ) หรือเรียกใช้โดยตรง:./program
MestreLion

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

ก็เพียงพอแล้ว ส่วนที่เหลือเป็นนัย


1
และหากโปรแกรมทั้งหมดของคุณเป็น.cไฟล์เดียวprogram:จำเป็นเท่านั้น หวาน :)
MestreLion

10

ไฟล์การสร้างที่ง่ายที่สุดสามารถเป็นได้

all : test

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

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

clean :
        rm test *.o

คุณสามารถเพิ่มรายละเอียดเพื่ออธิบายว่า Makefile ทำอะไรได้บ้าง
Federico

2
คุณสามารถไปได้ง่ายขึ้นมาก ดู @anonymous 1 liner
Mark Lakata

0

ขึ้นอยู่กับจำนวนส่วนหัวและพฤติกรรมการพัฒนาของคุณคุณอาจต้องการตรวจสอบ gccmakedep โปรแกรมนี้ตรวจสอบไดเรกทอรีปัจจุบันของคุณและเพิ่มในส่วนท้ายของ makefile ที่อ้างอิงส่วนหัวสำหรับแต่ละไฟล์. c / cpp นี่เป็น overkill เมื่อคุณมี 2 ส่วนหัวและหนึ่งไฟล์โปรแกรม อย่างไรก็ตามหากคุณมีโปรแกรมทดสอบเล็ก ๆ น้อย ๆ 5+ รายการและคุณกำลังแก้ไขหนึ่งใน 10 ส่วนหัวคุณสามารถเชื่อถือได้ที่จะสร้างใหม่แน่นอนโปรแกรมเหล่านั้นซึ่งมีการเปลี่ยนแปลงโดยการปรับเปลี่ยนของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.