2

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

4

1 回答 1

4

我的猜测是这是一个 C 库,并且您使用的头文件并非设计为由 C++ 编译器导入(函数定义周围libccn.a没有块)。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
于 2013-02-04T10:09:42.923 回答