我正在尝试为项目编写Makefile。有了这个,只要任何C文件发生变化,我就能够构建项目。但是,当头文件发生更改时,它不会构建。
所以,我正在尝试使用Makefile来实现更简单的目录结构,如果它有效,我打算在主项目中做同样的事情。
目录结构是,
src -> code1 -> file1.c
src -> code2 -> file2.c
src -> code1inc -> file1.h
src -> code2inc -> file2.h
所有文件应该构建并提供单个二进制文件FinalBin
当file1.h发生变化时,它必须只构建file1.c。 如何通过Makefile强制执行此操作?
这是我目前的Makefile。
CC = gcc
CFLAGS = $(INCLUDES)
TARGET = FinalBin
SOURCES := $(wildcard *.c)
PATH_CODE1 = src/code1
PATH_CODE2 = src/code2
CODE1_SOURCES := $(wildcard $(PATH_CODE1)/*.c)
CODE1_OBJECTS := $(patsubst %.c,%.o,$(CODE1_SOURCES))
CODE2_SOURCES := $(wildcard $(PATH_CODE2)/*.c)
CODE2_OBJECTS := $(patsubst %.c,%.o,$(CODE2_SOURCES))
PATH_CODE1INC = src/code1inc
PATH_CODE2INC = src/code2inc
INCLUDES = -I$(PATH_CODE1INC) \
-I$(PATH_CODE2INC)
CODE1_HEADERS := $(wildcard $(PATH_CODE1INC)/*.h)
CODE2_HEADERS := $(wildcard $(PATH_CODE2INC)/*.h)
all: $(TARGET)
obj1 = $(CODE1_OBJECTS) $(CODE1_HEADERS)
obj2 = $(CODE2_OBJECTS) $(CODE2_HEADERS)
$(TARGET) : $(obj1) $(obj2)
$(CC) $^ -o $@
clean:
rm $(TARGET) $(CODE1_OBJECTS) $(CODE2_OBJECTS)
请指导我。
答案 0 :(得分:2)
你所做的事似乎不寻常。
典型的方法是拥有一个源文件列表,可以手动编写或自动评估,例如:通过从一个或多个目录中捕获所有c文件。这就是你已经做过的事:CODE1_SOURCES := $(wildcard $(PATH_CODE1)/*.c)
但是应该自动生成每个文件的依赖项。例如,gcc提供了' -M'或者' -MM'重建所谓的依赖文件的选项,通常命名为' .d'或者' .dep'
可以在此处找到完整流程的好文档:
http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#basic
对于简单的情况,这是从上述文件中得到的一个例子:
SRCS = foo.c bar.c ...
%.o : %.c
@$(MAKEDEPEND); \
cp $*.Td $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.Td >> $*.d; \
rm -f $*.Td
$(COMPILE.c) -o $@ $<
include $(wildcard $(SRCS:.c=.d))
如果使用gcc MAKEDEPEND可以是:
MAKEDEPEND = gcc -M $(CPPFLAGS) -o $*.Td $<
一个简短的解释:
通常,您可以使用以下命令定义%。。文件生成%.o文件的规则:
%.o : %.c
作为该规则的第一步,如果必须编译源,则始终构建depfile,通常如果%.o文件不存在或者依赖项比%.o文件更新,则:
gcc -M $(CFLAGS) -o $*.Td $<
摘录中给出的最后一行确实包含了所有这些自动生成的依赖文件,只需将它们包含在Makefile本身中:
include $(wildcard $(SRCS:.c=.d))
答案 1 :(得分:1)
不需要规则中的sed语句。 Gcc支持-MF选项来控制依赖项输出文件。
CC = gcc
SRCS = foo.c bar.c ...
OBJS = $(SRCS:%.c=%.o)
DEPS = $(wildcard $(OBJS:%=%.d))
%.o : %.c
$(CC) -MD -MP -MF "$@.d" -o $@ -c $<
include $(DEPS)