40 Концепции Makefile Работа с docker контейнерам
40 Концепции Makefile Работа с docker-контейнерами¶
Makefile — это файл, используемый утилитой make для автоматизации процесса сборки программного обеспечения. Makefile содержит набор правил и инструкций, определяющих, как компилировать и связывать исходный код для создания исполняемых файлов или библиотек.
Концепции:¶
Цели
Цель — это то, что вы хотите создать или обновить. Это может быть исполняемый файл, объектный файл или даже другое правило в Makefile.
target: dependencies
command
- target: Имя цели.
- dependencies: Список файлов или других целей, от которых зависит эта цель.
- command: Команда (или команды), которые должны быть выполнены для создания или обновления цели.
пример:
app: main.o utils.o
gcc -o app main.o utils.o
Зависимости (Dependencies)
Зависимости указывают на файлы, от которых зависит цель. Если один из этих файлов изменяется, цель должна быть пересобрана.
Пример:
main.o: main.c utils.h
gcc -c main.c
utils.o: utils.c utils.h
gcc -c utils.c
Правила (Rules)
Правила состоят из цели, зависимостей и команд для выполнения. Они определяют процесс сборки.
Пример полного Makefile:
app: main.o utils.o
gcc -o app main.o utils.o
main.o: main.c utils.h
gcc -c main.c
utils.o: utils.c utils.h
gcc -c utils.c
clean:
rm -f app main.o utils.o
Переменные (Variables)
Переменные позволяют избежать дублирования кода и упрощают изменение Makefile.
Пример использования переменных:
CC = gcc
CFLAGS = -Wall -g
app: main.o utils.o
$(CC) -o app main.o utils.o $(CFLAGS)
main.o: main.c utils.h
$(CC) -c main.c $(CFLAGS)
utils.o: utils.c utils.h
$(CC) -c utils.c $(CFLAGS)
clean:
rm -f app main.o utils.o
Встроенные правила и макросы
Make имеет множество встроенных правил и макросов для распространенных задач сборки. Например, можно использовать встроенные правила для компиляции C-файлов без явного указания команд:
Пример:
app: main.o utils.o
$(CC) $^ -o $@
main.o: main.c
utils.o: utils.c
Пример сложного мейка:
# Переменные компилятора и флаги компиляции/линковки
CC = gcc
CFLAGS = -Wall -g
LDFLAGS =
# Списки исходных файлов и объектных файлов
SRCS = main.c foo.c bar.c
OBJS = $(SRCS:.c=.o)
# Основная цель
app: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
# Правила для объектных файлов
%.o : %.c
$(CC) $(CFLAGS) -c $<
# Дополнительные цели
.PHONY : clean all
all : app
clean :
rm -f *.o app
# Автоматическое создание зависимостей заголовочных файлов (.d files)
DEPFILES := $(SRCS:.c=.d)
%.d : %.c
@set -e; rm -f $@; \
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1\.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
include $(DEPFILES)
Использование докера с мейк файл¶
├── Dockerfile
├── Makefile
└── src
└── main.py
# Используем базовый образ Python
FROM python:3.8-slim
# Устанавливаем рабочую директорию в контейнере
WORKDIR /app
# Копируем файлы проекта в рабочую директорию
COPY src/ /app/
# Устанавливаем зависимости (если есть)
RUN pip install --no-cache-dir -r requirements.txt
# Определяем команду по умолчанию для запуска приложения
CMD ["python", "main.py"]
# Переменные
IMAGE_NAME = my_app_image
CONTAINER_NAME = my_app_container
.PHONY: all build run stop clean logs shell
all: build run
build:
docker build -t $(IMAGE_NAME) .
run:
docker run --name $(CONTAINER_NAME) -d $(IMAGE_NAME)
stop:
docker stop $(CONTAINER_NAME)
docker rm $(CONTAINER_NAME)
clean: stop
docker rmi $(IMAGE_NAME)
logs:
docker logs -f $(CONTAINER_NAME)
shell:
docker exec -it $(CONTAINER_NAME) /bin/sh
# Дополнительные цели могут быть добавлены по мере необходимости.
Использование Makefile¶
Для использования этого Make file, просто выполните нужные команды из корневой директории вашего проекта:
Чтобы собрать образ и запустить контейнер: make all
Чтобы остановить и удалить контейнер:
make stop
Чтобы очистить все (остановить контейнеры и удалить образы): make clean
Чтобы просмотреть логи:
make logs
Чтобы получить доступ к оболочке внутри работающего контейнера:
make shell