我正在尝试使用 GCC 编译可执行文件,但我得到了未定义的错误引用,即使有问题的函数在另一个头文件中定义,在另一个源文件中编译并编译为 .o 文件。
调用中间 .o 文件(文件 graph.o)中定义的函数会引发错误。
代码如下:
制作文件:
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
...
图.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
执行后我得到的错误
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
对原因有何见解?我也尝试将
string_linked_list
直接链接到 graph.o
但有同样的错误。
我已经在正确的文件中实现了
string_linked_list_push
,我检查了签名是否与头文件中的定义相匹配,我多次尝试将它直接链接到graph.o
:
graph.o: string_linked_list.o
gcc -o graph.o string_linked_list.o graph.c -Wall
还有:
graph.o:
gcc -o graph.o string_linked_list.c graph.c -Wall
(我实际上已经尝试过使用和不使用
-c
选项。
make
不知道它需要重新编译string_linked_list.o
每当string_linked_list.c
改变,因为你没有告诉它。
你要求它链接程序,它就这样做了,它已经有了非常好的 .o 文件,这些文件没有
string_linked_list_push
函数,因为你上次编译那个文件时没有写那个函数。
并且
make
没有看到您更改了文件并添加了下一个功能,因为您没有告诉它这样做。解决方案:告诉它这样做。
变化:
string_linked_list.o:
至:
string_linked_list.o: string_linked_list.c
并对其余的 .o 文件执行相同的操作。
有更短的方法来编写 makefile,但我会让你在有空的时候自己探索它们。
如果您不关心标头依赖项,您的
Makefile
可能会更短:
CC = gcc
CFLAGS = -Wall
kosaraju: kosaraju.o string_linked_list.o graph.o
运行
make -B
强制重建。