Як зробити простий makefile для gcc в Linux?


130

У мене є три файли: program.c, program.hі headers.h.

program.cвключає program.hі headers.h.

Мені потрібно скомпілювати це в Linux за допомогою компілятора gcc . Я не впевнений, як це зробити. Netbeans створили один для мене, але він порожній.


1
На сайті spin.atomicobject.com/2016/08/26/makefile-c-projects є надзвичайно елегантне (і добре задокументоване) рішення .
Кейсі

Відповіді:


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)

Він використовує символи підстановки та patsubst утиліти make для автоматичного включення .c та .h файлів у поточний каталог, тобто коли ви додаєте нові файли коду до свого каталогу, вам не доведеться оновлювати Makefile. Однак якщо ви хочете змінити ім'я створених виконуваних файлів, бібліотек або прапорців компілятора, ви можете просто змінити змінні.

В будь-якому випадку не використовуйте autoconf, будь ласка. Я тебе благаю! :)


7
Щоб бути технічно правильним, я вважаю, що ви повинні використовувати .PHONY: clean all defaultдля тих цілей, які призначені для використання з командного рядка. Крім того, Autoconf / Automake не так вже й погано. Звичайно, вони відчувають себе жахливо, і звикати до них - це так само весело, як змусити голову через цегляну стіну, але вони працюють, і вони добре розвинені, і вони покриють більшість ваших баз настільки портативними, і, нарешті, полегшить ваше життя, як тільки ви звикнете до їх жахливого дизайну.
Кріс Лютз

Я думаю, це працює, але я подумав, що якщо я набрав "make" на терміналі, програма повинна запуститися. Ось що я отримую: gcc statsh.o -Wall -lm -o prog Чи можна просто ввести програму make and Execute?
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 = -Стінка

все: програма
програма: program.o
program.o: program.c program.h headers.h

чисто:
    rm -f program program.o
run: програма
    ./програма

Зауважте, що <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
Федеріко

2
ви насправді можете піти набагато простіше. дивіться @anonymous 1 лайнер
Марк Лаката

0

Залежно від кількості заголовків та ваших звичок розвитку, можливо, ви захочете дослідити gccmakedep. Ця програма вивчає ваш поточний каталог і додає до кінця makefile залежності заголовка для кожного .c / cpp-файлу. Це зайвий рівень, коли у вас є 2 заголовки та один програмний файл. Однак якщо у вас є 5+ невеликих тестових програм і ви редагуєте одне з 10 заголовків, то можете довіритися зробити, щоб відновити саме ті програми, які були змінені вашими змінами.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.