Когда мне нужно использовать / иметь make-файл? - PullRequest
0 голосов
/ 28 мая 2019

Я пытаюсь научиться кодировать Raspberry PI. Я пришел от кодирования с использованием Windows и VS Code. Сейчас я использую Linux Mint 19.1 и ssh для доступа к Raspbian 4.14.

Проблема в том, что после долгой битвы с загрузкой библиотеки, которую я пытаюсь использовать, после установки компилятора, создания файла и поиска правильной команды для запуска и включения путей я получаю undefined reference to ошибки.

Я пытаюсь скомпилировать простейший пример кода из 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

main.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
    1. Это
    1. Потребность в makefile

Ища похожие проблемы и надеясь найти какое-то волшебное исправление, я оказался более озадаченным, чем раньше. Я понятия не имею, если то, что я сделал, это то, что я должен был сделать.

    1. Какие файлы cpp связать, если у меня есть только один?
    1. Нужно ли связывать все файлы .cpp и .h, которые есть в библиотеке?
    1. Я ничего не понимаю о makefile или о том, почему он вообще существует.

Моя проблема может быть связана с моей ситуацией, но я верю, что ответы помогут мне в будущих проектах.

Вы можете ответить на все мои вопросы и недоразумения и помочь мне понять, что происходит, или ответить только на вопрос, связанный с названием: Почему makefile?

1 Ответ

3 голосов
/ 28 мая 2019

Проблема в том, что после долгой битвы с загрузкой библиотеки, которую я пытаюсь использовать, после установки компилятора, создания файла и поиска правильной команды для запуска и включения путей, которые я получаю неопределенная ссылка на ошибки.

Уже имеется множество вопросов и ответов о SO, относящихся к таким проблемам, особенно Что такое неопределенная ссылка / нерешенная внешняя ошибка символа и как ее исправитьэто?

Возможные исправления, которые я нашел:

    1. Ссылка .cpp файлы в строгом порядке, когдасоставление: sudo g++ main1.cpp main2.cpp
  • [ТАК вопрос с ответами, примерно такими же, как и предыдущий]

Обычно не имеет значения.Хотя link порядок различных объектов / библиотек является существенным, это редко влияет на случай, когда все необходимые исходные файлы C и / или C ++ указаны в одной и той же команде компиляции.

  • Необходимость make-файла

Использование make по сути не решает проблему, и, конечно, не обязательно длярешение проблемы.Написание make-файла, который обеспечивает успешную сборку, будь то напрямую или с помощью инструмента сборки, такого как CMake или Autotools, требует от вас хотя бы на высоком уровне понимания того, как работают компиляторы и компоновщики, каковы их входы и выходы и каковы ихЗначения аргументов и опций.

    1. Какие файлы cpp связать, если у меня есть только один?

Вы не связываете .cpp (напрямую) вообще.Вы компилируете его и связываете результат с любыми необходимыми библиотеками и любыми другими объектами.g++ по умолчанию попытается сделать все это за один шаг, и в этом случае процесс обычно называется «компиляцией», а не «компоновкой», даже если обе функции выполняются.g++ можно сделать только для компиляции без привязки, указав для нее опцию -c (как это обычно бывает в make-файлах), и она с радостью будет связывать объекты и библиотеки без компиляции, если вы неНазовите ему любые исходные файлы.

В любом случае, ваш случай совсем не относится к одному .cpp файлу.Это ваш .cpp файл плюс всех библиотек, которые вы пытаетесь использовать.

  • Нужно ли связывать все файлы .cpp и .h, которые есть в библиотеке?

Вам не нужно компилировать (напрямую) или ссылка на любые файлы .h.Но если вы хотите использовать библиотеку, исходники которой вы скачали, вам do необходимо скомпилировать все источники, и вам, вероятно, следует связать их в реальную библиотеку.Кроме того, если вы не создаете и не используете статическую библиотеку, вам также следует установить библиотеку, которую вы строите.Похоже, что исходные тексты библиотеки включают в себя make-файл, поэтому вам рекомендуется использовать make для выполнения этих шагов.

  • Я ничего не понимаю в makefile или в том, почему он вообще существует.

Makefile - это входные данные для make.Хорошо написанный определяет правила для того, как построить одну или более "целей", и выражает предпосылки (обычно исходные источники или другие цели) для этого.make использует их вместе с набором встроенных правил, чтобы выяснить, какие шаги нужно предпринять, чтобы построить цели, которые вы просите его построить, а также какие шаги он может пропустить.Например, обычно пишут make-файлы, так что если вы создаете проект с несколькими источниками, изменяете только один исходный файл, а затем снова собираете, только измененный исходный код перекомпилируется.

Это может показаться тривиальным, когда вы привыкли к проектам с небольшим количеством источников, но это становится важным в более крупных проектах, где полная перестройка стоит дорого - в некоторых случаях много часов.Но даже если полная сборка занимает всего несколько минут, а если вам действительно нужно было потратить всего несколько секунд, то это в целом тратит впустую время за полный рабочий день.

В целом, тогда:

Когда мне нужно использовать / иметь make-файл?

Никогда.Но предоставление хорошего и использование make для сборки вашего проекта имеет следующие преимущества:

  • , запоминающий все необходимые команды сборки, включая опции и аргументы, в постоянной, действенной форме и, следовательно,
  • , обеспечивающий согласованные автоматические сборки.

Это также может быть достигнуто простым сценарием сборки, но make также может дать вам

  • более быстрая сборка за счет создания только тех частей, которые устарели, и
  • встроенных знаний о том, как строить определенные виды целей из соответствующих источников.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...