何时需要使用/拥有一个makefile?

11 浏览
0 Comments

何时需要使用/拥有一个makefile?

我正在尝试在树莓派上学习如何编码。\n我之前使用Windows和VS Code进行编码。\n现在我正在使用Linux Mint 19.1和ssh来访问Raspbian 4.14。\n问题是,在下载我要使用的库进行了漫长的战斗后,安装了编译器,创建了一个文件,并找到了正确的运行命令和包含路径后,我遇到了“undefined reference to”错误。\n我正在尝试编译来自https://github.com/hzeller/rpi-rgb-led-matrix的最简单示例代码,因为我从这个项目开始。我没有其他代码或示例。\n以下是我在命令行中编写的命令:\n

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

\n接下来的命令应该是:\n

sudo chmod +x main
./main

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

#include "led-matrix.h"
#include 
#include 
#include 
#include 
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) {
  /*
   * 让我们创建一个简单的动画。我们使用画布来绘制像素。我们在每个步骤之间等待以获得较慢的动画。
   */
  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);  // 等待一段时间以减慢速度。
  }
}
int main(int argc, char *argv[]) {
  RGBMatrix::Options defaults;
  defaults.hardware_mapping = "regular";  // 或者例如 "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;
  // 建立一个信号处理程序以在接收到CTRL-C等时干净地退出。DrawOnCanvas()例程正在寻找这个。
  signal(SIGTERM, InterruptHandler);
  signal(SIGINT, InterruptHandler);
  DrawOnCanvas(canvas);    // 使用画布。
  // 动画完成。关闭RGB矩阵。
  canvas->Clear();
  delete canvas;
  return 0;
}

\n错误:\n

/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

\n我找到的可能修复方法:\n

    \n

    1. \n

    2. 在编译时按顺序链接.cpp文件:sudo g++ main1.cpp main2.cpp
    3. \n

  • \n

    1. \n

    2. 这个
    3. \n

  • \n

    1. \n

    2. 需要一个makefile
    3. \n

  • \n

\n在搜索类似问题并希望找到一些神奇的修复方法时,我变得更加困惑。我不知道我做的是否是我应该做的。\n

    \n

    1. \n

    2. 如果我只有一个cpp文件,应该链接哪些cpp文件?
    3. \n

  • \n

    1. \n

    2. 我需要链接库中的所有.cpp和.h文件吗?
    3. \n

  • \n

    1. \n

    2. 我对makefile一无所知,也不知道它为什么存在。
    3. \n

  • \n

\n我的问题可能特定于我的情况,但我相信答案将对我以后的项目有所帮助。\n您可以回答我所有的问题和误解,并帮助我理解正在发生的事情,或者只回答与标题相关的问题:为什么需要makefile

0
0 Comments

什么时候需要使用/拥有一个makefile?

问题的出现原因:

根据上述内容,问题的出现是因为在下载所需库文件、安装编译器、创建文件以及找到正确的命令和包含路径之后,仍然出现了“undefined reference to”错误。

解决方法:

根据给出的一些可能的解决方法,可以尝试以下操作:

1. 编译时严格按照顺序链接.cpp文件:sudo g++ main1.cpp main2.cpp

2. 编译时链接所有需要的.cpp和.h文件

3. 使用makefile来解决问题

关于makefile的问题和解释:

- 使用make并不是解决问题的直接方法,也不是解决问题的必要条件。编写一个能够成功构建的makefile,无论是直接构建还是通过CMake或Autotools等构建工具,都要求你至少在高层次上了解编译器和链接器的工作原理、输入和输出、参数和选项的含义。

- 不需要直接链接.cpp文件,而是需要将其编译并将结果链接到任何需要的库和其他对象上。通常情况下,g++会默认在一步中完成这些操作,即使这两个功能都有执行。如果想要只编译而不链接,可以给g++指定-c选项。对于只链接对象和库而不编译任何内容的情况,也可以不给g++指定任何源文件。

- 如果想要使用下载的库文件,需要编译所有源文件,并将它们链接到一个实际的库中。此外,除非生成和使用静态库,否则还应该安装构建的库。根据库的源文件中是否包含makefile,可以使用make来执行这些步骤。

- makefile是make的输入文件。良好编写的makefile定义了如何构建一个或多个“目标”,并表达了构建这些目标所需的先决条件(通常是原始源文件或其他目标)。make结合内置规则使用这些信息来确定构建目标所需的步骤,以及可以跳过的步骤。通常,可以编写makefile,以便在构建一个多源项目时,只有修改的源文件会被重新编译。

- 使用makefile和make构建项目具有以下优点:记录所有所需的构建命令(包括选项和参数)的持久可行形式,从而提供一致的自动化构建;通过只构建过时的部分来实现更快的构建;内置了从相应源文件构建某些类型目标的知识。

不是必须使用makefile来解决问题,但提供一个良好的makefile并使用make来构建项目具有以下优点:记录构建命令的持久可行形式,提供一致的自动化构建,通过只构建过时的部分来实现更快的构建,以及内置了从相应源文件构建某些类型目标的知识。

感谢您耐心回答我所有的问题。尽管问题仍然存在,但我现在对编译器、链接器和makefile的目的有了更好的了解。

0