【问题标题】:C++ Makefile Dependencies: What Files Do Object Files Depend On?C++ Makefile 依赖关系:对象文件依赖于哪些文件?
【发布时间】:2019-12-14 22:25:43
【问题描述】:

我对 .cpp 文件的 Makefile 依赖项有点困惑。例如,假设我有一个包含 Point.h 和 Rectangle.h 的文件 main.cpp。我认为 main.o 的 Makefile 依赖行看起来像:

main.o: main.cpp

但似乎大多数人都会这样做:

main.o: main.cpp Point.h Rectangle.h

我不明白为什么。目标文件是在链接之前创建的,对吧?因此,当 main.cpp 编译为 main.o 时,它对 Point 和 Rectangle 函数的引用在某种程度上仍然是未解析的引用。然后,在生成最终可执行文件时,链接器使用 Point 和 Rectangle 的机器代码解析引用。换句话说,如果我更改 Point.h 或 Rectangle.h,main.o 并不会真正受到影响。最终的可执行文件确实依赖于所有三个,但 main.o 不依赖。我的想法有什么问题?

【问题讨论】:

    标签: c++ makefile dependencies


    【解决方案1】:

    假设您的 Point.h 头文件定义了一个类,如下所示:

    class Point {
    
        int x;
    
        int y;
    
        int hash() const
        {
              return x+y;
        }
    };
    

    这个类可能有其他东西,或者其他一些类方法。这只是一个例子。

    您的main.cpp 调用了一些Pointhash() 方法。然后你编译它。

    现在你回去,编辑这个头文件:

        int hash() const
        {
              return x*y;
        }
    

    您不会更改 main.cpp 中的任何内容。

    但是你显然必须重新编译它,因为它现在应该做一些不同的事情,因为它调用hash()

    头文件中几乎任何类型的更改都可能影响包含它的任何.cpp文件,因此它们都必须重新编译。

    #include 在逻辑上等同于将带有#include 的行替换为包含文件的全部内容。

    因此,如果您更改头文件中的任何内容,它在逻辑上等同于更改包含它的.cpp 文件中的某些内容。受它影响的是main.o 中的编译代码,而不仅仅是最终的可执行文件。在这里,您只需重新链接 main.o 中仍使用您现在已更改的 hash() 定义的相同代码。

    【讨论】:

    • 我不明白为什么必须重新编译 main.o。 main.o 编译的代码不包含 hash() 的机器代码,对吧?它只包含对 hash() 的引用。 hash() 的机器代码直到稍后才会链接,对吧?
    • 它肯定包含hash() 的代码,因为你只是链接main.o,没有别的。如果不在main.o 中,你认为它在哪里?链接器不会凭空创建代码,并将其与main.o 中的任何其他内容链接。您还需要关注我的回答中解释#include 是什么以及它是如何工作的部分。头文件中的所有内容,一旦从.cpp 中包含,就好像它在.cpp 中开始并且头文件不存在。这就是 C++ 的工作原理。因此,如果您更改该代码,则必须重新编译它。
    • 我现在明白了。谢谢!
    猜你喜欢
    • 2017-10-03
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-08-05
    相关资源
    最近更新 更多