1

我是制作文件的新手,我通过一些试验和错误把它放在一起。此代码用于编译我的 c++ 程序。

我的 main.cpp 文件与 makefile 位于同一文件夹中。我有一个 lib/ 文件夹,其中包含主要依赖的标题。

下面的 makefile 可以正确且完整地编译我的代码。但我期待我会找到留下的 *.o 对象。(请注意,我尝试使用和不使用“干净”规则,并且两次都得到相同的结果。)

#
# Makefile
#

CXX = g++
CCFLAGS = -O3 -I/sw/include -L/sw/lib
      ## /sw/include and /sw/lib contain dependencies for files in my lib/
LDFLAGS = -lpng
OPTS = $(CCFLAGS) $(LDFLAGS)

SOURCES = $(wildcard lib/*.cpp) main.cpp
OBJECTS = $(SOURCES: .cpp = .o)
TARGET = spirals

$(TARGET): $(OBJECTS)
    $(CXX) $(OPTS) $^ -o $@

.PHONY: depend
depend:
    g++ -MM $(SOURCES) > depend
      ## generate dependencies list
include depend

.PHONY: clean
clean:
    rm -f *.o lib/*.o $(TARGET)

另外,如果重要的话,我在 MacOSX 上,我的程序是用 xcode 设计的。(我知道 xcode 有自己的构建流程,但我正在为 linux 系统设计一个命令行程序,我想在 bash 环境中测试编译和链接,而不仅仅是通过 xcode。)

问题:

  1. 一旦创建了主要目标,我期望 makefile 生成 *.o 文件是否正确?

  2. 如果是这样,为什么我的 makefile 不这样做?

4

1 回答 1

4

如果您观察您的$(TARGET)规则导致运行的命令:

g++ -O3 -I/sw/include -L/sw/lib -lpng lib/bar.cpp lib/foo.cpp main.cpp -o spirals

您会看到它$(OBJECTS)实际上包含 *.cpp 文件,并且没有 *.o 文件存在,因为您没有要求任何文件。

问题在这里:

OBJECTS = $(SOURCES:.cpp=.o)

在您编写的 GNU makefile 中,此替换引用是用多余的空格编写的,因此永远不会匹配任何内容并且$(OBJECTS)最终与$(SOURCES). 像上面那样重写它,它会做你所期望的。

(其他注意事项:-lpng通常需要在链接命令的末尾才能工作,所以你应该引入另一个 make 变量(传统上称为$(LDLIBS))以便安排它。特别是作为 makefile 的新手,你最好拼出您的依赖项明确而不是使用$(wildcard)和计算$(OBJECTS). -I选项在编译期间需要,而-L在链接期间使用选项,因此最好安排单独的$(CXXFLAGS)/$(LDFLAGS)变量在单独的规则中使用,以便仅在需要时添加它们。)

于 2012-06-28T21:22:16.990 回答