c++ - 我在 so 文件上构建时缺少哪个编译器标志?

标签 c++ shared-libraries linker-errors

考虑以下三个文件,它们都在同一目录中。

库.h

namespace Foo {
    void bar();
}

库.cc

namespace Foo {
    void bar() { }
}

App.cc

#include "Lib.h"
int main(){
    Foo::bar(); 
}

以下是我尝试过的命令:

g++ -std=c++11 -fPIC -shared -o Lib.o Lib.cc
g++ -std=c++11 -shared -o libLib.so Lib.o

g++  -std=c++11 -o App  App.cc -L. -lLib

不幸的是,最后一行给出了以下 undefined reference 错误。

g++  -std=c++11 -o App  App.cc -L. -lLib
/tmp/ccwtxTdl.o: In function `main':
App.cc:(.text+0x5): undefined reference to `Foo::bar()'
collect2: error: ld returned 1 exit status

我也试过以下同样的错误。

g++ -std=c++11 -o App App.cc libLib.so

这是 nm libLib.so 的输出,它似乎不包含 bar

0000000000201030 B __bss_start
0000000000201030 b completed.6992
                 w __cxa_finalize
00000000000004e0 t deregister_tm_clones
0000000000000550 t __do_global_dtors_aux
0000000000200e48 t __do_global_dtors_aux_fini_array_entry
0000000000201028 d __dso_handle
0000000000200e58 d _DYNAMIC
0000000000201030 D _edata
0000000000201038 B _end
00000000000005c8 T _fini
0000000000000590 t frame_dummy
0000000000200e40 t __frame_dummy_init_array_entry
00000000000005d8 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000000490 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200e50 d __JCR_END__
0000000000200e50 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000000510 t register_tm_clones
0000000000201030 d __TMC_END__

我在 so 文件上构建时缺少哪个编译器标志?

我已经检查过this question但这并没有解决问题。

请注意,我正在尝试从 Lib.ccLib.h 构建一个共享库,然后链接 App.cc反对。我不是试图将所有源文件编译在一起。

最佳答案

当您使用 -lLib 链接库时,链接器会在标准库路径中查找名为 libLib.so 的文件,但当前目录通常不在他们。

你有两个选择:

  • g++ -std=c++11 -o App App.cc -L。 -lLib

否则:

  • g++ -std=c++11 -o App App.cc libLib.so

但是请注意,在运行程序时,动态链接器会按照自己的规则查找库,这些库也可能不包括当前目录。

IIRC,使用 -L。 -lLib 将使运行时动态链接器在标准路径中查找库。因此,要使其正常工作,您必须导出 LD_LIBRARY_PATH=. 或类似的内容。或者在 /usr/lib 中安装库。

但是,如果您将 SO 的全名用于链接器,那么该文件的完整路径将存储在可执行文件头中,所有这些都将正常工作……直到您移动/安装程序,然后它将坏掉了....

除非 SO 文件已与 --soname 选项链接...您可以检查 objdump -p App | 发生了什么需要 grep

如您所见,共享链接的规则很复杂。这就是 libtool 首先被发明的原因!

更新:

你这里有错误:

$ g++ -std=c++11 -fPIC -shared -o Lib.o Lib.cc

应该是:

$ g++ -std=c++11 -fPIC -shared -o Lib.o -c Lib.cc

您的命令使 Lib.o 成为共享库,而不是目标文件。使用您的命令,以下行:

$ g++ -std=c++11 -shared -o libLib.so Lib.o

构建一个没有代码的共享对象,因为Lib.o根本不是一个共享对象!

关于c++ - 我在 so 文件上构建时缺少哪个编译器标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27110132/

相关文章:

c++ - 模板缓冲区和模板测试

python - 构建 YouCompleteMe 时出现 Libpython 错误

c++ - ODB:包含带有通用声明的 *.hxx 文件时出现未解析的外部符号错误

c++ - 最小可用顶点优先的拓扑排序

c++ - 如何用空项目启动 MFC?

c++ - 键盘 Hook 与所有桌面交互 c++ win32

C++ oop 多个链接器错误

go - Flutter,在预构建的 GO .so 库上使用 DynamicLibrary.open(),无需编写 Native Code(Java/Swift)

c++ - 在运行时在共享库中调试/跟踪?

c++ - 如何指定要链接到哪个版本的 boost 库?