我正在尝试使用下面的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
标志查看该位置。也不起作用。 :( ..关于如何使其工作的任何想法?
答案 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