C实战:项目构建Make,Automake,CMake

C实战:项目构建Make,Automake,CMake

在本系列文章《C实战:强大的程序调试工具GDB》中我们简要学习了流行的调试工具GDB的使用方法。本文继续“C实战”的主题,对同样非常流行的构建工具Make的用法和原理一探究竟,并顺便看一下一些高级衍生产品。


1.Make基础

首先我们编写一个简单的C项目,以此项目在实战中学习Make的相关知识。更全面的介绍请参考官方手册

cdai@vm /syspace/2-ccpp/24-pragmatic/build-tool/make $ tree
.
├── hello.c
├── hello.h
├── main.c
└── Makefile

0 directories, 4 files

整个程序的逻辑非常简单:main.c中包含一个main方法,调用了hello.c中的sayHello()函数,打印了一句话到控制台上。

// cat main.c hello.h hello.c
// ----- main.c -----
#include "hello.h"

int main(void)
{
    sayHello("Make");
    return 1;
}

// ----- hello.h -----
#ifndef _HELLO_H_
#define _HELLO_H_

void sayHello(char *name);

#endif

// ----- hello.c -----
#include "hello.h"
#include <stdio.h>

void sayHello(char *name)
{
    printf("Hello, %s!\n", name);
}

1.1 基本语法

一个简单的Makefile包含很多规则(Rule),每一条规则的语法结构由目标(Target)、先决条件(Prerequisite)、动作(Recipe)三部分组成:

  • 目标:通常有两种命名方法,一是与要生成的可执行文件或目标文件同名,二是说明动作的目的,例如最常见的clean清理规则。对于第二种规则命名,为了避免与同名文件冲突,可以将目标名加入到.PHONY伪目标列表中。默认情况下,make执行Makefile中的第一个规则,此规则被称为最终目标
  • 先决条件:先决条件是用来创建目标的输入文件,一个目标可以依赖多个先决条件
  • 动作:动作由Make命令负责执行,可以包含多个命令,每个命令可以另起一行。一定要注意的是:命令必须以TAB开头
target: prerequisite
    recipe

下面就看一下示例项目的Makefile是什么样子的。在Makefile中有3个规则,其中目标main依赖于main.o和hello.o,利用gcc执行链接,这与我们的代码结构是相对应的。而main.o和hello.o则分别依赖于各自的源代码.c文件和hello.h头文件,并利用gcc -c执行编译。

main: main.o hello.o
    gcc -o main main.o hello.o

main.o: main.c hello.h
    gcc -c main.c -o main.o

hello.o: hello.c hello.h
    gcc -c hello.c -o hello.o

1.2 实现原理

Make看似非常智能,其实它的原理就像其语法规则一样简单。

  1. 确定目标:如果没有指明,则执行最终目标,即第一个规则的目标
  2. 处理变量和规则:替换变量,推导隐式规则(下一节会学习)
  3. 生成依赖关系链:为所有目标生成依赖关系链
  4. 递归构建:从依赖链的底部向上,根据先决条件会有三种情况:
    4.1 先决条件不存在,则执行规则中的命令
    4.2 先决条件存在,且至少一个比目标“更新”,则执行规则中的命令重新生成
    4.3 先决条件存在,且都比目标“更旧”, 则什么都不做

了解了Make的原理,就看一下我们的示例项目Make的执行过程。可以看到,Make以第一个目标main作为构建目标,从关系链底部的main.o和hello.o开始构建,最终生成了可执行文件main。接下来就执行main,可以看到控制台输出了”Hello, Make!”,证明我们构建成功了!

cdai@vm /syspace/2-ccpp/24-pragmatic/build-tool/make $ make
gcc -c main.c -o main.o
gcc -c hello.c -o hello.o
gcc -o main main.o hello.o

cdai@vm /syspace/2-ccpp/
  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值