考虑以下三个文件,它们都在同一目录中。
库.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.cc
和 Lib.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/