编译时不定义的参考错误不会消失?

时间:2014-11-23 20:41:26

标签: c

我正在上课的代理实验室,并且不明白为什么当我尝试使用make编译我的解决方案时,它会给我"undefined reference to `sem_init'"undefined reference to `Pthread_create' ...等等。它至少在12或15个函数中执行此操作。问题是,它说问题出在csapp.c文件中,但我只能修改并交出proxy.c文件。我正在使用-lpthread编译它,我读过很多人已经摆脱了这些未定义的错误,因为他们没有使用它。因此,当我使用-lpthread标志时,我不知道为什么我仍然会遇到这些问题。

为什么我会收到这些未定义的引用错误,有没有其他任何我可能遗漏的东西?感谢

这是我的make文件:

TEAM = NOBODY
VERSION = 1
HANDINDIR = /afs/cs/academic/class/15213-f02/L7/handin

CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lpthread

OBJS = proxy.o csapp.o

all: proxy

proxy: $(OBJS)

csapp.o: csapp.c
    $(CC) $(CFLAGS) -c csapp.c

proxy.o: proxy.c
    $(CC) $(CFLAGS) -c proxy.c

handin:
    cp proxy.c $(HANDINDIR)/$(TEAM)-$(VERSION)-proxy.c

clean:
    rm -f *~ *.o proxy core

这里只是一些proxy.c文件:

#include "csapp.h"
#include "stdlib.h"
#include "pthread.h"
#include "stdio.h"

//Global variables
sem_t mutex;
sem_t log_mutex;

/*
 * Function prototypes
 */
int parse_uri(char *uri, char *target_addr, char *path, int  *port);
void format_log_entry(char *logstring, struct sockaddr_in *sockaddr, char *uri, int size);
void log_to_file(char * log_entry);
//void handle_request(int *fd);



//WRAPPERS
//Wrapper for rio_readnb that doesn't exit the program
ssize_t Rio_readnb_w(rio_t *rp, void *usrbuf, size_t n)
{
    ssize_t rc;
    if ((rc = rio_readnb(rp, usrbuf, n)) < 0)
    {
        printf("ERROR: Rio_readnb failed!\n");
        return rc;
    }
    return rc;
}

//Wrapper for rio_readlineb that doesn't exit the program
ssize_t Rio_readlineb_w(rio_t *rp, void *usrbuf, size_t maxlen)
{
    ssize_t rc;
    if ((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0)
    {
        printf("ERROR: Rio_readlineb failed!\n");
        return rc;
    }
    return rc;
}

//Wrapper for rio_writen that doesn't exit the program
void Rio_writen_w(int fd, void *usrbuf, size_t n)
{
    if (rio_writen(fd, usrbuf, n) != n)
    {
        printf("ERROR: Rio_writen failed!\n");
        return;
    }
}

1 个答案:

答案 0 :(得分:0)

假设您使用的是GNU make。

您没有在makefile中指定任何链接规则,implicit link rule是:

$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)

其中n.o是您的目标文件。进一步; GNU链接器要求库名称位于应该链接到这些库的目标文件之后,因此如果您将LDFLAGS更改为LDLIBS,那么它可能会解决您的问题。

如果发布makefile尝试执行的实际链接命令,那将非常有用(因此我们可以验证是否正在使用此隐式规则)。当然,您可以编写自己的链接规则,而不是依赖隐式规则。