我正在尝试创建一个Makefile来编译我的C程序。我正在尝试使用以下目录结构生成Debug和Release版本:
helloworld/
├── Debug/
│ ├── bin/
│ ├── depends/
│ └── obj/
├── Release/
│ ├── bin/
│ ├── depends/
│ └── obj/
├── mylib/
│ ├── bar.c
│ ├── bar.h
│ ├── foo.c
│ └── foo.h
└── main.c
我想要做的是让Makefile包含基于目标的不同依赖文件(Debug vs Release)。我现在的makefile是这样的:
CC = clang
CFLAGS = -c -g -Wall -Wextra -pedantic
SOURCES = main.c foo.c bar.c
OBJECTS = $(SOURCES:%.c=Debug/obj/%.o)
INCLUDE = -Imylib/
VPATH = mylib
.PHONY: debug
debug: Debug/bin/main
Debug/bin/main: $(OBJECTS)
$(CC) $^ -o -g $@
Debug/obj/%.o: %.c | Debug
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE)
-include $(SOURCES:%.c=Debug/depends/%.d)
Debug:
-mkdir Debug
-mkdir Debug/bin
-mkdir Debug/depends
-mkdir Debug/obj
clean:
rm -rf Debug
rm -rf Release
哪个适用于调试。但是,当我尝试为Debug和Release创建单独的目标时,我很难理解如何修改-include $(SOURCES:%.c=Debug/depends/%.d)
CC = clang
CFLAGS = -c -g -Wall -Wextra -pedantic
SOURCES = main.c foo.c bar.c
DEBUG_OBJECTS = $(SOURCES:%.c=Release/obj/%.o)
RELEASE_OBJECTS = $(SOURCES:%.c=Debug/obj/%.o)
INCLUDE = -Imylib/
VPATH = mylib
.PHONY: all debug release
all: release debug
release: Release/bin/main
debug: Debug/bin/main
Release/bin/main: $(RELEASE_OBJECTS)
$(CC) $^ -o $@
Release/obj/%.o: %.c | Release
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Release/depends/$(@F:.o=.d) $(INCLUDE)
Debug/bin/main: $(DEBUG_OBJECTS)
$(CC) $^ -o -g $@
Debug/obj/%.o: %.c | Debug
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE)
# -------------------------------------------------------
# -include $(SOURCES:%.c=Debug/depends/%.d) What do I do?
# -------------------------------------------------------
Release:
-mkdir Release
-mkdir Release/bin
-mkdir Release/depends
-mkdir Release/obj
Debug:
-mkdir Debug
-mkdir Debug/bin
-mkdir Debug/depends
-mkdir Debug/obj
clean:
rm -rf Debug
rm -rf Release
如何根据目标有条件地包含依赖项文件?
是否有更好的项目组织结构?
我对makefile非常陌生。以前我只依靠我的IDE来管理构建和配置。还有其他提示可以帮助改进这个makefile吗?
答案 0 :(得分:0)
好的,我想我已经找到了一个可能的解决方案:使用两个makefile。第一个makefile创建目标文件并创建最终的可执行文件。第二个makefile使用不同的变量调用第一个makefile。
export CC := gcc
export SOURCES := main.c bar.c foo.c
export VPATH := mylib/
export INCLUDES := $(VPATH:%=-I%)
export DBGFLAGS := -g -c -Wall -Wextra -pedantic
export RELFLAGS := -c -Wall -Wextra -pedantic -Os
.PHONY: all debug release
all: debug release
release:
make -f target.mk TARGET=Release CFLAGS='$(RELFLAGS)'
debug:
make -f target.mk TARGET=Debug CFLAGS='$(DBGFLAGS)'
clean:
make -f target.mk clean TARGET=Debug
make -f target.mk clean TARGET=Release
$(TARGET)/bin/main.out: $(SOURCES:%.c=$(TARGET)/obj/%.o)
$(CC) $^ -o $@
$(TARGET)/obj/%.o: %.c | $(TARGET)
$(CC) $(CFLAGS) $< -o $@ -MMD -MP -MF $(TARGET)/depends/$(@F:.o=.d) $(INCLUDES)
$(TARGET):
-mkdir $(TARGET)
-mkdir $(TARGET)/bin
-mkdir $(TARGET)/depends
-mkdir $(TARGET)/obj
clean:
rm -rf $(TARGET)
-include $(SOURCES:%.c=$(TARGET)/depends/%.d)