简体   繁体   中英

Automatic make dependency generation with gcc

New to GNU Make and trying to build a Makefile that automatically generates its dependencies for rebuilding so that the necessary objects get rebuilt and linked upon changing a header file.

Rather than using .d files I want to have a single file like .depend so I have a rule that creates the file and include it as a dependency like this (using sed to append obj/ in front of every line)

.depend: $(SRC_FILES)
    rm -f ./.depend
    $(CC) $(CFLAGS) -MM $^ | sed 's/^/$(OBJECT_DIR)\//' >> ./.depend;

include .depend

The problem is, upon building it only compiles the first rule in the .depend file and then stops with a succession. This is very likely a problem with the way I have my rules/targets set up but I can't figure out what's making it stop at the first built object, my file looks like this

BIN_NAME := test

# Compiler
CC      := gcc
CFLAGS  := -Wall -O3

# Directories
BINARY_DIR := bin
OBJECT_DIR := obj
SOURCE_DIR := src

# Files 
SRC_FILES := $(wildcard $(SOURCE_DIR)/*.c)
OBJ_FILES := $(patsubst $(SOURCE_DIR)/%.c,$(OBJECT_DIR)/%.o, $(SRC_FILES))

# Dependencies
.depend: $(SRC_FILES)
    rm -f ./.depend
    $(CC) $(CFLAGS) -MM $^ | sed 's/^/$(OBJECT_DIR)\//' >> ./.depend;

#include .depend

# Targets
$(OBJECT_DIR)/%.o: $(SOURCE_DIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@

$(BINARY_DIR)/$(BIN_NAME): $(OBJ_FILES)
    $(CC) $(CFLAGS) -o $@ $^

clean:
    rm $(OBJECT_DIR)/* $(BINARY_DIR)/* .depend

Commenting include .depend skips generation of the .depend file and outputs the binary properly but only updates when changing a source file as expected when not using dependency gen. I want to know what causes this behavior, and the problems with my targets. The sample .depend file looks like this

obj/message.o: src/message.c src/message.h
obj/hello.o: src/hello.c src/message.h

Read the intro section in the GNU make manual and you will see in the first sentence:

By default, make starts with the first target.

What's the first target in your makefile? Since the include comes before any other targets, it's the first target in the include d file.

As Beta says, simply put the include line at the end of your makefile (or at least, not at the beginning) and your problem will be solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM