使不更新可执行文件
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
-x
或 make --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
都错了!)
我编写了以下 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
-x
或 make --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
都错了!)