undefined引用静态库makefile

时间:2013-02-04 09:57:17

标签: makefile undefined-reference

我正在尝试使用下面的makefile创建程序可执行文件时链接静态库。

IDIR =../inc
CC=g++ -g
CFLAGS=-I$(IDIR)
WFLAGS=-Wall -W
OFLAGS=-O3
DLINUX=-D_LINUX

ODIR=obj
LDIR =../lib
LIBS=-lm

_OBJ = testclient.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))

$(ODIR)/testclient.o: testclient.c
    $(CC) -c $< $(CFLAGS) -o $@
$(ODIR)/file2.o: file2.c
    $(CC) -c $< $(CFLAGS) -o $@

testclient: $(OBJ)
    $(CC) -o $@ $^ $(LIBS) -lccn -pthread 

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

我已尝试通过更改“-lccn”参数的顺序来检查函数是否存在于库中(nm libccn.a在其中提供所需的函数ccn_create())。返回的错误是:

obj/testclient.o: In function `main':
/root/testClient/src/testclient.c:91: undefined reference to `ccn_create()'

图书馆libccn.a位于/usr/local/lib。我还尝试更改目录路径,然后使用-L标志查看该位置。也不起作用。 :( ..关于如何使其工作的任何想法?

1 个答案:

答案 0 :(得分:4)

我的猜测是libccn.a是一个C库,你使用的头文件并不是由C ++编译器导入的(函数定义周围没有extern "C" { }块)。

C ++通过修改函数名称来支持函数重载。将函数放入extern "C" { }块时,C ++禁用名称修改(从而禁用重载)。在您的错误消息中,提到的函数是ccn_create()。注意(),这意味着函数类型是已知的,因此查找的命名是一个错位的名称。

当您执行nm libccn.a时,您会看到真实姓名,它是ccn_create。这不是一个错误的名字。因此,要解决此问题,您需要在export "C" { }块中包围函数定义。最简单的方法是将#include包围在这样一个区块中。

顺便说一下,你可以通过这样做来重现错误。

$ echo 'void ccn_create();' > ccn.h
$ echo '#include "ccn.h"
void ccn_create() { }' > ccn.c
$ echo '#include "ccn.h"
int main () {
  ccn_create();
  return 0;
}' > main.cc
$ gcc -o ccn.o -c ccn.c
$ g++ -o main main.cc ccn.o
Undefined symbols for architecture x86_64:
  "ccn_create()", referenced from:
      _main in cc8XnYRq.o
ld: symbol(s) not found for architecture x86_64
$ echo 'extern "C" {
#include "ccn.h"
}
int main () {
  ccn_create();
  return 0;
}' > main.cc
$ g++ -o main main.cc ccn.o