您当前所在位置:首页安装教程GNUC编译器的程序员入门指南

GNUC编译器的程序员入门指南

更新:2023-08-09 16:58:18编辑:tooool归类:安装教程人气:49

带你一窥生成二进制文件步骤的幕后,以便在出现一些错误时,你知道如何逐步解决问题。

GNUC编译器的程序员入门指南

C 语言广为人知,深受新老程序员的好评。使用 C 语言编写的源文件代码,使用了标准的英语术语,因而人们可以方便阅读。然而,计算机只能理解二进制代码。为将代码转换为机器语言,你需要使用一种被称为 编译器compiler 的工具。

最常见的编译器是 GCC(GNU 编译器集GNU Compiler Collection)。编译过程涉及到一系列的中间步骤及相关工具。

安装 GCC

为验证在你的系统上是否已经安装了 GCC,使用gcc命令:

$ gcc--version

如有必要,使用你的软件包管理器来安装 GCC。在基于 Fedora 的系统上,使用dnf

$ sudo dnf install gcc libgcc

在基于 Debian 的系统上,使用apt

$ sudo aptinstallbuild-essential

在安装后,如果你想查看 GCC 的安装位置,那么使用:

$ whereis gcc

演示使用 GCC 来编译一个简单的 C 程序

这里有一个简单的 C 程序,用于演示如何使用 GCC 来编译。打开你最喜欢的文本编辑器,并在其中粘贴这段代码:

// hellogcc.cinclude

保存文件为hellogcc.c,接下来编译它:

$ ls
hellogcc.c

$ gcc hellogcc.c

$ ls -1a.out
hellogcc.c

如你所见,a.out是编译后默认生成的二进制文件。为查看你所新编译的应用程序的输出,只需要运行它,就像你运行任意本地二进制文件一样:

$ ./a.outHello, GCC!

命名输出的文件

文件名称a.out是非常莫名其妙的,所以,如果你想具体指定可执行文件的名称,你可以使用-o选项:

(LCTT 译注:注意这和最近 Linux 内核废弃的 a.out 格式无关,只是名字相同,这里生成的 a.out 是 ELF 格式的 —— 也不知道谁给起了个a.out这破名字,在我看来,默认输出文件名就应该是去掉了.c扩展名后的名字。by wxy)

$ gcc -o hellogcc hellogcc.c

$ ls
a.out hellogcc hellogcc.c

$ ./hellogcc
Hello, GCC!

当开发一个需要编译多个 C 源文件文件的大型应用程序时,这种选项是很有用的。

在 GCC 编译中的中间步骤

编译实际上有四个步骤,即使在简单的用例中 GCC 自动执行了这些步骤。

  1. 预处理Pre-Processing:GNU 的 C 预处理器(cpp)解析头文件(include语句),展开 宏macros 定义(define语句),并使用展开的源文件代码来生成一个中间文件,如hellogcc.i
  2. 编译Compilation:在这个期间中,编译器将预处理的源文件代码转换为指定 CPU 架构的汇编代码。由此生成是汇编文件使用一个.s扩展名来命名,如在这个示例中的hellogcc.s
  3. 汇编Assembly:汇编程序(as)将汇编代码转换为目标机器代码,放在目标文件中,例如hellogcc.o
  4. 链接Linking:链接器(ld)将目标代码和库代码链接起来生成一个可执行文件,例如hellogcc

在运行 GCC 时,可以使用-v选项来查看每一步的细节:

$ gcc -v -o hellogcc hellogcc.c

手动编译代码

体验编译的每个步骤可能是很有用的,因此在一些情况下,你不需要 GCC 完成所有的步骤。

首先,除源文件文件以外,删除在当前文件夹下生成的文件。

$ rm a.out hellogcc.o

$ ls
hellogcc.c

预处理器

首先,启动预处理器,将其输出重定向为hellogcc.i

$ cpp hellogcc.c > hellogcc.i

$ ls
hellogcc.c hellogcc.i

查看输出文件,并注意一下预处理器是如何包含头文件和扩展宏中的源文件代码的。

编译器

现在,你可以编译代码为汇编代码。使用-S选项来设置 GCC 只生成汇编代码:

$ gcc -S hellogcc.i

