假设我们有一个简单的C项目,我们想在桌面上运行。为了生成可执行文件,我们需要对它进行预处理、编译和链接。让我们假设我们使用GCC来做这件事。我们可以在一个步骤中完成这三个操作:
gcc -o program src/*.c
为什么我们不需要在这里指定链接器脚本?也许在某个地方有一个默认的,它看起来像什么?操作系统会帮我们处理吗或者,链接器脚本可能只对将要闪存到外部嵌入式系统中的软件是必需的?这里链接器、预处理器和编译器的默认选项是什么?
czfnxgou1#
为什么我们不需要在这里指定链接器脚本?因为每个链接器都有一个默认的链接。事实上,链接器脚本支持是一个 * 实现细节 *。没有任何链接器脚本支持,链接器也可以正常工作。也许在某个地方有一个默认的,它看起来像什么?如果您使用的是GNU ld,您可以使用ld --verbose看到它的内置链接器脚本。我们什么时候需要使用链接器脚本当默认的不能满足你的需要时,你需要额外的控制在最终的链接器输出中放置不同的部分。
ld --verbose
wgx48brx2#
链接器脚本通常定义平台上可用的存储器资源,对于嵌入式系统而言,这是特定于应用程序的,并且对于工具链而言是未知的。此外,在裸机嵌入式系统中,链接器必须在构建时链接和定位代码,而在托管系统可执行对象文件中,数据和代码将具有段标识符,操作系统加载器使用这些段标识符在程序启动时适当地定位代码/数据。因此,在这种情况下,链接器不需要知道可用的内存资源,因为这是由OS加载器处理的。因此,在嵌入式系统中,链接器执行模块间引用解析(link)和显式内存位置(locate),后者需要了解内存布局。在托管系统中,静态链接器仅执行链接阶段,并且位置由0 S处理(在现代桌面0 S中,该环境通常也是“虚拟化的”)。这并不意味着桌面系统中没有链接器脚本。例如,在x86 64位的Linux/gnu中,你会发现/lib/x86_64-linux-gnu/ldscripts,我相信实际应用的脚本取决于构建时传递给工具链的开关。(参考Actual default linker script and settings gcc uses)。
/lib/x86_64-linux-gnu/ldscripts
2条答案
按热度按时间czfnxgou1#
为什么我们不需要在这里指定链接器脚本?
因为每个链接器都有一个默认的链接。
事实上,链接器脚本支持是一个 * 实现细节 *。没有任何链接器脚本支持,链接器也可以正常工作。
也许在某个地方有一个默认的,它看起来像什么?
如果您使用的是GNU ld,您可以使用
ld --verbose
看到它的内置链接器脚本。我们什么时候需要使用链接器脚本
当默认的不能满足你的需要时,你需要额外的控制在最终的链接器输出中放置不同的部分。
wgx48brx2#
链接器脚本通常定义平台上可用的存储器资源,对于嵌入式系统而言,这是特定于应用程序的,并且对于工具链而言是未知的。
此外,在裸机嵌入式系统中,链接器必须在构建时链接和定位代码,而在托管系统可执行对象文件中,数据和代码将具有段标识符,操作系统加载器使用这些段标识符在程序启动时适当地定位代码/数据。因此,在这种情况下,链接器不需要知道可用的内存资源,因为这是由OS加载器处理的。
因此,在嵌入式系统中,链接器执行模块间引用解析(link)和显式内存位置(locate),后者需要了解内存布局。在托管系统中,静态链接器仅执行链接阶段,并且位置由0 S处理(在现代桌面0 S中,该环境通常也是“虚拟化的”)。
这并不意味着桌面系统中没有链接器脚本。例如,在x86 64位的Linux/gnu中,你会发现
/lib/x86_64-linux-gnu/ldscripts
,我相信实际应用的脚本取决于构建时传递给工具链的开关。(参考Actual default linker script and settings gcc uses)。