Исправление "неопределенной ссылки на" ft. Makefile.txt и pthreads - PullRequest
0 голосов
/ 01 апреля 2019

Итак, я работаю над многопоточной программой и готов к компиляции, но я сталкиваюсь с тем, что я считаю ошибками компоновщика.

Я уверен, что все мои файлы содержат моифайл заголовка, и что я должным образом извлек переменные.Однако я все еще думаю, что есть проблема с файлом заголовка, который я не вижу.Также возможно, что make-файл играет роль.

Вот мой make-файл.Я действительно новичок, и самый большой вопрос, который у меня здесь возникает, - правильно ли я включил библиотеку pthread.(Я использую GNU на сервере Linux):

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 часа, не делая никакого прогресса, и ястремится увидеть все ошибки компилятора, которые я сделал.

1 Ответ

1 голос
/ 01 апреля 2019

Тот факт, что ваши инициализации включают вызовы функций:

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 - файл .o, который зависит от внешнего объекта, должен прийти до файла .o, который определяет этот объект.

...