Makefile简单实用

最近公司项目可能涉及到Makefile,今天来浅学一下!

1、GCC使用

当我们只有一个C文件时,可以用gcc编译直接生成文件,例如写一个main.c

#include <stdio.h>
int main()
{
printf("this is main.c\r\n");
return 0;
}

我们在命令行输入

sudo gcc -c main.c -o a.out

编译完成后就可以当前文件夹下找到可执行程序a.out,直接执行./a.out就可以打印出想要的结果,但是在实际项目中,一个工程肯定不可能只有一个main.c,也会存在对其他文件的调用,但是使用gcc一个个的生成中间文件,可执行文件,那可是相当麻烦,因此需要使用makefile文件来进行统一处理。

2、make使用

在这里来做一个最简单的示例,建立一个小工程,项目路径是这样:

├── inc
│   ├── test1.h
│   └── test2.h
├── Makefile
└── src
    ├── main.c
    ├── test1.c
    └── test2.c

其中,main.c文本为:

#include <stdio.h>
#include "test1.h"
#include "test2.h"
int main(void)
{
        printf("hello world!\r\n");
        fun_test1();
        fun_test2();
        return 0 ;
}

test1.c为

#include "test1.h"
#include "stdio.h"
void fun_test1()
{
        printf("this is test1!\r\n");
}

test2.c为

#include "test2.h"
#include "stdio.h"
void fun_test2()
{
        printf("this is test2!\r\n");
}

test1.h为

#ifndef __TEST_1_
#define __TEST_1_
void fun_test1();
#endif

test2.h为

#ifndef __TEST_2_
#define __TEST_2_
void fun_test2();
#endif

makefile文件为:

VERSION = 1.0     #程序版本号  
SOURCE = $(wildcard ./src/*.c)  #获取所有的.c文件  
OBJ = $(patsubst %.c, %.o, $(SOURCE))   #将.c文件转为.o文件  
INCLUDES = -I./inc    #头文件路径  

# LIBS = -ldylib      #库文件名字  
# LIB_PATH = -L./lib  #库文件地址  

DEBUG = -D_MACRO    #宏定义  
CFLAGS = -Wall -c   #编译标志位  

TARGET = app  
CC = gcc

$(TARGET): $(OBJ)     
    @mkdir -p output/   #创建一个目录,用于存放已编译的目标  
    $(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET)

%.o: %.c  
    $(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@  
 
.PHONY: clean  
clean:  
    rm -rf $(OBJ) output/

简单看一下,说白了makefile就是bash指令与gcc指令的集合,在使用中,例如mkdir、rm等bash指令必须使用tab缩进。
再添加到自己的工程中时,设定对应的源文件,头文件路径,库文件路径(我这里没用到,注释掉了),宏定义输出目标路径名称与文件名称,在命令行中执行make,出现以下结果:

shumei@ubuntu:~/Desktop/makeTest$ make
gcc -I./inc     -D_MACRO     -Wall -c    src/test2.c -o src/test2.o  
gcc -I./inc     -D_MACRO     -Wall -c    src/main.c -o src/main.o  
gcc -I./inc     -D_MACRO     -Wall -c    src/test1.c -o src/test1.o  
gcc  ./src/test2.o  ./src/main.o  ./src/test1.o      -o output/app  

看一下增加了哪些文件:

shumei@ubuntu:~/Desktop/makeTest$ tree
.
├── inc
│   ├── test1.h
│   └── test2.h
├── Makefile
├── output
│   └── app
└── src
    ├── main.c
    ├── main.o
    ├── test1.c
    ├── test1.o
    ├── test2.c
    └── test2.o

3 directories, 10 files

在output文件夹下执行文件:

shumei@ubuntu:~/Desktop/makeTest$ cd output
shumei@ubuntu:~/Desktop/makeTest/output$ ls
app
shumei@ubuntu:~/Desktop/makeTest/output$ ./app
hello world!
this is test1!
this is test2!
文章目录