Ваш вопрос фактически задает как Makefile
, так и процесс компиляции.
Makefile
файл содержит правила со следующей структурой:
output: input1 input2
command_to_obtain_output_from_inputs
Проверка thisссылка , чтобы увидеть, как работает компиляция.Вы увидите другой шаг: предварительная обработка (т.е. замена макросов), компиляция, сборка (генерируйте машинный код из вашего файла, но не подставляя команды из внешних библиотек), связывание (соединение вашего машинного кода с машинным кодом внешних библиотек, чтобы вашфинальные исполняемые файлы).
Файл будет считываться с начала до тех пор, пока не будет найдено первое правило, определяющее конечный результат процесса.
Начиная с конца исполняемый файл является результатом процесса компоновки, для которого требуется *.o
файлов.В Makefile
это должно быть ваше первое правило (над всеми остальными), которое обычно выглядит примерно так:
исполняемый файл: o1.o o2.o gcc $ ^ -o $ @
где $@
- имя файла цели правила, executable
в этом случае и $@
- все входные данные o1.0
, o2.o
.
, поскольку make
хотя бы первоевремя не найдет эти файлы и продолжит сканирование Makefile
, чтобы найти другое правило для их создания (файлы *.o
).Такое правило может быть что-то вроде:
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile
gcc -MMD -MP -c $< -o $@
, и это будет правильным правилом для создания всех необходимых *.o
.
, где $<
является первой предпосылкой, то есть соответствующей %.c
файл.Также Makefile
был добавлен в качестве зависимости для регенерации *.o
в случае, если он изменен, но не используется в команде.-MMD
создаст *.d
файлы для зависимостей, но обычно это не нужно.
Makefile
также позволяет вам определять переменные, чтобы вы могли ссылаться на них через весь ваш файл.Просто чтобы привести пример, я выложу Makefile
моего.
CXX = gcc
SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR=$(SOURCEDIR)/obj
LIBS = ... #your external libraries
CXXFLAGS = ... #your flags
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: ruptime
clean:
$(RM) $(OBJECTS) $(DEPENDS) ruptime
# Linking the executable from the object files
# $^ # "src.c src.h" (all prerequisites)
ruptime: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $@ $(LIBS)
-include $(DEPENDS)
$(OBJDIR):
mkdir -p $(OBJDIR)
#Note the dependency from the folder $(OBJDIR) and the
#rule above to generate it. However with the symbol |
# no ricompilation is perform if the folder if it modified
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
$(CXX) $(WARNING) -MMD -MP -c $< -o $@