我知道有很多关于它的帖子,但是我已经尝试过,但我仍然在链接我的库时收到错误。
在我当前的目录中,我创建了一个动态库
/bin/library_test.so
源代码和包含文件像往常一样在
./lib/ and ./src/
然后我正在尝试编译一个简单的 main.cpp并通过
g++ main.cpp -I/lib/ -L/bin/ -llibrary_test
但是我不断收到错误,例如"ExampleClass"未在此范围内声明,这意味着我没有链接库,对吗?由于此类包含在我的库中 cpp/头文件中。
我在链接中缺少某些内容,还是应该在我的主.cpp文件中添加一些包含命令?
在命令和设置中有几个内容需要检查。另请查看C++编译阶段。您需要了解这一点才能充分了解您的问题。
查看您发表的评论,您有 3 个主要问题:
- 编译(预处理后、组装和链接之前(
- 链接(编译器运行时仍在(
- 运行时链接(在执行已编译的二进制文件期间(
汇编
您收到的错误处于编译阶段,在链接二进制文件之前。此错误可能由于以下原因而生成:
-
您忘记了定义
ExampleClass
的标头的#include
-
您没有告诉编译器搜索标头的正确路径。在您的命令中,您告诉编译器搜索
/lib
(从文件系统根目录开始的目录(中的标头,而我很确定您想在相对于当前工作目录的目录中搜索它们,这意味着-Ilib -Isrc
.顺便说一下,我强烈建议您将所有源文件放在
src
目录中,将所有标头放在include
目录中,这通常在复杂的C/C++项目中完成。
连接
更正编译阶段后,您可能会遇到链接问题,因为您的库未遵循 linux 中用于共享对象的命名约定。库LIBRARYNAME
的文件名应为libLIBRARYNAME.so
。
在某些情况下,您可能有多个版本的库,因此可以在so
扩展名之后添加具有语义版本控制约定的版本(例如,libLIBRARYVERSION.so.2.1
库的版本 2.1
(。要链接上述库,您必须使用-lLIBRARYNAME
选项。
为了在链接时通知编译器在哪里可以找到库,您应该提供带有-L
的路径,但此选项仅通知编译器,而不会在可执行文件中保存此类库的位置。
运行时链接
在这种情况下,有两种主要情况(我会有点草率,但只是为了指出正确的方向。完整的解释可能需要更多空间...和时间(:
- 您可以使用
rpath
对二进制文件中共享库的位置进行硬编码,但是如果您分发应用程序,最终用户必须将 lib 放在您通过 rpath 指定的相同路径中,这就是我倾向于避免此解决方案的原因。 - 现代 Linux 系统能够搜索所需的共享对象(这就是存在命名约定的原因(。搜索在受信任的目录中执行,搜索路径通过
ldconfig
配置文件(或$LD_LIBRARY_PATH
env 变量(进行配置。在搜索路径中安装新库时,应刷新运行时链接器的缓存(同样,这是通过ldconfig
或重新启动完成的(。我强烈建议您阅读有关ldconfig
的链接,因为它解释了如何配置新的搜索路径(例如/usr/local/lib
(。
您可以通过命令ldd BINARY_NAME
检查二进制文件是否能够找到所有必需的共享对象(在您的例子中为ldd a.out
(。