没有规则为目标列表中的最后一个项目制定目标

时间:2014-02-03 06:27:09

标签: makefile

我正在尝试使用以下Makefile来更好地了解它们的工作原理。但我继续得到以下错误。运行make clean然后make build后,会发生以下错误。

src/main.cpp src/src1.cpp src/src2.cpp src/src3.cpp
obj/main.o obj/src1.o obj/src2.o obj/src3.o
bin/AoS
Building object obj/main.o
touch obj/main.o
Building object obj/src1.o
touch obj/src1.o
Building object obj/src2.o
touch obj/src2.o
make: *** No rule to make target `obj/src3.o', needed by `build'.  Stop.

这是我的Makefile的内容。

#CURR_DIR = $(notdir $(shell pwd))
SRC_DIR := src/
OBJ_DIR := obj/
BIN_DIR := bin/
SRC := $(wildcard $(SRC_DIR)*.cpp)
OBJ := $(SRC:$(SRC_DIR)%.cpp=$(OBJ_DIR)%.o)
BIN := bin/AoS

$(info $(SRC))
$(info $(OBJ))
$(info $(BIN))

build:  $(OBJ) 
    @echo "Building the project"
    @echo "g++ -o $(BIN) $^"

$(OBJ)%.o:  
    @echo "Building object $@"
    touch $@

dirs:
    mkdir -p ./$(OBJ_DIR)
    mkdir -p ./$(SRC_DIR)
    mkdir -p ./$(BIN_DIR)

tsfls:
    touch $(SRC_DIR)src1.cpp
    touch $(SRC_DIR)src2.cpp
    touch $(SRC_DIR)src3.cpp
    touch $(SRC_DIR)src1.h
    touch $(SRC_DIR)src2.h
    touch $(SRC_DIR)src3.h
    touch $(OBJ_DIR)main.o

print:
    make build --just-print

clean:
    /bin/rm -f $(OBJ)
    /bin/rm -f $(BIN)

为什么$(OBJ)中的最后一项错误?我减少了源文件的数量,并且我仍然得到最后一项的相同错误。

感谢您的帮助!这里修正了我的Makefile版本,它借用了James的例子中的组件。

SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
# DIRS = $(SRC_DIR) $(OBJ_DIR) $(BIN_DIR)
# SRCS = $(wildcard $(SRC_DIR)/*.cpp) Don't rely on this method. 
SRCS = main.cpp src1.cpp src2.cpp src3.cpp
OBJS = $(SRCS:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
BIN = $(BIN_DIR)/AoS

$(info $(SRCS))
$(info $(OBJS))
$(info $(BIN))

# target: link the objects. 
#   prerequisite: make sure that the objects are compiled first.
#   prerequisite: check for any $(BIN) prerequisites.
build: $(OBJS) $(BIN)
    @echo "Building the project"
    @echo "g++ -o $(BIN) $^ A_BUNCH_OF_FLAGS"

# target: do work for creating the binary file. 
#   prerequisite: Make sure that there is a bin directory. 
$(BIN): $(BIN_DIR)

# target: If a dependency asks for files in the OBJ_DIR that have teh .o extension then
#   build those objects.
#   prerequisite: Find the matching source file in the SRC_DIR.
#   prerequisite: Find the matching header file in the SRC_DIR.
#   prerequisite: Make sure that the object directory exists.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h $(OBJ_DIR)
    @echo "Building object $@"
    @echo "g++ $@ -c $<"
    touch $@

# target: Make make an executables directory if necessary. 
$(BIN_DIR): 
    @echo "Did not find an binary directory... creating one"
    mkdir -p ./$(BIN_DIR)

# target: Make an object directory if necessary. 
$(OBJ_DIR):
    @echo "Did not find an object directory... creating one"
    mkdir -p ./$(OBJ_DIR)

# Create bogus files to experiment with dependencies.
tsfls:
    touch $(SRC_DIR)/src1.cpp
    touch $(SRC_DIR)/src2.cpp
    touch $(SRC_DIR)/src3.cpp
    touch $(SRC_DIR)/src1.h
    touch $(SRC_DIR)/src2.h
    touch $(SRC_DIR)/src3.h

print:
    make build --just-print

clean:
    /bin/rm -rf $(OBJ_DIR)
    /bin/rm -rf $(BIN_DIR)

db:
    make build --print-data-base

1 个答案:

答案 0 :(得分:2)

简短的回答:你的依赖关系错了。此外,您正在使用:= 而不是plain =,所以你在制作SRC_DIR等条件变量。 这些是正确的,我不建议使用它们,除非你 实际上需要这样做。

这是我希望能帮到你的东西。它适用于gmake和Solaris Studio的dmake

#BEGIN
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin

DIRS = $(SRC_DIR) $(OBJ_DIR) $(BIN_DIR)
SRCS = src1.cpp src2.cpp src3.cpp main.cpp
OBJS = $(SRCS:%.cpp=$(OBJ_DIR)/%.o)
HDRS = $(SRCS:%.cpp=%.h)

BIN = $(BIN_DIR)/AoS

# gmake will "helpfully" assume that these are 'intermediate' files
# without .PRECIOUS, and automagically clean them up for you.
.PRECIOUS: $(HDRS) $(SRCS)

$(BIN): $(DIRS) $(OBJS)

build:  $(DIRS) $(BIN)
    @echo "Building the project"
    @echo "g++ -o $(BIN) $(OBJ)"
    touch $?

$(OBJ_DIR)/%.o: $(OBJS_DIR) $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
    @echo "Building object $@"
    touch $@

$(SRC_DIR)/%:  $(SRC_DIR)
    touch $@

$(DIRS):
    mkdir -p $@
#END

样式方面,你的例子将目录路径分隔符(/)附加到每个变量 - 这不是我推荐的东西,它使得一个人的模式 规则中的匹配相当丑陋。