我有这个Makefile:
CFLAGS = -c -Wall
CC = g++
EXEC = main
SOURCES = main.cpp listpath.cpp Parser.cpp
OBJECTS = $(SOURCES: .cpp=.o)
EXECUTABLE = tp
DIR_SRC = /src/
DIR_OBJ = /obj/
all: $(SOURCES) $(OBJECTS)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
rm $(OBJECTS) $(EXECUTABLE)
请注意:
我得到的错误是:
No rules to build "main.cpp", necessary for "all". Stopping.
帮助!
答案 0 :(得分:1)
好的,从顶部开始:
CFLAGS = -c -Wall
CC = g++
# EXEC = main never used, not needed
SOURCES = main.cpp listpath.cpp Parser.cpp
到目前为止,这么好。请注意,此SOURCES
未提及DIR_SRC
,因此我们必须稍后建立该连接($(DIR_SRC)$(SOURCES)
将无效,因为路径必须附加到列表的每个成员)。但OBJECTS
确实需要路径(例如/obj/main.o
):
OBJECTS = $(patsubst %.cpp, $(DIR_OBJ)%.o, $(SOURCES))
EXECUTABLE = tp
DIR_SRC = /src/
DIR_OBJ = /obj/
(我个人不喜欢在变量中添加尾部斜杠,但这是一个品味问题。)第一个目标是默认目标,所以它应该构建你真正想要构建的东西:
all: $(EXECUTABLE)
不要担心将来源列为先决条件;他们以后会自行解决。
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@ # <-- note the automatic variable $^
.cpp.o
约定在这里并不真正起作用;我们必须拼出来。我们必须告诉Make要搜索$(DIR_SRC)
.cpp
个文件:
$(OBJECTS): $(DIR_OBJ)%.o: %.cpp $(DIR_OBJ)
$(CC) $(CFLAGS) $< -o $@
$(DIR_OBJ):
mkdir $@
vpath %.cpp $(DIR_SRC)
告诉Make clean
不是真正的目标,只是为了安全:
.PHONY: clean
clean:
rm $(OBJECTS) $(EXECUTABLE)
修改
我不应该一步到位地尝试这么多。让我们尝试一些更简单的方法:
$(DIR_OBJ)%.o: $(DIR_SRC)%.cpp $(DIR_OBJ)
$(CC) $(CFLAGS) $< -o $@
答案 1 :(得分:0)
修改SOURCES
以包含源目录(例如src/main.cpp
等)。
对于目标文件,请考虑以下内容:
OBJECTS = $(subst src/,obj/,$(SOURCES:%.cpp=%.o))
# ...
all: $(SOURCES) build
.PHONY: build
build: pre_build $(EXECUTABLE)
.PHONY: pre_build
pre_build: obj
obj:
-mkdir obj
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@