我正在尝试使用以下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
答案 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
样式方面,你的例子将目录路径分隔符(/)附加到每个变量 - 这不是我推荐的东西,它使得一个人的模式 规则中的匹配相当丑陋。