【问题标题】:Questions about the GCC compiler and linker关于 GCC 编译器和链接器的问题
【发布时间】:2012-01-16 01:39:51
【问题描述】:

假设您的程序由两个源文件(main.c 和辅助.c)和两个头文件(declarations.h 和辅助.h)组成。

然后你运行编译器如下:

$gcc main.c auxiliary.c -o myprogram

问题 1:编译器会为我的程序创建一个目标文件(即,只是缺少库)还是会创建两个目标文件,每个源文件一个(然后链接一切都在一起)?

问题 2:是否需要单独调用链接器?因为如果您使用上面的命令,编译器会为您解决这个问题,对吧?

问题 3:为什么有些库会自动链接(例如,stdio)以及为什么有些需要额外的工作(例如,math.h 需要在编译时添加 -lm)。 -lm 代表什么?

问题 4:假设您有一个源文件并且您的程序不需要任何外部库。这是否意味着您从编译器获得的目标代码已经可以执行? (即,像 $gcc -c main.c 一样编译它)。

【问题讨论】:

  • 这些东西是特定于每个实现的。用“C”和“compilers”等通用标签标记它是不合适的,因为它指的是“the”C 编译器。
  • 同意。我将其重新命名为“关于 GCC 编译器的问题”

标签: c compiler-construction gcc


【解决方案1】:
  1. gcc 通常会为每个源文件生成一个对象。但是有一个-combine 选项可以告诉您要不然。

  2. 当你有几十个源文件时重新编译所有东西不是一个好主意(当你有更多时,你将它们拆分到库中)。

  3. 历史。曾经有一段时间——在共享库之前——当数学库相对较大并将其放在每个可执行文件中,即使是那些不需要它的人也被认为是浪费的(使用数学库涉及到 printf 等函数的替代版本,所以即使不使用你也要付出代价)

  4. 我在等着看一个甚至不使用标准库的任何部分的程序(逻辑上调用 main 是作为 exit(main(argc, argv)) 完成的,所以至少调用了 exit)然后那里是启动和完成代码。

【讨论】:

    【解决方案2】:
    1. gcc为每个源文件创建一个目标文件,然后链接它们以构建可执行文件。

    2. 您的示例证明gcc 能够链接所有需要的步骤

    3. 自动链接的库是标准 C 库。其他需要指定。当您不需要atan2() 时,这允许构建更小的可执行文件。
      -lm 向编译器指示它应该找到数学库,其 id 是 m。在 Unix 上,它的文件名是 libm.solibm.a 取决于链接是动态的(在运行时执行并导致较小的可执行文件)还是静态的(在链接时执行并导致独立的可执行文件)。

    4. 没有。无论如何,它必须链接到标准 C 库。此外,目标代码的文件格式与可执行文件不同。

    【讨论】:

    • 4.从技术上讲,它们都是 ELF 文件,但具有一些不同的属性。
    • 谢谢。还有一个问题:为什么 Wikipedia 和其他来源说 math.h 是标准库的一部分? -> en.wikipedia.org/wiki/C_standard_library
    • 维基百科文章中有一段关于它的内容。此外,并非所有的 C 风格都符合最新标准。
    • @Daniels:因为 ISO C 标准是这样说的。 GCC 将“ISO 标准”库分解为“默认”和“可选”部分; libm 不是默认值的一部分。微软 OTOH 没有单独的数学库。
    【解决方案3】:

    问题 1:使用“-save-temps”执行 gcc 语句,您会看到编译器创建了两个目标文件。

    问题 2:对链接器的调用是隐式的。 “gcc”命令并不是真正的编译器,而是根据需要通过调用预处理器、编译器、汇编器和链接器来驱动编译过程。 在小型程序中,让 'gcc' 处理一切可能是个好主意,但对于具有许多源文件的大型程序,这意味着重新编译所有源文件,即使它们没有更改。

    问题 3:这是约定俗成的问题。 (m 库是数学库。)

    问题 4:不,事实并非如此。总是有一些额外的代码必须链接到处理流程启动/拆卸要求。在 linux 上,这些是 crt1.o、crti.o、crtbegin.o 和 crtn.o 文件。

    【讨论】:

    • 感谢您的回答。我猜当我在 gcc 中使用 -c 选项时,编译器将输出汇编代码,汇编器会将其转换为目标文件并停在那里,对吗?在这种情况下,是否可以在汇编代码步骤停止? (即,制作 gcc 输出程序集而不是目标文件?)
    • @DanielS 是的,这是可能的。看到这个:stackoverflow.com/questions/137038/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    相关资源
    最近更新 更多