使不更新可执行文件

Make Does Not Update Executable

我编写了以下 makefile:

CC=g++

all: happy

happy: happy.o HappyLetter.o
        $(CC) -o happy happy.o HappyLetter.o

happy.o: happy.cpp
        $(CC) -c happy.cpp

HappyLetter.o: HappyLetter.cpp
        $(CC) -c HappyLetter.cpp

clean:
        rm -rf *.o happy

并且正在使用文件 HappyLetter.cpp 和 happy.cpp(包括前者)创建一个名为 happy 的可执行文件。

我可以使用 make 成功构建代码。但是,当我修改 HappyLetter.cpp 并再次键入 'make' 时,更改没有反映出来。它仅在我输入 'make clean' 然后输入 'make' 时有效。我期望发生的目标文件更新被回显到命令行:

$ make
g++ -c HappyLetter.cpp
g++ -o happy happy.o HappyLetter.o

然而,对HappyLetter.cpp的更新并未反映在happy中。

换个方向问题不成立。也就是说,如果我修改 happy.cpp,更改会在我键入 'make' 后立即反映出来。

我已经在我的 Mac OS X 和 Ubuntu 机器上用三个 make 二进制文件复制了这个问题。所以我一定是在编码中做错了什么。以下是文件的文本,它们与 makefile 位于同一目录中:

happy.cpp

#include "HappyLetter.cpp"

int main()
{
  printf("Hello from happy.cpp!\n");
  HappyLetter *myObj = new HappyLetter();
  myObj->speak();
  return 0;
}

HappyLetter.cpp

#include <cstdio>

class HappyLetter {
  public:
    void speak()
    {
      printf("Hello from HappyLetter.cpp!\n");
    }
};

我认为问题很简单,但我不知道要检查什么。我的一个假设是规则和依赖项的顺序无关紧要。

正如我评论的那样:

首先,你不应该(按照惯例)在你的 happy.cpp 中不 #include "HappyLetter.cpp"(即使这是可行的,但品味很差)。您应该有一个 单独的 头文件(使用常规的 include guard

#ifndef HAPPY_INCLUDED
//// file happy.h
#define HAPPY_INCLUDED 
  class HappyLetter {
 public:
   void speak();
 };
#endif /*HAPPY_INCLUDED*/

(您可以决定在 class HappyLetter 之前的 happy.h 中使用例如 #include <cstdio>;这两种方式都有充分的理由!)

那么你应该有第一个源文件:

// file happy.cpp
 #include <cstdio>
 #include "happy.h"
int main() {
  printf("Hello from happy.cpp!\n");
  HappyLetter *myObj = new HappyLetter();
  myObj->speak();
  delete myObj;
  return 0;
}

顺便说一句,你应该使用 smart pointers!

然后你有了第二个源文件:

 // file happyletter.cpp
 #include <cstdio>
 #include "happy.h"

 void HappyLetter::speak() {
  printf("Hello from HappyLetter.cpp!\n");
 }

最后,一个Makefile(灵感见here),比如:

 # file Makefile
 CXX= g++
 CXXFLAGS= -std=c++11 -Wall -Wextra -g
 RM= rm -f
 .PHONY: all clean

 all: happy-prog

 clean:
    $(RM) *.o *~ happy-prog

 happy-prog: happy.o happyletter.o

 happy.o: happy.cpp happy.h
 happyletter.o: happyletter.cpp happy.h

注意对 happy.h header

的显式依赖

正如我评论的那样,考虑使用 remake-xmake --trace 来调试您的 Makefile。请注意,GNU make 有很多内置规则,运行 make -p 来获取它们。

阅读有关 C++11, notably a tutorial, a good programming in C++ book, have a glance into the standard (e.g. n3337 draft). Read also about make, notably GNU make 的更多信息。

研究一些现有 free software coded in C++ (see sourceforge or github 等的源代码...找到一个)。

(所以你的 C++ 源文件和 Makefile 都错了!)