多目录、多文件的Makefile的编写

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


结构

下面以我自己写的一个很小的工程代码为例!带你进入多目录、多文件下的makefile的编写:

  • 1、首先我们需要创建一个test目录,然后在test目录下创建5个目录,分别为inc、lib、main、obj、src。和一个Makefile文件。
    下面就主要介绍下这四个文件的主要存放的文件和作用
    –inc:inc目录就是include的缩写,主要存放在一些头文件。
    –lib: lib目录就是library的缩写,主要就是存放一些库文件。比如.a、.so等静态库和动态库文件。
    –main: 该目录就是存放main函数的文件,程序的入口就是从该目录下的main函数下开始的。
    –obj:obj目录就是object的缩写,主要存放的就是目标文件,一些可重定向文件,如.o等文件。
    –src:src目录就是source的缩写,就是存放一些源文件,main函数主要调用src目录下的一个函数。
    Makefile:主makefile文件,该makefile主要定义一些目录的路径然后跳到指定目录下的makefile中执行相应子目录下的makefile。

  • 2、在main目录下有一个main.c文件和Makefile文件,二话不说,直接上代码吧!
    main.c的代码

#include<stdio.h>
#include "test.h"
int main(void)
{
    test1();
    test2();

    return 0;
}

main目录下的子Makefile

$(OBJ_DIR)/main.o:main.c
    $(CC) -c $^ -o $@ $(CFLAG)
  • 3、src目录下有三个文件,test1.c、test2.c、Makefile
    test1.c
#include "test.h"

void test1()
{
    printf("test1\n");

    return;
}

test2.c

#include "test.h"

void test2()
{
    printf("test2\n");

    return;
}

src目录下的子Makefile:

.PHONY:all

all:$(OBJ_DIR)/test1.o $(OBJ_DIR)/test2.o

$(OBJ_DIR)/test1.o:test1.c
    $(CC) -c $^ -o $@ $(CFLAG)

$(OBJ_DIR)/test2.o:test2.c
    $(CC) -c $^ -o $@ $(CFLAG)
  • 4、obj目录下就只有一个Makefile文件
OBJ=$(wildcard *.o)

$(PWD_DIR)/app:$(OBJ)
    $(CC) -o $@ $^
  • 5、inc目录下也只有一个文件test.h
#ifndef _TEST_H
#define _TEST_H

#include<stdio.h>

void test1();
void test2();

#endif
  • 6、主目录下的Makefile
.PHONY:all clean

##
PWD_DIR=$(shell pwd)
SRC_DIR=$(PWD_DIR)/src
OBJ_DIR=$(PWD_DIR)/obj
MAIN_DIR=$(PWD_DIR)/main
LIB_DIR=$(PWD_DIR)/lib
INC_DIR=$(PWD_DIR)/inc

##
CC=gcc
CFLAG=-Wall -g -I$(INC_DIR)

##
export PWD_DIR SRC_DIR OBJ_DIR MAIN_DIR LIB_DIR INC_DIR CC CFLAG

##
all:
    make -C $(SRC_DIR)
    make -C $(MAIN_DIR)
    make -C $(OBJ_DIR)

##
clean:
    $(RM) -rf $(OBJ_DIR)/*.o
    $(RM) app

执行解析

到现在为止,已经把所以的代码都呈现出来了!现在就来说说makefile的总体执行流程!

首先进入test目录下,看下主目录下的Makefile。如果你以前从来没有学过Makefile,也许你会觉得这是乱码!怎么会有这样一堆的东西呢?但是只要你细心去看,还是能找到规律的。

##
PWD_DIR=$(shell pwd) #这里是执行shell的pwd命令获取路劲作为PWD_DIR参数
SRC_DIR=$(PWD_DIR)/src
OBJ_DIR=$(PWD_DIR)/obj
MAIN_DIR=$(PWD_DIR)/main
LIB_DIR=$(PWD_DIR)/lib
INC_DIR=$(PWD_DIR)/inc

这些就是获取当前目录和其他子目录的路径,然后通过

##
export PWD_DIR SRC_DIR OBJ_DIR MAIN_DIR LIB_DIR INC_DIR CC CFLAG
这条语句把所以的目录路径导出,给子Makefile使用。

##
all:
    make -C $(SRC_DIR)
    make -C $(MAIN_DIR)
    make -C $(OBJ_DIR)
make -C 目录   -------》  这就代表执行指定目录下的makefile
所以这几条语句就是依次执行以下几个目录下的makefile

##
clean:
    $(RM) -rf $(OBJ_DIR)/*.o
    $(RM) app
这几条语句删除编译生成的目标文件和可执行文件app

main目录下Makefile

$(OBJ_DIR)/main.o:main.c
    $(CC) -c $^ -o $@ $(CFLAG)

将main.c文件编译成main.o放在obj目录下

src目录下的Makefile

.PHONY:all

all:$(OBJ_DIR)/test1.o $(OBJ_DIR)/test2.o

$(OBJ_DIR)/test1.o:test1.c
    $(CC) -c $^ -o $@ $(CFLAG)

$(OBJ_DIR)/test2.o:test2.c
    $(CC) -c $^ -o $@ $(CFLAG)
这里的意思是将test1.c和test2.c编译成目标文件存放在obj文件。

下面来看下obj目录下的Makefile文件了

OBJ=$(wildcard *.o)

$(PWD_DIR)/app:$(OBJ)
    $(CC) -o $@ $^

将所以的目标文件编译成可执行文件app放在PWD_DIR目录下.wildcard解释如下

wildcard解释:用来明确表示通配符。因为在 Makefile 里,变量实质上就是 C/C++ 中的宏,也就是说,如果一个表达式如 objs = *.o ,则 objs 的值就是 *.o ,而不是表示所有的 .o 文件。若果要使用通配符,那么就要使用 wildcard 来声明 * 这个符号,使 * 符号具有通配符的功能。

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值