g++ 链接器是静态链接还是动态链接 libusb 和 pthreads?

Is g++ linker statically or dynamically linking libusb and pthreads?

在编译命令中加入-lusb-1.0-pthread时,是静态链接还是动态链接?

g++ -pthread -o myprog obj1.o obj2.o -lusb-1.0

ldd 给出以下输出

libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007fc4662b7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc465af7000)

.so 是共享对象。我很迷惑。如果是动态加载,符号是如何解析的?我以为 .so 只能用 dlopen and to obtain address of a symbol one would use dlsym

加载

共享对象可以在编译时链接并在程序启动时加载,也可以在运行时使用 dlopen 动态加载。

“在编译命令中添加 -lusb-1.0 和 -pthread 时,它们是静态链接还是动态链接?” 如果编译器找到动态库,它会链接到它们。否则它会链接到静态库。

这个

libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007fc4662b7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc465af7000)

表示动态库在编译时链接。

I am confused. If it is dynamically loading, how are the symbols resolved?

注意Linux是open source,可以下载研究源码

(属于 kernel, of the GCC C and C++ compiler and its C++ standard library, of the binutils linker, of libc or musl-libc, of GNU emacs, of GDB, of libusb.......)。

在 Linux 上,库最好是默认情况下(如果可用)共享库。因此 gccg++ 的动态链接是隐式偏好。如果没有找到共享库,则链接一个静态库。

在此之前阅读 Dragon Book, a good C++ programming book, the Linker and loaders book, the Program Library HowTo, Assembler HowTo, C++ dlopen HowTo, dlopen(3), ld.so(8), Advanced Linux Programming, some textbook on Operating Systems, syscalls(2), elf(5), and the C++11 standard n3337 and Drepper's How to write shared libraries paper. See also the RefPerSys 项目(我创建的一个免费软件项目,它使用 dlopen 编写 C++ 代码)。

养成启用 DWARF debug information (to later use the GDB debugger) and warnings when compiling, so do g++ -Wall -Wextra -g -c src1.cc -o obj1.o 的习惯,并注意 g++ 的参数顺序很重要。而g++实际上是运行其他程序(cc1plusasld)。将 -v 传递给 g++ 以找出哪些。

I thought .so can be loaded only with dlopen

不是,动态链接器ld.so(8) is loading shared libraries and might be invoked by execve(2). Use ldd(1), strace(1), proc(5)

另读Teach Yourself Programming in Ten Years and see Linux From Scratch

When adding -lusb-1.0 and -pthread to compilation command, are they statically or dynamically linked?

默认情况下,共享库 link 在 Linux 上编辑。除非你要求静态linking,否则各自的共享库 -pthread-lusb-1.0 将被 linked。如果需要,您可以通过 -static 选项告诉 linker 您想要静态 linking。

.so is a shared object. I am confused. If it is dynamically loading, how are the symbols resolved?

它是动态的 linked - 不在编译时加载。但是静态 linker (ld) at compile time so that when the libraries are loaded at run time by the dynamic linker (ld.so) 做了一些工作,它知道如何定位符号。

编译时发生的事情是静态 linker 在 PLT 部分 (Procedure Link Table). At program load time (or when the symbols are referenced), the dynamic linker/loader "fills" those addresses to the actual addresses This is done via the GOT (Global Offset Table) 中为共享库中的符号创建“存根”地址。所以实际的符号解析和加载是在运行时完成的,但在编译时需要静态 linker 的一些帮助。

I thought .so can be loaded only with dlopen and to obtain address of a symbol one would use dlsym.

事实并非如此。共享库可以在编译时 link 编辑,也可以在运行时通过 dlopen 打开。在编译时 link 比通过 dlopen 打开要多得多。几乎所有系统二进制文件实际上都是在 Linux 上动态 linked 的;动态 linking 是所有现代 Linux 系统的默认设置。

如果您对详细信息感兴趣,请查看 Drepper 的 how to write shared libraries