查看“Libgcc”的源代码
←
Libgcc
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[GCC|GNU Compiler Collection]]在代码生成过程中使用了一个名为<tt>libgcc</tt>的特殊库,其中包含共享代码,每次重复这些代码都会降低效率,还包含辅助辅助程序例程和运行时支持。 其确切内容取决于特定的目标、配置,甚至取决于命令行选项。 GCC无条件地假设它可以安全地发出对它认为合适的 <tt>libgcc</tt> 符号的调用,因此GCC编译的所有代码都必须与 <tt>libgcc</tt> 链接。 当你链接到GCC时,默认情况下会自动包含该库,并且无需进一步操作即可使用它。 然而,由于显而易见的原因,内核通常不与标准用户空间libc链接,而是与<tt>-nodefaultlibs</tt>(由<tt>-nostdlib</tt>隐含)链接,这将禁用与libc和<tt>libgcc</tt>的自动链接。 这是一个问题,因为gcc仍然认为它可以使用 <tt>libgcc</tt>,你需要与之链接。 ==如何构建libgcc== {{Main|GCC Cross-Compiler}} 你需要在构建 [[GCC Cross-Compiler]] 时调用 <tt>all-target-libgcc</tt> 和 <tt>install-target-libgcc</tt> make target,以构建和安装 <tt>libgcc</tt> 以及你的交叉-编译器。 名为<tt>libgcc</tt>.a的静态库与其他特定于编译器的文件一起安装到你的编译器前缀中。 请注意,一些体系结构,如ARM,有多种类型的ABI和指令集:因此,这些目标需要多个版本的<tt>libgcc</tt>,具体取决于你使用的特定编译选项,它们都会进入编译器特定的子目录。 ==如何与libgcc链接== {{Main|Bare Bones}} 在将内核与编译器链接时,可以通过传递 <tt>-lgcc</tt> 与 <tt>libgcc</tt> 链接。 除非通过了<tt>-nodefaultlibs</tt>选项(由<tt>-nostdlib</tt>隐含),否则不需要这样做。 例如: <source lang="bash">i686-elf-gcc -T linker.ld -o myos.kernel -ffreestanding boot.o kernel.o -nostdlib -lgcc</source> 请注意如何将 <tt>libgcc</tt> 安装对于编译器是已知的,但链接器不知道的特定于编译器的目录中。 因此,必须将编译器用作链接器,而不是直接调用<tt>ld</tt>,否则需要告诉链接器在哪里可以找到<tt>libgcc</tt>。 还要注意,你必须确保在链接时为机器提供编译选项(<tt>-mfoo</tt>和<tt>-fbar</tt>等选项),否则可能会得到错误的<tt>libgcc</tt>。 如果你想知道 <tt>libgcc</tt> 的完整路径 (如果你坚持用 <tt>ld</tt> 而不是你的编译器链接),你可以这样做: <source lang="bash">i686-elf-gcc $CFLAGS -print-libgcc-file-name</source> 在使用<tt>-print libgcc file name</tt>选项时,当然也需要传递机器编译选项。 使你的构建脚本或Makefile位于<tt>libgcc</tt>,而不是在某个地方硬编码路径,否则其他人将更难构建你的操作系统。 == 常见问题 == ==我什么时候需要链接到libgcc=== 所有用GCC编译的代码都必须链接<tt>libgcc</tt>。 === 我和libgcc链接,什么都没有改变?=== 编译器不需要发出对<tt>libgcc</tt>的调用,在某些平台上,<tt>libgcc</tt>是一个小型库,你也可以编写不需要<tt>libgcc</tt>的复杂程序。 编译器将只链接<tt>libgcc</tt>中需要的特定部分,因为它是一个静态库。 但是,编译器可以自由地改变主意,并突然发出对 <tt>libgcc</tt> 的调用,总会有一些突发情况 (或者你将编译器升级到较新的版本)。 ===我没有链接到libgcc,它还能工作吗=== 请参阅上面的问题。 编译器不在乎你是否实际与 <tt>libgcc</tt> 链接,它将发出相同的调用。 如果链接到<tt>libgcc</tt>,则永远不会出现与<tt>libgcc</tt>相关的链接错误,这很简单,并且使内核编译过程可靠。 可以这样想:你进入编译器源代码,随机注释掉几个随机选择的函数。 编译器仍然碰巧为你的内核工作,但它将始终为你可以编写的所有可能的内核源代码工作吗? libgcc库是编译器的一部分,不安全地禁用编译器的某些部分是愚蠢的。 ===我可以使用Linux现有libgcc吗?=== 你必须使用交叉编译器附带的正确的 <tt>libgcc</tt>。 你发现的任何其他<tt>libgcc</tt>都可能有不同的目标,使用不同的机器编译选项构建,依赖于标准库,是不同编译器版本的一部分(甚至你的发行版可能已经修补了其gcc)。 使用不同的<tt>libgcc</tt>可能会起作用,但可能不可靠。 === 我可以将所需的libgcc函数复制到操作系统中吗?=== 你真的不应该。 这些函数是特定于编译器版本的,当你升级编译器时,所需的函数集可能会发生变化。 你将和编译器开发人员玩起追逐游戏,如果你的其他贡献者使用不同的编译器版本,你可能会遇到更多麻烦。 还有一个问题是,你是否已经复制了足够多的<tt>libgcc</tt>,如果你没有全部复制,事情将无法可靠地运行。 ===我能否重新实现libgcc?=== 你真的不应该。 请看上面的问题。 这需要大量的工作,而且非常棘手,你可能会得到一个低效的64位除法函数,它并不能对所有的值都正常工作。 仅与 <tt>libgcc</tt> 链接并进行处理要简单得多。 ===libgcc是否有依赖关系=== 通常不会,这里用于教程的<tt>-elf</tt>目标肯定不会。 如果你有一个托管的用户空间,它可能会启用自身的其他部分,并具有依赖于在系统标头中找到的特定用户空间功能的特殊符号。 这些是你希望在内核标准库中实现的常见函数。 某些依赖项仅在使用触发它们的相关libgcc部件时才相关。 === libgcc是什么许可证?=== libgcc库在GNU GPL加上the GCC Runtime Library 例外下获得许可 (请参见gcc源代码树中的COPYING.RUNTIME</tt>)。 这大致意味着,只要你使用非专有版本的GCC,你就可以将libgcc链接到你的软件中,即使它通常会违反GNU GPL。 这并不奇怪,这样的授权代码与GCC创建的所有东西都有关联,尤其是用户空间程序,由于运行库例外,你可以合法地使用GCC编译和分发专有程序。 === Libgcc太大了!=== 其实不是。 静态存档包含很多对象文件,每个文件都包含调试符号。 如果你尝试剥离它,你会发现归档变得相当小。 此外,它甚至还没有链接,很多信息只是文件格式和链接信息的开销。 最后,它是一个静态存档,这意味着只有相关的部分才能真正链接到二进制文件中。 === 如果我小心回避Libgcc呢?=== 在某些平台上,除特定情况外,编译器不会为大多数常见代码生成对 <tt>libgcc</tt> 的调用。 但我敢打赌,你还没有真正阅读过GCC的源代码,并找到了发出<tt>libgcc</tt>调用的确切规则。 更新编译器时,规则可能会更改。 事实上,明天可能是周二。(译者注:指美国历史上星期二突然爆破的股灾) 该库提供了有用的功能,并且很容易链接到它并享受这些功能。 如果规则发生变化,并且你无法使用新的编译器构建内核,但你修复了内核,那么你仍然无法构建操作系统的旧版本 (这对于调试或历史目的可能是有用的)。 我不想要它,因为我想要完全掌控=== 你并不是在编写你正在使用的编译器。 考虑一下,让不重复发明的做法-从这里开始。 === 我真的不想要libgcc=== 上面的规则是: : 所有使用gcc编译的代码都必须与 <tt>libgcc</tt> 链接。 但没关系,你可以改变gcc的定义,去掉这个规则。 修改GCC源代码,使其永远不向<tt>libgcc</tt>发出调用(可能是<tt>-ffreestanding</tt>),而是直接生成代码。 那你就不用和它链接了。 ===我在用clang=== 这是一篇关于GCC的文章,如果你正在使用另一个编译器,你需要做不同的事情。 === 我看到有人没有和libgcc链接!=== 向当地打击编译器犯罪警察报案。(译者注:这里是开玩笑,指这样的事情不太可能发生,或者即使读者以为发生了其实也是误解了吧。) ==另见== === 文章 === * [[GCC]] * [[GCC Cross-Compiler]] * [[Bare Bones]] * [[Building libgcc for mcmodel=kernel]] [[Category:C]] [[Category:C++]] [[Category:Compilers]] [[Category:FAQ]]
本页使用的模板:
模板:Main
(
查看源代码
)
返回至“
Libgcc
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息