我无法让我的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"
我不确定以上消息的含义以及如何解决?谢谢!
最佳答案
问题在于-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)
获得相同的结果。