我无法使用makefile生成可执行文件。 这是我的makefile中的代码:
CXX = g++
CXXFLAGS = -std=c++0x
CXXFLAGS += -Wall
CXXFLAGS += -pedantic-errors
CXXFLAGS += -g
LDFLAGS = -lboost_date_time
OBJS = f.o g.o lab1-2.o
SRCS = f.cpp g.cpp lab1-2.cpp
HEADERS = f.h g.h
#target: dependencies
# rule to build
lab1-2: ${OBJS} ${HEADERS}
${CXX} ${LDFLAGS} ${OBJS} -o lab1-2
${OBJS}: ${SRCS}
${CXX} ${CXXFLAGS} -c $(@: .o=.cpp)
当我致电" make"这就是:
g++ -std=c++0x -Wall -pedantic-errors -g -c f.o;
g++ -std=c++0x -Wall -pedantic-errors -g -c g.o;
g++ -std=c++0x -Wall -pedantic-errors -g -c lab1-2.o;
"linker input file unused because linking not done"
我不确定这条消息(上图)的含义以及我如何修复它?谢谢!
答案 0 :(得分:1)
问题是-c
标志告诉编译器前端(g++
)它应该将源文件编译成目标文件,然后停止。但是,您要将目标文件提供给编译器(f.o
,g.o
,lab1-2.o
),而不是源文件。所以编译器告诉你它忽略了那些目标文件,因为你正在编译(-c
)而不是链接。
你的makefile有问题。例如:
${OBJS}: ${SRCS}
${CXX} ${CXXFLAGS} -c $(@: .o=.cpp)
不是你想要的。首先,您不能在:
之后的模式引用中添加空格。 Make非常特别关于某些类型的空白(就像所有的计算机工具一样)。如果手册中的示例没有空格,则最好不添加任何内容(反之亦然)。你想说$(@:.o=.cpp)
(没有空格)。然后你的编译行将包含源文件:f.cpp
,g.cpp
)而不是目标文件。
其次,如果你扩展你得到的变量:
f.o g.o lab1-2.o: f.cpp g.cpp lab1-2.cpp
与写作相同:
f.o: f.cpp g.cpp lab1-2.cpp
g.o: f.cpp g.cpp lab1-2.cpp
lab1-2.o: f.cpp g.cpp lab1-2.cpp
无论何时更改任何源文件,都将重建所有目标文件。这不是你想要的。此外,由于您没有在此列出任何头文件,因此意味着由于您更改了头文件,因此不会重建这些目标文件。
最后,你有这个:
lab1-2: ${OBJS} ${HEADERS}
您已将头文件列为可执行文件的先决条件,这是不对的:当头文件更改时,您不会重新链接可执行文件,您重新编译源文件。
你想要这样的东西:
lab1-2: ${OBJS}
${CXX} ${LDFLAGS} ${OBJS} -o lab1-2
$(OBJS): $(HEADERS)
%.o: %.cpp
${CXX} ${CXXFLAGS} -c -o $@ $<
当然,GNU make有内置的规则可以为你完成所有这些,所以你可以写下这个:
lab1-2: ${OBJS}
$(OBJS): $(HEADERS)
获得相同的结果。