C++编译:明明设置了链接库,但链接时找不到符号 undefined reference to ....

可能有多种原因:(如果你遇到了其他原因欢迎在评论区补充)

原因1:依赖库的编译环境与当前环境不同

比如你可能都是在Linux下用g++编译,但是库的linux版本与当前linux版本差异过大

  • 库编译时的glibc版本为2.17
  • 而当前项目编译环境的glibc版本为2.31

可以通过ldd --version查看glibc版本。如果差别过大,那么在当前项目中使用其他环境编译的动态库中的函数,就可能导致undefined reference to …某个函数。

再比如,你都是在Windows下开发C++, 但库和当前使用库的项目分别使用了Visual Studio和mingw64 g++进行编译,同样有很大可能导致无法兼容。

解决方法自然是统一环境,要么在新环境中重新编译库,要么把当前环境调整为原来编译库时的环境。

原因2:项目源码中混合了C和C++源码

比如你现在是想写C++工程的,但是有的源码后缀为.c也就是C源码,那么编译不会出错,但是ld链接阶段会报错undefined reference to C源码中的函数。

解决方法是把C源码中的函数声明添加extern "C", 告诉编译器这是C函数,你在生成符号的时候不要对函数名称进行修饰。C++工程中用到C源码通常是这样搞的:

// 源文件 test.c

void testA()
{
    
    
 
}

void testB()
{
    
    
 
}
// 头文件 test.h
#ifndef __TEST_H__
#define __TEST_H__

#ifdef __cplusplus
extern "C" {
    
    
#endif

void testA();
void testB();

#ifdef __cplusplus
}
#endif

#endif  // __TEST_H__

原因3:可能你设置了隐藏符号

例如,

  • 你可能在cmake中设置了visibility=hidden, 默认隐藏所有符号,然后在C++代码中没有把其他二进制文件需要用到的符号给导出__attribute__((visibility("default")))
  • 也可能是cmake中对编译的库设置了属性,通过version script把除了某几个符号之外的其他符号都隐藏了。

这里所说的符号,简单理解就是代码中的函数、类、以及全局变量等东西。

原因4:类的static变量未定义

原因:可能你在某个类中声明了一个static成员变量,但忘记在源文件中初始化了。

猜你喜欢

转载自blog.csdn.net/weixin_44220976/article/details/135704500