Makefil'ы для release и debug
Jan. 16th, 2020 01:10 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Ковыряясь с TODO, решил еще и Makefile немножко улучшить. С cmake я уже раньше подобное вытворял, но с Makefile пока как-то ручками (а то и иной раз вообще в начале makefile писал DEFS+=-DEBUG и комментировал эту строку для release).
Вот что получилось. Привожу основную выжимку:
Все! Теперь покуда мы сидим в одной модели, правка отдельных файлов вызовет лишь их пересборку при соответствующих флагах. Как только модель поменяли, в mk/ не оказывается нужного файла, вызывается make clean, а затем новая модель сборки выполняется начисто! Вуаля!
# run `make DEF=...` to add extra defines
PROGRAM := test
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
SRCS := $(wildcard *.c)
DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
OBJDIR := mk
CFLAGS += -O2 -Wall -Wextra -Wno-trampolines -std=gnu99
OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
DEPS := $(OBJS:.o=.d)
CC = gcc
TARGET := RELEASE
all: $(OBJDIR)/RELEASE
all: $(PROGRAM)
release: all
debug: CFLAGS += -DEBUG -Werror
debug: TARGET := DEBUG
debug: $(OBJDIR)/DEBUG
debug: $(PROGRAM)
$(OBJDIR)/DEBUG:
make clean
$(OBJDIR)/RELEASE:
make clean
$(PROGRAM) : $(OBJDIR) $(OBJS)
echo -e "\t\tTARGET: $(TARGET)"
@> $(OBJDIR)/$(TARGET)
echo -e "\t\tLD $(PROGRAM)"
$(CC) $(LDFLAGS) $(OBJS) -o $(PROGRAM)
$(OBJDIR):
mkdir $(OBJDIR)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(OBJDIR)/%.o: %.c
echo -e "\t\tCC $<"
$(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
clean:
echo -e "\t\tCLEAN"
rm -rf $(OBJDIR) 2>/dev/null || true
xclean: clean
rm -f $(PROGRAM)
.PHONY: clean xclean
Вот что получилось. Привожу основную выжимку:
# это пишем в начале, где определяем всякое разное, целью по умолчанию будет release TARGET := RELEASE # здесь у меня всякий мусор хранится, чтобы некошерными файлами не заваливать основную директорию с кодом OBJDIR = mk # самой первой целью задаем умолчательную: all: $(OBJDIR)/RELEASE # в поддиректории mk создаем файл RELEASE или DEBUG в зависимости от модели сборки all: bin list size release: all # отдельно даем возможность писать не просто make, но и make release (хоть это и одно и то же) # а теперь - для debug, здесь добавляем -DEBUG и -Werror debug: CFLAGS += -DEBUG -Werror debug: TARGET := DEBUG # меняем имя цели debug: $(OBJDIR)/DEBUG # и меняем зависимость от файла debug: bin list size # писать здесь all нельзя, т.к. all зависит от $(OBJDIR)/RELEASE # ну и объявим виртуально, что сами файлы mk/DEBUG и mk/RELEASE "создаются" при помощи make clean: $(OBJDIR)/DEBUG: make clean $(OBJDIR)/RELEASE: make clean # ну и в цель - бинарник - добавляем создание нужных файлов: $(BIN): $(ELF) @echo "TARGET: $(TARGET)" @> $(OBJDIR)/$(TARGET)
Все! Теперь покуда мы сидим в одной модели, правка отдельных файлов вызовет лишь их пересборку при соответствующих флагах. Как только модель поменяли, в mk/ не оказывается нужного файла, вызывается make clean, а затем новая модель сборки выполняется начисто! Вуаля!
# run `make DEF=...` to add extra defines
PROGRAM := test
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
SRCS := $(wildcard *.c)
DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
OBJDIR := mk
CFLAGS += -O2 -Wall -Wextra -Wno-trampolines -std=gnu99
OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
DEPS := $(OBJS:.o=.d)
CC = gcc
TARGET := RELEASE
all: $(OBJDIR)/RELEASE
all: $(PROGRAM)
release: all
debug: CFLAGS += -DEBUG -Werror
debug: TARGET := DEBUG
debug: $(OBJDIR)/DEBUG
debug: $(PROGRAM)
$(OBJDIR)/DEBUG:
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
$(OBJDIR)/RELEASE:
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
$(PROGRAM) : $(OBJDIR) $(OBJS)
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
@> $(OBJDIR)/$(TARGET)
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
$(CC) $(LDFLAGS) $(OBJS) -o $(PROGRAM)
$(OBJDIR):
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(OBJDIR)/%.o: %.c
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
$(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
clean:
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
xclean: clean
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
.PHONY: clean xclean
no subject
Date: 2020-01-16 12:24 am (UTC)