c++ - 我什么时候需要使用/拥有 makefile?

标签 c++ c linux makefile raspberry-pi

我正在尝试学习如何在 Raspberry PI 上编码。 我来自使用 Windows 和 VS Code 进行编码。 现在我使用 Linux Mint 19.1 和 ssh 访问 Raspbian 4.14。

问题是,经过长时间的下载我尝试使用的库后,安装编译器、创建文件并找到正确的命令来运行并包含路径后,我得到了 undefined 引用 错误。

我正在尝试编译 https://github.com/hzeller/rpi-rgb-led-matrix 中最简单的示例代码 因为我是从这个项目开始的。我没有任何其他代码或示例。

以下是我在命令行中编写的命令:

sudo apt-get install g++
mkdir 4panel
cd 4panel
sudo nano main.cpp
git clone https://github.com/hzeller/rpi-rgb-led-matrix.git
sudo g++ -Wall -Irpi-rgb-led-matrix/include  main.cpp -o main

以下命令应该是:

sudo chmod +x main
./main

ma​​in.cpp 包含与 https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/examples-api-use/minimal-example.cc 相同的代码

#include "led-matrix.h"

#include <unistd.h>
#include <math.h>
#include <stdio.h>
#include <signal.h>

using rgb_matrix::GPIO;
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;

volatile bool interrupt_received = false;
static void InterruptHandler(int signo) {
  interrupt_received = true;
}

static void DrawOnCanvas(Canvas *canvas) {
  /*
   * Let's create a simple animation. We use the canvas to draw
   * pixels. We wait between each step to have a slower animation.
   */
  canvas->Fill(0, 0, 255);

  int center_x = canvas->width() / 2;
  int center_y = canvas->height() / 2;
  float radius_max = canvas->width() / 2;
  float angle_step = 1.0 / 360;
  for (float a = 0, r = 0; r < radius_max; a += angle_step, r += angle_step) {
    if (interrupt_received)
      return;
    float dot_x = cos(a * 2 * M_PI) * r;
    float dot_y = sin(a * 2 * M_PI) * r;
    canvas->SetPixel(center_x + dot_x, center_y + dot_y,
                     255, 0, 0);
    usleep(1 * 1000);  // wait a little to slow down things.
  }
}

int main(int argc, char *argv[]) {
  RGBMatrix::Options defaults;
  defaults.hardware_mapping = "regular";  // or e.g. "adafruit-hat"
  defaults.rows = 32;
  defaults.chain_length = 1;
  defaults.parallel = 1;
  defaults.show_refresh_rate = true;
  Canvas *canvas = rgb_matrix::CreateMatrixFromFlags(&argc, &argv, &defaults);
  if (canvas == NULL)
    return 1;

  // It is always good to set up a signal handler to cleanly exit when we
  // receive a CTRL-C for instance. The DrawOnCanvas() routine is looking
  // for that.
  signal(SIGTERM, InterruptHandler);
  signal(SIGINT, InterruptHandler);

  DrawOnCanvas(canvas);    // Using the canvas.

  // Animation finished. Shut down the RGB matrix.
  canvas->Clear();
  delete canvas;

  return 0;
}

错误:

