I'm trying to compile an executable with GCC but I'm getting an undefined reference to error even though the function in question is defined in another header file, compiled in another source file and compiled to a .o file.
The error is raised by a call to a defined function in an intermediary .o file (file graph.o).
Here's the code:
makefile:
kosaraju: kosaraju.o string_linked_list.o graph.o [...]
gcc -o ../kosaraju kosaraju.o string_linked_list.o graph.o [...] -Wall
make clean
kosaraju.o:
gcc -o kosaraju.o kosaraju.c -c -Wall
graph.o:
gcc -o graph.o graph.c -c -Wall
string_linked_list.o:
gcc -o string_linked_list.o string_linked_list.c -c -Wall
...
graph.c
#include "string_linked_list.h"
#include "graph.h"
#include ...
...
void dfs1_step(char * node, string_linked_list * topological_sort, /*more stuff*/)
{
{
// DFS_step implementation
}
// after iteration marks as visited
string_linked_list_push(topological_sort, node);
}
string_linked_list.h
#ifndef STRING_LINKED_LIST
#define STRING_LINKED_LIST
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
typedef struct string_linked_list_node
{
char * value;
struct string_linked_list_node * next;
} string_linked_list_node;
typedef struct string_linked_list
{
struct string_linked_list_node * head;
struct string_linked_list_node * tail;
uint16_t count;
} string_linked_list;
bool string_linked_list_push(string_linked_list * list, char * value);
// more prototypes
#endif
string_linked_list.c
#include "graph.h"
#include "string_linked_list.h"
#include //more stuff
// Problematic function
bool string_linked_list_push(string_linked_list * list, char * value)
{
string_linked_list_node * new_node = malloc(sizeof(string_linked_list_node));
new_node->value = calloc(1, NODE_ID_LEN);
if (new_node == NULL || new_node->value == NULL)
{
return false;
}
strncpy(new_node->value, value, NODE_ID_LEN);
new_node->next = list->head->next;
list->head->next = new_node;
return true;
}
// more functions
the error I get after executing make
:
gcc -o ../kosaraju kosaraju.c scanner.o map.o string_linked_list.o graph.o -Wall
/usr/bin/ld: graph.o: in function `dfs1_step':
graph.c:(.text+0x48a): undefined reference to `string_linked_list_push'
collect2: error: ld returned 1 exit status
Any insights on the reason? I've also tried to link string_linked_list
directly into graph.o
but had the same error.
I have implemented the string_linked_list_push
in the correct file, I've checked if the signature matched it's definition in the header file, I've tried to link it directly into graph.o
multiple times:
graph.o: string_linked_list.o
gcc -o graph.o string_linked_list.o graph.c -Wall
and also:
graph.o:
gcc -o graph.o string_linked_list.c graph.c -Wall
(I've actually tried with and without the -c
option.
make
doesn't know that it needs to re-compile string_linked_list.o
whenever string_linked_list.c
changes, because you didn't tell it that.
You asked it to link the program, so it does that, with the perfectly good .o files it already has, which don't have a string_linked_list_push
function because you hadn't written that function last time you compiled that file.
And make
doesn't see that you changed the file and added the next function, because you didn't tell it to do that. Solution: Tell it to do that.
Change:
string_linked_list.o:
to:
string_linked_list.o: string_linked_list.c
and do the same for the rest of the .o files.
There are shorter ways to write makefiles, but I'll leave you to explore them yourself when you get around to it.