如何在make下编译多个文件

问题描述 投票:0回答:1

我有几个 .cpp 和 .hpp 文件。我想使用 make 来编译和连接它们。我怎样才能做到这一点?

    sample.cpp sample.hpp
    sample_2.cpp sample_2.hpp
    sample_3.cpp sample_3.hpp
    ...
    and 
    main.cpp

    I have done :

    default:

             g++ -c sample sample.cpp
             g++ -c sample_2 sample_2.cpp
             g++ -c sample_3 sample_3.cpp

             g++ -o main main.cpp sample sample_2 sample_3

当我在终端上输入 make 时,它给出错误:

 /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 10
c++ makefile linker g++
1个回答
3
投票

每个单独的输出应该是一个 make 目标,而不是拥有一个执行所有操作的

default
目标。这使得 make 能够正常工作,以正确的顺序(或者如果依赖关系图允许的话并行)一次构建一件事,并在每一步正确报告错误。 另外,非常重要的是,通过告诉 make 关于每个单独的目标以及它们所依赖的内容,您可以确保当依赖项更改时 make 将准确地知道由于更改的依赖项而需要重建哪些目标。这是Make 最好的功能。

在您的情况下,最终目标是

main
,因此您希望
default
目标来构建它,您可以通过说
main
main
的先决条件来实现:

default: main

现在你需要说出如何构建

main
,这取决于各种目标文件,所以我们告诉make:

main: main.o sample.o sample_2.o sample_3.o

这表示它取决于那些目标文件(它们是其先决条件),因此将首先构建它们。这些对象中的每一个都是将单独构建的另一个 make 目标。

当所有先决条件都建立后,将使用一个配方将它们链接到

main
,因此我们需要向上述目标添加一个配方:

main: main.o sample.o sample_2.o sample_3.o
        g++ main.o sample.o sample_2.o sample_3.o -o main

Make 有很多缩写来简化事情,例如

$(CXX)
是 C++ 编译器,
$@
表示当前目标,
$^
表示当前目标的先决条件,因此您可以将该规则简化为:

main: main.o sample.o sample_2.o sample_3.o
        $(CXX) $^ -o $@

这实际上就是您所需要的,Make 已经知道如何使用其内置规则构建

.o
先决条件,因此它将看到一个名为
main.cpp
的文件,并知道它可以编译该文件以创建
main.o
,并看到
sample.cpp
并将其编译为
sample.o
等。它将从 makefile 创建一个依赖关系图来决定需要哪些目标为了构建
default
(这意味着它决定需要
main
并且需要
main.o
sample.o
等,并且它们需要已经存在的
main.cpp
sample.cpp
等,所以它可以开始构建先决条件,直到它拥有链接所需的一切
main
,然后它就可以做到这一点并且完成。)

现在,如果您更改

sample_2.cpp
并再次运行
make
,它将发现
sample_2.o
已过时,需要重新编译,但其他
.o
文件仍然可以(它们比
.cpp
更新)他们依赖的文件),所以它将重新编译
sample_2.o
并且重新链接
main
并且不重建其他所有内容

事实上,您可以通过使用默认配方将对象链接到可执行文件来进一步简化它:

LINK.o = $(CXX)

default: main

main: main.o sample.o sample_2.o sample_3.o

这就是您所需要的!但使用更详细的版本通常会更清晰,尤其是对于初学者来说,因为当您不熟悉 Make 的所有自动规则和变量时,更容易自定义。

告诉 make 关于头文件的依赖关系也很有帮助,这样当头文件更改时就会重建。这可以使用编译器自动生成先决条件来完成,但对于简单的情况,您可以直接将其添加到 makefile 中,例如

sample.o: sample.hpp sample.cpp
© www.soinside.com 2019 - 2024. All rights reserved.