Как создать простой make-файл для gcc в Linux?

130

У меня есть три файла: program.c, program.hи headers.h.

program.cвключает program.hи headers.h.

Мне нужно скомпилировать это в Linux с помощью компилятора gcc . Я не знаю, как это сделать. Netbeans создал один для меня, но он пуст.

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

Ответы:

193

Интересно, что я не знал, что make по умолчанию будет использовать компилятор 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

(имейте в виду, что make требует табуляции вместо отступа пробела, поэтому обязательно исправьте это при копировании)

Однако для поддержки большего количества файлов 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), которые обычно встречаются в make-файлах. Если вам интересно это выяснить, я надеюсь, что дал вам хорошее начало.

Вот 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 и запустить программу?
user69514
куда бы вы добавили флаг openmp -fopenmp
MySchizoBuddy
1
Почему не использовать autoconf joey-adams?
Михал Гонда
7
Если кому-то интересно, почему перед ним черточки rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Тор Клингберг
25

Например, этого простого Makefile должно быть достаточно:

CC = GCC 
CFLAGS = -Wall

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

чистый:
    rm -f программа program.o
запустить: программа
    ./program

Обратите внимание, что <tab>на следующей строке после очистки и запуска должны быть пробелы, а не пробелы.

ОБНОВЛЕНИЕ Комментарии ниже применены

Вилиам
источник
@ user69514: makeбез аргументов обычно только строить свое программное обеспечение. Чтобы запустить его, либо используйте make run(доступно в этом ответе, но не обязательно во всех Makefiles), либо запустите его напрямую:./program
MestreLion
14
all: program
program.o: program.h headers.h

достаточно. остальное неявно

анонимный
источник
1
И если вся ваша программа представляет собой один .cфайл, program:необходим только его. Sweet :)
MestreLion
10

Самый простой make-файл может быть

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. Эта программа проверяет ваш текущий каталог и добавляет в конец make-файла зависимости заголовков для каждого файла .c / cpp. Это перебор, когда у вас есть 2 заголовка и один программный файл. Однако, если у вас есть 5+ маленьких тестовых программ и вы редактируете один из 10 заголовков, вы можете доверять make перестроить именно те программы, которые были изменены вашими модификациями.


источник