<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Libgcc</id>
	<title>Libgcc - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Libgcc"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Libgcc&amp;action=history"/>
	<updated>2026-04-03T21:36:52Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Libgcc&amp;diff=1183&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“GNU Compiler Collection在代码生成过程中使用了一个名为&lt;tt&gt;libgcc&lt;/tt&gt;的特殊库，其中包含共享代码，每次重复这些代码都会降低效率，还包含辅助辅助程序例程和运行时支持。 其确切内容取决于特定的目标、配置，甚至取决于命令行选项。 GCC无条件地假设它可以安全地发出对它认为合适的 &lt;tt&gt;libgcc&lt;/tt&gt; 符号的调用，因此GCC编译的所有代码都必须与 &lt;tt…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Libgcc&amp;diff=1183&amp;oldid=prev"/>
		<updated>2022-04-23T12:44:55Z</updated>

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