Linux下编译C程序

Linux基础

Posted by Xiaosheng on August 1, 2015

我们都知道,C 程序的源代码必须要编译成可执行文件才能运行。那么如何在 Linux 下编译 C 程序呢?

你首先可能想到的是通过 Code::Blocks 等 IDE(集成开发环境)来完成,这时我们只需要按一下按钮,IDE 就会自动完成程序的编译操作。这种通过图形化界面来完成编译的方式固然简单,但是我们就无法知晓编译背后的实现细节了。

本文接下来要介绍的,是如何在命令行界面下完成 C 程序的编译。

想要编译程序,首先需要有编译器。Linux 下使用的标准 C 编译器是由 FSF(自由软件基金会) 提供的 GCC(GNU 编译器套件)。GCC 是属于 GNU 项目的自由软件,现在已经被大多数类 Unix 系统采纳为标准的编译器。

注:GCC 同样适用于微软的 Windows 系统

准备工作

在开始编译前,先检查一下你的 Linux 系统上是否已经安装了 GCC,你可以通过输入 gcc -v 命令来判断。如果你的系统上已经安装了 GCC,终端会打印出当前 GCC 的版本以及其他相关的信息。如果终端提示未找到命令,就说明系统中还没有安装 GCC,你可以使用命令 sudo apt-get install gcc 来安装。

一切准备就绪,接下来我们进入正题。

本文首先会介绍最基本的编译命令,包含各种不同情况下 gcc 命令的使用方法,之后还会简单介绍 Make 工具,以便我们能处理大型项目的编译任务。

基础命令

如果想简单地编译一个源程序文件,我们只需输入 gcc 源程序文件名称。例如,想要编译一个名为 test.c 的源程序文件,我们就输入:

$ gcc test.c

GCC 会将 test.c 编译链接成可执行文件,并且自动命名为 a.out。之后,我们可以通过 ./a.out 命令运行 a.out

如果想指定输出可执行文件的名称,可以使用 -o 选项。沿用上例,若想要将编译好的可执行文件命名为 testprogram,可以这样写:

$ gcc test.c -o testprogram

GCC 会将 test.c 编译链接成可执行文件 testprogram

若有多个源文件也是用类似的方法。例如要将源文件 a.cb.c 编译链接成可执行文件 c.out,可以这样写:

$ gcc a.c b.c -o c.out

GCC 会将 a.cb.c 分别编译后链接成可执行文件 c.out

先编译后链接

试想一下,一个大型的项目由许许多多的源文件组成。若每次修改后,都要将所有的源文件全部重新编译,将会浪费大量的时间。那么我们可不可以只重新编译修改过的源文件呢?答案是肯定的。

其实我们之前一直所谓的“编译”是一种简称,更确切地说,C 程序的编译过程是由编译链接两个阶段组成的。编译阶段将源代码文件(.c)编译汇编成目标代码文件(.o),链接阶段则是将目标代码文件和库文件链接生成可执行文件。

那么如果我们先将所有的源文件编译成对应的目标代码文件,再链接所有的目标代码文件来生成可执行文件,就可以解决上面的问题了。如果有源文件修改了,只需重新编译生成它的目标代码文件,再重新链接一下就可以了。

下面举一个例子,有两个源文件 main.cmax.c,分别如下:

main.c

#include <stdio.h>

int main()
{
    printf("max(15,5) = %d",max(15,5));
    return 0;
}

max.c

int max(int a, int b)
{
    if(a > b) return a;
    else return b;
}

要 GCC 编译生成目标代码文件,使用 -c 选项:

$ gcc -c main.c max.c

GCC 会生成对应的目标代码文件 main.omax.o,再链接它们生成可执行文件 main.out

$ gcc main.o max.o -o main.out

假如我们后来修改了文件 max.c,那么重新编译时我们就只需 gcc -c max.c,重新生成 max.c 的目标代码文件 max.o,再通过 gcc main.o max.o -o main.out 与之前编译好的目标代码文件 main.o 链接,就可以重新生成可执行文件了。

凡是没有修改过的文件,我们都不需要重新编译,直接在链接时使用它们对应的目标代码文件就可以了。

Make 工具

想像一下,一个大型的项目可能由数百甚至上千个源文件组成,如果还是使用这种一个一个输入文件名的方式,那么每次链接所有的目标代码文件将会是一场噩梦。

这时就需要使用 make 了。make 可以通过我们手动创建的 Makefile 文件(文件名就为 Makefile,没有后缀)来自动完成编译和链接,每次重新编译链接时,只需输入命令 make,它就会自动将修改过的源文件重新编译,并链接生成最终的可执行文件。

Makefile 文件的格式为:

# 注释一行  
编译生成的文件:编译所需的文件...
<TAB>编译指令  

对于上面的例子,Makefile 文件就可以这样写(从上往下逐步细化):

# This is a Makefile !  
main.out:max.o main.o  
	gcc max.o main.o -o main.out
max.o:max.c  
	gcc -c max.c  
main.o:main.c  
	gcc -c main.c

编写好后执行 make 命令,make 程序就会自动递归地进行编译和链接,生成可执行文件。

make 程序每次运行时都会检查文件是否修改过,make 只会重新编译那些修改过的文件,以及需要依赖于这些文件生成的其他文件。

例如修改过 max.c 文件后,再次执行 make 命令,gcc -c main.c 就不会执行,但是因为文件 main.out 的生成依赖于 max.o,而 max.o 又依赖于 max.c,所以 gcc max.o main.o -o main.out 也会重新执行。