Makefile с несколькими исполняемыми файлами
Я пытаюсь написать make-файл, который использует макросы для создания нескольких исполняемых файлов из нескольких файлов одновременно. Я попытался найти ответы на ранее отвеченные вопросы, но, поскольку я довольно новичок в программировании на C, а также в работе с gcc, я не смог найти ответ на свой вопрос.
Вот что у меня так далеко:
CC=gcc
CFLAGS=-I.
OBJ = ex1.c ex3.c
EXECUTABLE = ex1 ex3
$(EXECUTABLE): $(OBJ)
gcc -o $@ $^ $(CFLAGS)
clean:
rm -f $(EXECUTABLE)
Я бы хотел линию
$(EXECUTABLE): $(OBJ)
создать исполняемые файлы ex1 и ex3 из файлов ex1.c ex3.c соответственно.
4 ответа
Для этого конкретного случая, где каждый исполняемый файл имеет один исходный файл с .c
расширение, все, что вам нужно, это одна строка Makefile:
all: ex1 ex3
Встроенные правила по умолчанию для make
тогда работай уже
$ make
cc -O2 -pipe ex1.c -o ex1
cc -O2 -pipe ex3.c -o ex3
За кулисами, make
использует обязательное встроенное правило POSIXly с одним суффиксом
.c:
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
Измените команду по своему вкусу с make CC=gcc CFLAGS=-O2 LDFLAGS=-s
и тому подобное.
Пустяки дня: на самом деле, если вы хотите назвать цели при вызове make
Вы можете использовать пустой или даже запустить без Makefile:
$ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
$ rm -f Makefile ex1 ex3
$ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c -o ex1
gcc -O2 -s ex3.c -o ex3
Сделай магию!
Как правило, не изобретайте велосипед (или правила), используйте правила, которые уже есть. Это упростит вашу жизнь и сделает ее намного проще. Это делает маленькие и сексуальные makefiles впечатляющими дам:-)
Некоторые предложения (если вы используете GNU make, а не что-то другое)
Сначала беги один раз make -p
, вы поймете, что такое встроенные правила make
зная. Ищите, в частности, для COMPILE.c
а также LINK.c
Тогда я предлагаю
CFLAGS= -g -Wall -I.
(потому что вы действительно хотите -g
для отладки и -Wall
чтобы получить большинство предупреждений)
И вам, вероятно, не нужно
$(EXECUTABLE): $(OBJ)
gcc -o $@ $^ $(CFLAGS)
Тем не менее, я предлагаю добавить перед большинством других правил
.PHONY: all clean
all: $(EXECUTABLES)
На самом деле, я бы код вашей Makefile
(для GNU make
!) следующим образом
# file Makefile
CC= gcc
RM= rm -vf
CFLAGS= -Wall -g
CPPFLAGS= -I.
SRCFILES= ex1.c ex2.c ## or perhaps $(wildcard *.c)
OBJFILES= $(patsubst %.c, %.o, $(SRCFILES))
PROGFILES= $(patsubst %.c, %, $(SRCFILES))
.PHONY: all clean
all: $(PROGFILES)
clean:
$(RM) $(OBJFILES) $(PROGFILES) *~
## eof Makefile
Помните, что вкладка является значимым символом в Makefile
-s (часть действия правил). В этом ответе строки, начинающиеся как минимум с четырех пробелов, должны начинаться с символа табуляции.
Как только все отлажено, рассмотрите возможность запуска make clean
очистить все, а затем make -j CFLAGS=-O2 all
скомпилировать все параллельно с оптимизацией.
Наконец, я рекомендую использовать remake
и работает remake -x
отлаживать комплекс Makefile
-s
Конечно, я предполагаю, что в вашем каталоге есть только однофайловые программы.
Кстати, есть другие программы для строителей. Возможно, вы могли бы рассмотреть omake
Не забудьте использовать систему контроля версий, такую как git, для ваших исходных файлов. Настало время освоить такой инструмент.
Следующий ответ включает несколько исполняемых файлов, таких как initiate, process1, process2, ..., process4.
LOCAL_INCLUDE=./
all: clean process_first process_second init
process_first:
gcc -g -o process1 -I$(LOCAL_INCLUDE) process1.c -lzmq -L. -L./.
gcc -g -o process2 -I$(LOCAL_INCLUDE) process2.c -lzmq -L. -L./.
process_second:
gcc -g -o process3 -I$(LOCAL_INCLUDE) process3.c -lzmq -L. -L./.
gcc -g -o process4 -I$(LOCAL_INCLUDE) process4.c -lzmq -L. -L./.
init:
gcc -g -o initiate -I$(LOCAL_INCLUDE) initiate.c -lzmq -lconfig -lpthread -L. -L./. -ldl -lrt
clean:
rm -rf init_manager.o init_manager
rm -rf process1 process2 process3 process4
ПРИМЕЧАНИЕ. Рекомендуется очищать и трогать все исполняемые файлы перед повторным созданием.
Вы близки, но вам нужно шаблонное правило:
$(EXECUTABLE): % : %.c
А затем правило по умолчанию, чтобы заставить его строить оба:
all: $(EXECUTABLE)