编译C程序

编译C程序

廖雪峰

资深软件开发工程师,业余马拉松选手。

C程序的编译通常分两步:

将每个.c文件编译为.o文件;

将所有.o文件链接为最终的可执行文件。

我们假设如下的一个C项目,包含hello.c、hello.h和main.c。

hello.c内容如下:

#include

int hello()

{

printf("hello, world!\n");

return 0;

}

hello.h内容如下:

int hello();

main.c内容如下:

#include

#include "hello.h"

int main()

{

printf("start...\n");

hello();

printf("exit.\n");

return 0;

}

注意到main.c引用了头文件hello.h。我们很容易梳理出需要生成的文件,逻辑如下:

┌───────┐ ┌───────┐ ┌───────┐

│hello.c│ │main.c │ │hello.h│

└───────┘ └───────┘ └───────┘

│ │ │

│ └────┬────┘

│ │

▼ ▼

┌───────┐ ┌───────┐

│hello.o│ │main.o │

└───────┘ └───────┘

│ │

└───────┬──────┘

┌─────────┐

│world.out│

└─────────┘

假定最终生成的可执行文件是world.out,中间步骤还需要生成hello.o和main.o两个文件。根据上述依赖关系,我们可以很容易地写出Makefile如下:

# 生成可执行文件:

world.out: hello.o main.o

cc -o world.out hello.o main.o

# 编译 hello.c:

hello.o: hello.c

cc -c hello.c

# 编译 main.c:

main.o: main.c hello.h

cc -c main.c

clean:

rm -f *.o world.out

执行make,输出如下:

$ make

cc -c hello.c

cc -c main.c

cc -o world.out hello.o main.o

在当前目录下可以看到hello.o、main.o以及最终的可执行程序world.out。执行world.out:

$ ./world.out

start...

hello, world!

exit.

与我们预期相符。

修改hello.c,把输出改为"hello, bob!\n",再执行make,观察输出:

$ make

cc -c hello.c

cc -o world.out hello.o main.o

仅重新编译了hello.c,并未编译main.c。由于hello.o已更新,所以,仍然要重新生成world.out。执行world.out:

$ ./world.out

start...

hello, bob!

exit.

与我们预期相符。

修改hello.h:

// int 变为 void:

void hello();

以及hello.c,再次执行make:

$ make

cc -c hello.c

cc -c main.c

cc -o world.out hello.o main.o

会触发main.c的编译,因为main.c依赖hello.h。

执行make clean会删除所有的.o文件,以及可执行文件world.out,再次执行make就会强制全量编译:

$ make clean && make

rm -f *.o world.out

cc -c hello.c

cc -c main.c

cc -o world.out hello.o main.o

这个简单的Makefile使我们能自动化编译C程序,十分方便。

不过,随着越来越多的.c文件被添加进来,如何高效维护Makefile的规则?我们后面继续讲解。

参考源码

可以从GitHub下载源码。

GitHub

小结

在Makefile正确定义规则后,我们就能用make自动化编译C程序。

📚 相关推荐

监控广角最大是多少度
365手机app

监控广角最大是多少度

📅 09-13 👁️ 2559
QQ聊天记录完全清除方法
任丘36524便利店电话

QQ聊天记录完全清除方法

📅 09-06 👁️ 7994
BBC百年简史
亚洲365bet体育

BBC百年简史

📅 07-23 👁️ 3137
手机降频怎么解决 安卓手机自动降频怎么关
任丘36524便利店电话

手机降频怎么解决 安卓手机自动降频怎么关

📅 09-08 👁️ 3788
跑滴滴一公里赚多少钱
亚洲365bet体育

跑滴滴一公里赚多少钱

📅 07-25 👁️ 1702
从北斗导航地图说起
365手机app

从北斗导航地图说起

📅 08-12 👁️ 7287
鬼屋 (Haunted House) - 墓园 (The Graveyard) - MC百科
365手机app

鬼屋 (Haunted House) - 墓园 (The Graveyard) - MC百科

📅 07-02 👁️ 8260
光明大陆包裹品质概率是多少 货运任务包裹品质介绍
淘宝退货多久会自动退款成功?退货规则有哪些?
任丘36524便利店电话

淘宝退货多久会自动退款成功?退货规则有哪些?

📅 07-27 👁️ 3305