$ ls
hellogcc.c hellogcc.i hellogcc.s

$ cat hellogcc.s

查看汇编代码,来看看生成了什么。

汇编

使用你刚刚所生成的汇编代码来创建一个目标文件:

$ as -o hellogcc.o hellogcc.s

$ ls
hellogcc.c hellogcc.i hellogcc.o hellogcc.s

链接

要生成一个可执行文件,你必须将对象文件链接到它所依赖的库。这并不像前面的步骤那么简单,但它却是有教育意义的:

$ ld -o hellogcc hellogcc.o
ld: warning: cannotfindentry symbol _start; defaulting to0000000000401000ld: hellogcc.o:infunction`main`:hellogcc.c.text+0xa): undefined reference to `puts

在链接器查找完libc.so库后,出现一个引用undefined puts错误。你必须找出适合的链接器选项来链接必要的库以解决这个问题。这不是一个小技巧,它取决于你的系统的布局。

在链接时,你必须链接代码到核心运行时core runtime(CRT)目标,这是一组帮助二进制可执行文件启动的子例程。链接器也需要知道在哪里可以找到重要的系统库,包括libclibgcc,尤其是其中的特殊的开始和结束指令。这些指令可以通过--start-group--end-group选项来分隔,或者使用指向crtbegin.ocrtend.o的路径。

这个示例使用了 RHEL 8 上的路径,因此你可能需要依据你的系统调整路径。

$ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
    -o hello \
    /usr/lib64/crt1.o /usr/lib64/crti.o \
    --start-group \
        -L/usr/lib/gcc/x86_64-redhat-linux/8 \
        -L/usr/lib64 -L/lib64 hello.o \
        -lgcc \
        --as-needed -lgcc_s \
        --no-as-needed -lc -lgcc \
    --end-group \
    /usr/lib64/crtn.o

在 Slackware 上,同样的链接过程会使用一组不同的路径,但是,你可以看到这其中的相似之处:

$ld -static -o hello \
    -L/usr/lib64/gcc/x86_64-slackware-linux/11.2.0/ \
    /usr/lib64/crt1.o /usr/lib64/crti.o hello.o /usr/lib64/crtn.o \
    --start-group \
        -lc -lgcc -lgcc_eh \
    --end-group

现在,运行由此生成的可执行文件:

$ ./hello
Hello, GCC!

一些有用的实用程序

下面是一些帮助检查文件类型、符号表symbol tables 和链接到可执行文件的库的实用程序。

使用file实用程序可以确定文件的类型:

$filehellogcc.chellogcc.c:Csource,ASCIItext$filehellogcc.ohellogcc.o:ELF64-bitLSBrelocatable,x86-64,version1(SYSV),notstripped$filehellogcchellogcc:ELF64-bitLSBexecutable,x86-64,version1(SYSV),dynamicallylinked,interpreter/lib64/ld-linux-x86-64.so.2,BuildID[sha1]=bb76b241d7d00871806e9fa5e814fee276d5bd1a,forGNU/Linux3.2.0,notstripped

对目标文件使用nm实用程序可以列出 符号表symbol tables :

$nm hellogcc.o0000000000000000T mainUputs

使用ldd实用程序来列出动态链接库:

$ ldd hellogcc
linux-vdso.so.1(0x00007ffe3bdd7000)
libc.so.6=>/lib64/libc.so.6(0x00007f223395e000)
/lib64/ld-linux-x86-64.so.2(0x00007f2233b7e000)

总结

在这篇文章中,你了解到了 GCC 编译中的各种中间步骤,和检查文件类型、符号表symbol tables 和链接到可执行文件的库的实用程序。在你下次使用 GCC 时,你将会明白它为你生成一个二进制文件所要做的步骤,并且当出现一些错误时,你会知道如何逐步处理解决问题。

via: https://opensource.com/article/22/5/gnu-c-compiler

作者:Jayashree Huttanagoudar选题:lkxed译者:robsean校对:wxy

本文由 LCTT原创编译,Linux中国荣誉推出

我告诉你msdn版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

Win10一周年更新预览版14352新增6款火爆游戏支持 windows10系统开机后直接弹出开始菜单的解决方案

游客 回复需填写必要信息