修复 "undefined reference to" ft. makefile.txt 和 pthreads

Fixing "undefined reference to" ft. makefile.txt and pthreads

所以,我正在开发一个多线程程序并准备编译,但我 运行 陷入我认为是链接器错误的地方。

我确定我的所有文件都包含我的头文件,并且我已经正确地外部化了相关变量。但是我仍然认为头文件存在我没有看到的问题。 makefile 也有可能发挥作用。

这是我的生成文件。我真的很新,我在这里遇到的最大问题是我是否正确地包含了 pthread 库。 (我在 Linux 服务器上使用 GNU):

CFLAGS=-I. -g -pthread

ODIR=obj

DEPS = simpleServer.h
OBJ = Logger.o logQueue.o simpleServer.o SpellChecker.o Worker.o workQueue.o open_listenfd.o


%.o:: %.c %(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

server: $(OBJ)
    gcc -o $@ $^ $(CFLAGS)

这是我遇到的错误(我用 .. 删除了重复项):

cis-lclient11:~/proj3/v0.1>make -f makefile.txt
gcc -o server Logger.o logQueue.o simpleServer.o SpellChecker.o Worker.o workQueue.o open_listenfd.o -I. -g -pthread

Logger.o: In function `logger':
/proj3/v0.1/Logger.c:12: undefined reference to `logLock'.
/proj3/v0.1/Logger.c:14: undefined reference to `logCond'
.
.
/proj3/v0.1/Logger.c:20: undefined reference to `logFile'

SpellChecker.o: In function `spellCheck':
/proj3/v0.1/SpellChecker.c:14: undefined reference to `dic' 
.
.
/proj3/v0.1/SpellChecker.c:43: undefined reference to `logLock'
/proj3/v0.1/SpellChecker.c:45: undefined reference to `logCond'

Worker.o: In function `worker':
/proj3/v0.1/Worker.c:14: undefined reference to `workLock'
/proj3/v0.1/Worker.c:19: undefined reference to `workCond'

collect2: error: ld returned 1 exit status
makefile.txt:14: recipe for target 'server' failed
make: *** [server] Error 1

头文件相关部分:

extern FILE *dic;
extern FILE *logFile;
extern pthread_mutex_t workLock, logLock;
extern pthread_cond_t workCond, logCond;

初始化(在 simpleServer.c 中):

pthread_mutex_t workLock, logLock;
pthread_cond_t workCond, logCond;
FILE *logFile = fopen("log.txt", "w");
FILE *dic = fopen(argv[2], "r");

抱歉代码太长,但我已经花了 3 个小时没有取得任何进展,并且很想看到我犯的所有编译器错误。

您的初始化包括函数调用的事实:

pthread_mutex_t workLock, logLock;
pthread_cond_t workCond, logCond;
FILE *logFile = fopen("log.txt", "w");
FILE *dic = fopen(argv[2], "r");

似乎暗示这段代码在一个函数中。这意味着这些实际上是包含它们的函数的局部变量,不是头文件中声明的extern变量的定义。

相反,您应该在一个 .c 文件中在文件范围内(在任何函数之外)定义这些变量:

pthread_mutex_t workLock = PTHREAD_MUTEX_INITIALIZER, logLock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t workCond = PTHREAD_COND_INITIALIZER, logCond = PTHREAD_COND_INITIALIZER;
FILE *logFile, *dic;

然后在函数中你可以调用 fopen(),但引用全局变量而不是声明新的局部变量:

logFile = fopen("log.txt", "w");
dic = fopen(argv[2], "r");

您仍然需要在 Makefile 中使用正确的 link 顺序 - 依赖外部对象的 .o 文件必须 .o 文件之前定义那个对象。