编译一个C程序

GCC是类Unix操作系统下的标准编译器,在Linux或者是以FreeBSD为基础的macOS下可以直接使用。

编译一个简单的C程序

下面的代码被包含在一个名为test.c的文本文件里:

#include <stdio.h>
int main(){
    printf("Hello World!\n");
}   

你可以通过macOS终端直接编译该文件:

$gcc test.c -o test

编译指令会将test.c编译成一个名为test的可执行程序,-o参数用于指定编译后的程序名。 执行程序(./test)时屏幕上会输出 Hello World!

除此之外,你也可以执行下面两行编译命令来生成test程序

$gcc -c test.c
$gcc test.o -o test

和第一条编译命令相比,除了执行命令多出一行以外,还额外生成了一个名为test.o的文件。这是因为,GCC在编译C程序时要经过预处理、编译、汇编和连接四步。通过第二种方式,编译器首先会将源文件test.c编译成名为hello.o的机器语言程序。接着,再将hello.o和一些用于输出”Hello World”的系统库链接在一起,并合成最终的可执行程序test。

而第一种方式同样执行了这两步,只不过编译器在后台悄悄运行,并删除了中间文件test.o

编译参数

在编译时,我们可以指定一些参数来告诉编译器如何编译我们的程序

在编译命令里加入-g选项,可以开启 gdb 对程序进行调试,通过输入命令 gdb ./test进入调试模式

$gcc -g test.c -o test

在编译命令里加入-Wall选项会打印出程序编译时的警告信息,包括一些语法问题。

$gcc -Wall test.c -o test

加入 -O选项,开启默认优化。

$gcc -O test.c -o test

加入 -shared ,用来生成共享文件*.so(Shared Object)

$gcc -shadred test.c -o libtest.so

链接库(-l&-L)

当程序需要一些系统库或我们自己生成的类库时,并且这个库文件是在以下三个目录之中时,/lib、/usr/lib和/usr/local/lib,我们就可以在编译指令里加入-l参数来指定编译时需要链接的库文件。

-l参数和其他参数的用法有所不同,-l后面不加空格并直接跟要链接的库名,比如说我们要连接的库为libm.dylib数学库,那么我们要写成-lm的形式,即库名去掉lib和.dylib后的库名。这样,编译器在链接时就会自动在目录/lib、/usr/lib和/usr/local/lib下寻找要链接的库文件

gcc test.c -o test -lm

但是,如果要链接的库不在这三个目录之列时,通过-l链接就会出错。这时可以用到-L参数。-L参数用来指定库的目录位置。比如我们用到当前项目下的lib文件夹里的库文件(../lib),我们可以写成如下格式:

gcc test.c -o test -L../lib

指定头文件目录(-I)

有时,我们会将头文件放在一个统一的目录里,比如include文件夹。 这时候,我们可以在编译指令里加入-I参数来指定头文件的目录

gcc test.c -o test -I./include

当然你也可以在引用头文件的时写成完整路径的形式./include/header.h

参见

Comments