I understand that code included in an executable at compile-time can come from object files (.o files) and statically-linked libraries (.lib/.a files). What is fundamentally and conceptually the difference between these two? Why is there a different concept between "object code" and a "statically-linked library"? What are the advantages and disadvantages to each, and why use one as opposed to the other? Can statically-linked library(ies) be made from object file(s), and vise-versa, can object file(s) be made from statically-linked library(ies)?
我理解在编译时包含在可执行文件中的代码可以来自对象文件(。o文件)和静态链接库(.lib/。一个文件)。这两者的根本和概念上的区别是什么?为什么“对象代码”和“静态链接库”之间有不同的概念?它们各自的优缺点是什么,为什么要用一个而不是另一个呢?静态链接库(ies)可以由对象文件生成,反之亦然,对象文件可以由静态链接库(ies)生成吗?
2 个解决方案
#1
9
Object files are compiled but unlinked code. Libraries contain object files. Thus your question becomes, "Why use statically-linked libs if I can just use object files?" Here's why.
对象文件是编译的但没有链接的代码。库包含对象文件。因此,您的问题变成了“如果我可以使用对象文件,为什么要使用静态链接的libs ?”这是为什么。
Unlike a collection of objects, each of which have their own symbol tables, a library has a single, unified symbol table, created when ar
is called by the library developer using the s
switch. s
calls ranlib
to create a unified symbol table for all objects in that archive.
与对象集合(每个对象都有自己的符号表)不同,库有一个统一的符号表,由库开发人员使用s开关调用ar时创建。s调用ranlib为该存档中的所有对象创建统一的符号表。
Running ranlib
in shell shows in the first line of help text:
在shell中运行ranlib显示在帮助文本的第一行:
Generate an index to speed access to archives.
生成索引以加速对档案的访问。
And from the generic ranlib docs:
来自一般的ranlib文档:
An archive with such an index speeds up linking to the library and allows routines in the library to call each other without regard to their placement in the archive. T
有这样一个索引的归档可以加速对库的链接,并允许库中的例程相互调用,而不考虑它们在归档中的位置。T
See also the FreeBSD ranlib docs - different wording, same idea: Speed of linkage.
参见FreeBSD ranlib文档——不同的措辞,相同的思想:链接的速度。
#2
6
A library is simply a file containing many object files, which can be searched to resolve symbols.
库只是包含许多对象文件的文件,可以通过搜索来解析符号。
So typically, when you link objects together, you get all the objects in one executable (though some optimising linkers can throw out unused ones).
因此,通常,当您将对象链接在一起时,您将获得一个可执行文件中的所有对象(尽管一些优化链接器可能会抛出未使用的链接器)。
When you give a library to the linker, it examines each of the object files within it and brings in those that are needed to satisfy unresolved symbols (and will probably continue to bring them in until either all symbols are resolved or no more can be).
当你给链接器一个库时,它会检查其中的每个对象文件,并引入那些需要满足未解析符号的文件(并且可能会继续引入这些文件,直到所有的符号都被解析或者再也不能被解析)。
It's just a way of efficiently packaging up a lot of objects into a single file so that the linker can do more of your work - you don't have to worry about which objects you need.
它只是一种有效地将许多对象打包成一个文件的方法,以便链接器可以完成更多的工作——您不必担心需要哪些对象。
If you think of the C library, you may have a printf.o
, puts.o
, fopen.o
as a result of keeping your source well separated. You don't want the user to have to explicitly list every single object file they want so you package the whole lot up into libc.a
and tell them they just need to link with that single file.
如果你想到C库,你可能会有一个printf。啊,把。o,打开外部文件。o的结果,保持你的来源良好的分离。您不希望用户必须显式地列出他们想要的每一个对象文件,因此您将所有内容打包到libc中。告诉他们他们只需要链接到那个文件。
The statically-linked bit is irrelevant here, it just decides that the objects should go into the executable at link time rather than being dynamically loaded at run time. It's explained here.
静态链接的比特在这里无关紧要,它只是决定对象应该在链接时进入可执行文件,而不是在运行时动态加载。这里的解释。
#1
9
Object files are compiled but unlinked code. Libraries contain object files. Thus your question becomes, "Why use statically-linked libs if I can just use object files?" Here's why.
对象文件是编译的但没有链接的代码。库包含对象文件。因此,您的问题变成了“如果我可以使用对象文件,为什么要使用静态链接的libs ?”这是为什么。
Unlike a collection of objects, each of which have their own symbol tables, a library has a single, unified symbol table, created when ar
is called by the library developer using the s
switch. s
calls ranlib
to create a unified symbol table for all objects in that archive.
与对象集合(每个对象都有自己的符号表)不同,库有一个统一的符号表,由库开发人员使用s开关调用ar时创建。s调用ranlib为该存档中的所有对象创建统一的符号表。
Running ranlib
in shell shows in the first line of help text:
在shell中运行ranlib显示在帮助文本的第一行:
Generate an index to speed access to archives.
生成索引以加速对档案的访问。
And from the generic ranlib docs:
来自一般的ranlib文档:
An archive with such an index speeds up linking to the library and allows routines in the library to call each other without regard to their placement in the archive. T
有这样一个索引的归档可以加速对库的链接,并允许库中的例程相互调用,而不考虑它们在归档中的位置。T
See also the FreeBSD ranlib docs - different wording, same idea: Speed of linkage.
参见FreeBSD ranlib文档——不同的措辞,相同的思想:链接的速度。
#2
6
A library is simply a file containing many object files, which can be searched to resolve symbols.
库只是包含许多对象文件的文件,可以通过搜索来解析符号。
So typically, when you link objects together, you get all the objects in one executable (though some optimising linkers can throw out unused ones).
因此,通常,当您将对象链接在一起时,您将获得一个可执行文件中的所有对象(尽管一些优化链接器可能会抛出未使用的链接器)。
When you give a library to the linker, it examines each of the object files within it and brings in those that are needed to satisfy unresolved symbols (and will probably continue to bring them in until either all symbols are resolved or no more can be).
当你给链接器一个库时,它会检查其中的每个对象文件,并引入那些需要满足未解析符号的文件(并且可能会继续引入这些文件,直到所有的符号都被解析或者再也不能被解析)。
It's just a way of efficiently packaging up a lot of objects into a single file so that the linker can do more of your work - you don't have to worry about which objects you need.
它只是一种有效地将许多对象打包成一个文件的方法,以便链接器可以完成更多的工作——您不必担心需要哪些对象。
If you think of the C library, you may have a printf.o
, puts.o
, fopen.o
as a result of keeping your source well separated. You don't want the user to have to explicitly list every single object file they want so you package the whole lot up into libc.a
and tell them they just need to link with that single file.
如果你想到C库,你可能会有一个printf。啊,把。o,打开外部文件。o的结果,保持你的来源良好的分离。您不希望用户必须显式地列出他们想要的每一个对象文件,因此您将所有内容打包到libc中。告诉他们他们只需要链接到那个文件。
The statically-linked bit is irrelevant here, it just decides that the objects should go into the executable at link time rather than being dynamically loaded at run time. It's explained here.
静态链接的比特在这里无关紧要,它只是决定对象应该在链接时进入可执行文件,而不是在运行时动态加载。这里的解释。