/tmp/cci8MGL5.o: In function `main':
main.cpp:(.text+0x264): undefined reference to `rgb_matrix::RGBMatrix::Options::Options()'
main.cpp:(.text+0x2a8): undefined reference to `rgb_matrix::CreateMatrixFromFlags(int*, char***, rgb_matrix::RGBMatrix::Options*, rgb_matrix::RuntimeOptions*, bool)'
collect2: error: ld returned 1 exit status

我发现的可能的修复:

    1. 编译时按照严格的顺序链接.cpp文件:sudo g++ main1.cpp main2.cpp
  • This
  • 需要makefile

在寻找类似的问题并希望找到一些神奇的解决方案时,我最终比以前更加困惑。我不知道我所做的是否是我应该做的。

    1. 如果我只有一个 cpp 文件,要链接哪些文件?
  • 我需要链接该库拥有的所有 .cpp 和 .h 文件吗?
  • 我完全不明白 makefile 或者它为何存在。

我的问题可能针对我的具体情况,但我相信答案将对我 future 的项目有所帮助。

您可以自由地回答我的所有问题和误解,并帮助我了解正在发生的事情,或者只回答与标题相关的问题:为什么 makefile

最佳答案

The problem is that, after a long battle with downloading the library that I am trying to use, after installing a compiler, creating a file, and finding the right command to run and include paths I get undefined reference to errors.

已经有很多与此类问题相关的问题和答案,特别是 What is an undefined reference/unresolved external symbol error and how do I fix it?

Possible fixes that I found:

    1. Link .cpp files in a strict order when compiling: sudo g++ main1.cpp main2.cpp
    1. [SO question with answers saying roughly the same as the previous]

通常不相关。尽管不同对象/库的链接顺序很重要,但这很少影响在同一编译命令中指定所有所需的 C 和/或 C++源文件的情况。

    1. The need of a makefile

使用make本质上并不能解决问题,而且它当然不是解决问题的必要。编写一个提供成功构建的 makefile,无论是直接还是通过 CMake 或 Autotools 等构建工具,都需要您至少在较高层次上了解编译器和链接器的工作原理、它们的输入和输出是什么以及它们的作用是什么。参数和选项的含义。

    1. What cpp files to link if I have just one ?

您根本不链接.cpp(直接)。您编译它并将结果链接到任何需要的库和任何其他对象。默认情况下,g++ 将尝试一步完成所有操作,在这种情况下,该过程通常称为“编译”,而不是“链接”,即使这两个函数都已执行。通过指定 -c 选项(事实证明,这在 makefile 中很常见),可以使 g++ 仅进行编译,而不进行链接,并且它会很高兴如果您没有为其命名任何源文件,则链接对象和库而不编译任何内容。

无论如何,您的情况根本不仅仅是一个 .cpp 文件。这是您的一个.cpp 文件加上您尝试使用的库的所有文件。

    1. Do I need to link all the .cpp and .h files that the library has ?

您不需要编译(直接)链接任何.h 文件。但是,如果您想使用下载了源代码的库,您确实需要编译所有源代码,并且您可能应该将它们链接到实际的库中。此外,除非您生成并使用静态库,否则您还应该安装您构建的库。看起来库源代码包含一个 makefile,因此强烈建议您使用 make 来执行这些步骤。

    1. I don't understand a thing about makefile or why it even exists.

makefile 是 make 的输入。一份写得好的定义了如何构建一个或多个“目标”的规则,并表达了这样做的先决条件(通常是原始来源或其他目标)。 make 使用这些以及一组内置规则来确定需要采取哪些步骤来构建您要求其构建的目标,以及它可以跳过哪些步骤。例如,通常会编写 makefile,以便在构建多源项目时仅修改一个源文件,然后再次构建,则仅重新编译修改后的源文件。

当您习惯于只有少数来源的项目时,这可能看起来微不足道,但在较大的项目中,它变得很重要,因为在这些项目中,完全重建的成本很高——在某些情况下需要花费很多时间。但即使完整的构建只需要几分钟,如果您真的只需要花费几秒钟,那么一整天的工作都会浪费大量时间。

总的来说,那么:

When do I need to use/have a makefile?

从来没有。但提供一个好的 make 并使用 make 来构建您的项目具有以下优点:

  • 以持久、可操作的形式记住所有所需的构建命令,包括选项和参数,因此
  • 提供一致的自动化构建。

这些也可以通过简单的构建脚本来实现,但是make也可以给你

  • 通过仅构建那些过时的部分来加快构建速度,并且
  • 关于如何从相应来源构建特定类型目标的内置知识。

关于c++ - 我什么时候需要使用/拥有 makefile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56344144/

相关文章:

c++ - 如何为多态数据类型动态分配内存?

c++ - 创建 CvSVM vector 的 vector (数组)

c - 为什么 'typedef struct' 没有在 C 中成为可选的?

CCS C编译器,命令行指令

c - 如何在 timerfd_create 中检查定时器到期

linux - 获取按时间排序的文件名

c++ - 检查 std::cin operator>> 是否读取了整行

c++ - 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?

C,代码 :Block, 另一个 sigsegv,列出

linux - 使用用户空间进程来协助内核模块