我无法让我的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.og.olab1-2.o),而不是源文件。因此,编译器告诉您它将忽略那些目标文件,因为您正在编译(-c)未链接。

您的makefile有问题。例如:

${OBJS}: ${SRCS}
        ${CXX} ${CXXFLAGS} -c $(@: .o=.cpp)


不是你想要的。首先,您不能在这样的模式引用中的:之后添加空格。 Make对某些种类的空白非常讲究(实际上是所有计算机工具一样)。如果手册中的示例没有空格,则最好不要添加任何空格(反之亦然)。您想说$(@:.o=.cpp)(无空格)。然后,您的编译行中将包含源文件:f.cppg.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)


获得相同的结果。

09-12 16:30