我的makefile在不需要时构建依赖文件 - 为什么?

时间:2010-07-09 02:52:30

标签: makefile

我正在尝试创建一个通用的makefile来构建我的项目使用的静态库。我已经使用了这个网站上的专业知识,以及GNU Make手册来帮助编写以下makefile。除了一个令人讨厌的问题之外,它的效果很好。

# Generic makefile to build/install a static library (zlib example)
ARCH      = linux
CFLAGS    = -O3 -Wall

# List of source code directories
SOURCES   = src test utils
# List of header files to install
INCLUDES  = src/zlib.h src/zconf.h
# Library to create
LIBNAME   = libz.a

############################################################

BUILD_DIR   = build/$(ARCH)

# Full path to the built library
TARGET      = $(BUILD_DIR)/$(LIBNAME)

prefix = ../..
exec_prefix = prefix
libdir = $(prefix)/lib/$(ARCH)
includedir = $(prefix)/include
INSTALL_PROGRAM = install -D
INSTALL_DATA = $(INSTALL_PROGRAM) -m 644

CFILES    := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.c))
OBJECTS   := $(addprefix $(BUILD_DIR)/,$(CFILES:.c=.o))
DEPENDS   := $(OBJECTS:.o=.d)

.PHONY: all installdirs install uninstall clean

# Default
all: $(DEPENDS) $(TARGET)

# Build the dependency files
# (GNU Make Manual 4.14 Generating Prerequisites Automatically)
$(BUILD_DIR)/%.d: $(BUILD_DIR)
    @echo "build dep for $*.c as $@"
    @$(CC) -M $(CFLAGS) $*.c > $@.tmp
    @sed s~.*:~"$(BUILD_DIR)/$*.o $@:"~ $@.tmp > $@
    @rm $@.tmp

# Link all changed object files into static library
$(TARGET): $(OBJECTS)
    $(AR) -rc $(TARGET) $?

# Compile C source to object code
$(BUILD_DIR)/%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

# Create the necessary directory tree for the build
$(BUILD_DIR):
    @for p in $(SOURCES); do mkdir -p $(BUILD_DIR)/$$p; done

# Create the necessary directory tree for installation
installdirs:
    @mkdir -p $(libdir)
    @mkdir -p $(includedir)

# Install the library and headers
install: all installdirs
    $(INSTALL_DATA) $(TARGET) $(libdir)
    for p in $(INCLUDES); do $(INSTALL_DATA) $$p $(includedir); done

# Remove the library and headers
uninstall: 
    rm -f $(libdir)/$(LIBNAME)
    for p in $(notdir $(INCLUDES)); do rm -f $(includedir)/$$p; done

# Remove all build files
clean:
    rm -fr $(BUILD_DIR)

# Pull in the dependencies if they exist
# http://scottmcpeak.com/autodepend/autodepend.html
-include $(DEPENDS)

问题是依赖项文件是在不需要的时候构建的。例如下面显示的make install在安装之前重建.d文件。

$make --version
GNU Make 3.81
$make
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
...
{ continues on making the other .d files, then the .o files }
...
cc -O3 -Wall -c src/zutil.c -o build/linux/src/zutil.o
cc -O3 -Wall -c test/test.c -o build/linux/test/test.o
cc -O3 -Wall -c utils/utils.c -o build/linux/utils/utils.o
ar rc { ... .o files ... }

到目前为止一切都很好!但是'make install'现在将重建.d文件

$make install
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
{ ... }
install -D -m 644 build/linux/libz.a ../../lib/linux
for p in src/zlib.h src/zconf.h; do install -D -m 644 $p ../../include; done

我在构建对象时尝试“触摸”.d文件,因此更新时间比.o文件更新,但是没有效果。我的makefile出了什么问题?

1 个答案:

答案 0 :(得分:2)

问题是你include依赖文件(无论什么d。),你还有一个建立这些文件的规则。所以每次使用这个makefile时,无论你指定什么目标,它都会重建它们,包含它们,然后重新执行。

尝试使用this来解决此问题的依赖项处理方法。基本上,你不需要为foo.d单独的规则,只是使它成为foo.o规则的副作用(需要一些思考才能意识到这将起作用)。