
1、GCC、glibc和GNU C的关系解析
1.1 GCC简介
GCC(GNU Compiler Collection)是GNU项目的一部分,主要是一套编译器工具集,支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada等。作为GNU操作系统的官方编译器,GCC用于编译GNU/Linux系统和应用程序。它遵循GNU General Public License(GNU GPL)发布。
GCC的主要作用是将源代码编译成机器语言,生成可执行文件或库文件,并提供了一些优化选项,可以在编译过程中优化代码,提高程序运行的效率。
1.2 glibc概述
glibc,全称GNU C Library,是GNU项目的一部分,是C语言标准库的一个实现版本,为C语言提供了标准的API,包括输入输出处理、字符串操作、内存管理等。glibc是Linux系统上最常用的C标准库实现之一,实现了C标准规定的所有函数以及POSIX(可移植操作系统接口)的扩展。
1.3 GNU C的特性
GNU C通常指的是GNU项目的C语言编程标准,特别是在GCC中实现的C语言的扩展和特性。GNU C包括ANSI C(现在通常指C89或C90)的所有特性,以及对C99、C11等更现代C标准的支持和一些GNU特有的扩展。
1.4 三者之间的关系
GCC使用glibc作为其C语言程序的标准库。当GCC编译C语言程序时,程序中使用的标准库函数(如printf或malloc)是通过glibc提供的。
GNU C是GCC中实现的C语言的一个版本,包含对C语言标准的支持以及GNU特有的扩展。
GCC是编译器,负责将源代码转换为可执行代码;glibc是运行时库,提供程序运行所需的标准函数和操作系统服务的接口;而GNU C则定义了GCC支持的C语言的标准和扩展。这三者共同构成了GNU/Linux系统下开发和运行C语言程序的基础。
2、POSIX标准介绍
POSIX,全称为“可移植操作系统接口”(Portable Operating System Interface),是一组标准,用来确保不同的操作系统能够提供相同的应用编程接口(API)。这套标准由IEEE(电气和电子工程师协会)制定,标识符为IEEE 1003。
POSIX标准内容包括:系统调用和库、Shell和工具、程序接口等。遵循POSIX标准的操作系统可以提供一系列接口和规范,使程序能够在不同的系统上运行,提高了软件的可移植性和灵活性。
3、C语言编译过程概述
在Linux环境下,C语言的开发一般选择GCC工具链进行编译。下面是C语言编译的一个基本流程示例:
首先创建工程文件夹并新建源文件。假设我们有两个源文件main.c和01_hello.c,它们相互引用并调用彼此的函数。我们需要先预处理这两个文件生成.i文件,然后编译生成.s文件,再进行汇编生成.o目标文件。最后通过链接生成可执行文件。这个过程可以使用GCC命令行参数一次性完成,也可以分步骤进行以了解每个阶段的作用。在编译过程中还可以选择静态链接或动态链接来生成最终的可执行文件。静态链接将库函数直接嵌入到可执行文件中,而动态链接则在运行时加载所需的库文件。此外还可以将部分代码编译为动态链接库以供其他程序使用。这样通过灵活选择链接方式可以优化程序的性能和资源占用。
通过执行特定指令,我们可以将hello.o文件编译成静态链接库libhello.a。
使用的归档命令是ar,通过输入“ar crv libhello.a hello.o”来执行操作。
其中,ar命令的选项包括:
c:表示创建归档文件,如果指定的libhello.a不存在,则会创建它。
r:代表替换或添加文件到归档文件中。如果hello.o已存在于libhello.a中,则会被新版本替换;如果不存在,则会被添加进去。
v:为详细模式,处理文件时显示详细信息,包括哪些文件被添加或替换。
而libhello.a是我们想要创建或更新的静态库文件名。按照惯例,Linux下的静态库文件名以lib开头,并使用.a作为文件扩展名。我们的输入文件是hello.o,即要添加到静态库libhello.a中的目标文件。
如果在相同目录下同时存在hello的静态库和动态库文件,为了防冲突,我们可能需要删除动态链接库,以确保在链接时选择静态链接库。
接下来,我们可以利用静态库文件生成可执行文件main。使用gcc命令,“gcc main.o -L ./ -lhello -o main”来操作。这里的“-L ./”表示额外的库文件位置为当前目录;“-lhello”表示链接到libhello.a文件。请注意,这里需要去掉lib前缀和.a后缀。
完成编译后的main文件可以执行,并且不依赖于静态库libhello.a。然而需要注意的是,虽然我们静态链接了libhello.a库,但在执行main文件时,依然需要动态链接glibc的库。这种链接方式实际上是混合链接。
至于glibc的动态库和静态库,它们分别位于/usr/lib/x86-64_64-linux-gnu/目录下的libc.so和libc.a文件中。静态库libc.a是编译时的静态版本,而动态库libc.so则是在运行时加载的版本。这两种库为程序提供了不同的运行方式选择,开发者可以根据需求选择合适的库进行使用。
