Мой make-файл создает файлы зависимостей, когда в них нет необходимости - почему? - PullRequest
0 голосов
/ 09 июля 2010

Я пытаюсь создать универсальный make-файл для сборки статических библиотек, которые использует мой проект. Я использовал опыт на этом сайте, а также руководство по GNU Make, чтобы помочь написать следующий make-файл. Это работает хорошо, за исключением одной раздражающей проблемы.

# 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, но это не дало никакого эффекта Что не так с моим make-файлом?

1 Ответ

2 голосов
/ 09 июля 2010

Проблема в том, что у вас include файлы зависимостей (what.d), и у вас также есть правило для создания этих файлов.Поэтому каждый раз, когда вы используете этот make-файл, независимо от того, какую цель вы указали, он будет перестраивать их, включать их и выполнять снова.

Попробуйте this для подхода к обработке зависимостей, который решает эту проблемупроблема.По сути, вам не нужно отдельное правило для foo.d, просто сделайте его побочным эффектом правила foo.o (нужно подумать, чтобы понять, что это будет работать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...