2010-07-09 68 views
0

我想創建一個通用的生成文件來構建我的項目使用的靜態庫。我已經使用了本站的專業知識,以及GNU Make手冊來幫助編寫下面的makefile。除了一個令人討厭的問題之外,它的運作很好。我的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 [email protected]" 
    @$(CC) -M $(CFLAGS) $*.c > [email protected] 
    @sed s~.*:~"$(BUILD_DIR)/$*.o [email protected]:"~ [email protected] > [email protected] 
    @rm [email protected] 

# 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 [email protected] 

# 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) 

問題是,當它們不需要時依賴文件被建立。例如使安裝前重新生成.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 ... } 

這一切都很好!但是,「使安裝」現在重建.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有什麼問題?

回答

2

問題是你include的依賴文件(whatever.d),你也有一個建立這些文件的規則。所以每次使用這個makefile時,不管你指定了什麼目標,它都會重建它們,包含它們,然後再次執行。

嘗試this可獲得解決此問題的依賴性處理方法。基本上,你不需要爲foo.d制定一個單獨的規則,只需將其作爲foo.o規則的一個副作用(需要考慮一下才能認識到這一點)。

相關問題