C не может скомпилировать - символы (символы) не найдены для архитектуры x86_64

Имея серьезную проблему с моим C-кодом, я просто, похоже, не могу его скомпилировать, и я действительно не могу понять, почему.

Я пытался исследовать онлайн и не могу найти решение проблемы, есть ли у вас какие-либо идеи?

Спасибо за ваше время!

Undefined symbols for architecture x86_64:
  "_Insert", referenced from:
      _InsertNode in part1.o
     (maybe you meant: _InsertNode)
  "_Create", referenced from:
      _findShortestPaths in part1.o
  "_DeleteMin", referenced from:
      _findShortestPaths in part1.o
  "_decreaseKey", referenced from:
      _findShortestPaths in part1.o
  "_GetMin", referenced from:
      _findShortestPaths in part1.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [part1] Error 1

Снимки из part1.c

#include "limits.h"
#include "pegBinaryHeap.h"

void InsertNode(int distance, Node* node, PriorityQueue PQ) {
  ...
  Insert(*item, PQ);
}

...

int* findShortestPaths(Graph *graph, int start) {
  ...

  //Priority queue ordered by distance
  PriorityQueue pq = Create(graph->MaxSize);
  for(int i = 0; i < graph->MaxSize; i++) {
    ...
  }

  //While the queue isn't empty:
  while((currentPqItem=GetMin(pq)) != NULL) { 
    ...
    DeleteMin(pq);

      //for each node accesable from currentNode
    List *currentNeighbour = currentNode.outlist;

    while(currentNeighbour!=NULL) {
      ...
        decreaseKey(currentNode.id, newDistance, pq);
    } // end for
  }// end while
}

int main(int argc,char *argv[])
{
  Graph mygraph;
  return 0;
}

И файл .h, который, как представляется, жалуется на

#include "graph.h"

struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;

typedef struct {
  int distance;
  Node *node;
} QueueType;

PriorityQueue Create( int MaxSize );
void Destroy( PriorityQueue H );
int Insert( QueueType Item, PriorityQueue H );
QueueType DeleteMin( PriorityQueue H );
QueueType* GetMin( PriorityQueue H );
void decreaseKey(int nodeId, int value, PriorityQueue H);

Ответ 1

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

part1.o использует функции, определенные вами в последнем .h файле, и реализации не удается найти. Когда вы связываете свою программу, вам нужно убедиться, что вы связываетесь в объектных файлах (или библиотеках), которые содержат реализации этих функций. Вероятно, вы сделали что-то вроде:

gcc part1.c -o myapp

и поэтому линкер не имеет всех частей головоломки.

Если вы хотите скомпилировать по частям, вам необходимо:

gcc -c part1.c -o part1.o
gcc -c implementations.c -o implementations.o 
gcc implementations.o part1.o -o myapp

Здесь все файлы .c скомпилированы в файлы объектов (.o) отдельно, а затем связаны вместе в исполняемый файл. Или вы можете сделать все сразу:

gcc part1.c implementations.c -o myapp

Если реализации находятся в библиотеке (libimplementations.a):

gcc part1.c -Lpath/to/libs -limplementations -o myapp

Ответ 2

Я хотел бы добавить, что получаю аналогичную ошибку компиляции. См. Ниже.

Undefined symbols for architecture x86_64:
  "_add", referenced from:
   _load in file.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1

Я решил эту проблему, выполнив прототип функций add(), который я создал в моем файле заголовка. После реализации я больше не получал эту ошибку. Может помочь кому-то другому.

Ответ 3

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

Ответ 4

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

(да, это должен быть комментарий, а не ответ, но я не могу прокомментировать вопросы по какой-то причине)