.o .a和.so文件有什么区别?

我知道.o是目标文件,.a是静态库,.so是动态库吗? 它们的物理意义是什么? 我何时可以使用,何时不使用?

.a是一个“档案”。 虽然存档可以包含任何类型的文件,但在GNU工具链的上下文中,它是一个目标文件库(其他工具链尤其是在WIndows上使用.lib用于相同的目的,但这些工具的格式通常不是通用的存档,通常特定于工具链)。 可以从归档中提取单个目标文件,这基本上是链接器在使用库时所执行的操作。

.o是一个目标文件。 这是编译为机器代码但不(通常)完全链接的代码 – 它可能具有对通过单独编译生成的其他目标文件(在库中或单独)中定义的符号的未解析引用。 对象文件包含支持与其他模块链接的元数据,也可以包含源级符号调试(例如,在GDB中)。 其他工具链,通常在Windows上,使用扩展名.obj而不是.o

.so是一个共享对象库(或只是共享库)。 当程序启动时,它会动态链接到可执行文件,而不是在构建时静态链接。 它允许较小的可执行文件,并且多个可执行文件使用单个对象库实例。 操作系统API通常是共享库,并且它们通常也在GNU中用于许可,例如将LGPL代码与闭源专有代码分开(我不是律师 – 我没有对此方法的合法性提出任何要求。任何特殊情况)。 与.o.a文件不同,应用程序使用的.so文件必须在运行时系统上可用。 其他系统(通常也称为Windows)使用.dll (动态链接库)用于相同目的。

理解.o文件在.a文件中的目标代码之前链接可能是有用的,这样如果.o文件满足符号解析,则任何库实现都不会链接 – 允许您基本上用您的库替换库实现拥有,也用于库实现来调用用户定义的代码 – 例如,GUI框架可能会调用应用程序入口点。

.so是共享库文件。 .a是静态库文件。

您可以静态链接到.a库,并在运行时.so文件中动态链接和加载,前提是您以这种方式编译和链接。

.o是目标文件(它们是从* .c文件编译的,可以链接到创建可执行文件,.a或.so库。 在这里阅读更多相关信息

静态库是包含库的目标代码的归档,当链接到将代码编译到可执行文件中的应用程序时。

共享库的不同之处在于它们不会编译到可执行文件中。 而是动态链接器搜索一些目录,寻找它需要的库,然后将其加载到内存中。 多个可执行文件可以同时使用同一个共享库,从而减少内存使用量和可执行文件大小。 但是,随后可以使用可执行文件分发更多文件。 您需要确保将库安装到链接器可以找到它的用户系统上,静态链接可以消除此问题,但会导致更大的可执行文件。